From 1d4c0532d7833285da8d970e88e21e458690d6f3 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Mon, 13 Jan 2014 10:57:49 +0000 Subject: [PATCH] Introduce kGCCallbackForced flag. This flag will be passed to GC prologue/epilogue callbacks if GC was forced through GC extension. BUG= R=dcarney@chromium.org, mstarzinger@chromium.org Review URL: https://codereview.chromium.org/104023011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18558 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 3 ++- src/extensions/gc-extension.cc | 6 ++++-- src/heap-inl.h | 7 +++++-- src/heap-snapshot-generator.cc | 2 +- src/heap.cc | 26 ++++++++++++++++---------- src/heap.h | 29 +++++++++++++++++++---------- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/include/v8.h b/include/v8.h index 02ffcc5..bcc4b3e 100644 --- a/include/v8.h +++ b/include/v8.h @@ -3893,7 +3893,8 @@ enum GCType { enum GCCallbackFlags { kNoGCCallbackFlags = 0, kGCCallbackFlagCompacted = 1 << 0, - kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1 + kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1, + kGCCallbackFlagForced = 1 << 2 }; typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags); diff --git a/src/extensions/gc-extension.cc b/src/extensions/gc-extension.cc index 69fd717..205587f 100644 --- a/src/extensions/gc-extension.cc +++ b/src/extensions/gc-extension.cc @@ -42,9 +42,11 @@ v8::Handle GCExtension::GetNativeFunctionTemplate( void GCExtension::GC(const v8::FunctionCallbackInfo& args) { i::Isolate* isolate = reinterpret_cast(args.GetIsolate()); if (args[0]->BooleanValue()) { - isolate->heap()->CollectGarbage(NEW_SPACE, "gc extension"); + isolate->heap()->CollectGarbage( + NEW_SPACE, "gc extension", v8::kGCCallbackFlagForced); } else { - isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "gc extension"); + isolate->heap()->CollectAllGarbage( + Heap::kNoGCFlags, "gc extension", v8::kGCCallbackFlagForced); } } diff --git a/src/heap-inl.h b/src/heap-inl.h index 5e6fb2b..cc65389 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -532,10 +532,13 @@ void Heap::ScavengeObject(HeapObject** p, HeapObject* object) { } -bool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason) { +bool Heap::CollectGarbage(AllocationSpace space, + const char* gc_reason, + const v8::GCCallbackFlags callbackFlags) { const char* collector_reason = NULL; GarbageCollector collector = SelectGarbageCollector(space, &collector_reason); - return CollectGarbage(space, collector, gc_reason, collector_reason); + return CollectGarbage( + space, collector, gc_reason, collector_reason, callbackFlags); } diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc index 6be580f..35cfcb4 100644 --- a/src/heap-snapshot-generator.cc +++ b/src/heap-snapshot-generator.cc @@ -2128,7 +2128,7 @@ void NativeObjectsExplorer::FillRetainedObjects() { group->info = NULL; // Acquire info object ownership. } isolate->global_handles()->RemoveObjectGroups(); - isolate->heap()->CallGCEpilogueCallbacks(major_gc_type); + isolate->heap()->CallGCEpilogueCallbacks(major_gc_type, kNoGCCallbackFlags); // Record objects that are not in ObjectGroups, but have class ID. GlobalHandlesExtractor extractor(this); isolate->global_handles()->IterateAllRootsWithClassIds(&extractor); diff --git a/src/heap.cc b/src/heap.cc index 5ca85ec..899d701 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -702,12 +702,14 @@ void Heap::GarbageCollectionEpilogue() { } -void Heap::CollectAllGarbage(int flags, const char* gc_reason) { +void Heap::CollectAllGarbage(int flags, + const char* gc_reason, + const v8::GCCallbackFlags gc_callback_flags) { // Since we are ignoring the return value, the exact choice of space does // not matter, so long as we do not specify NEW_SPACE, which would not // cause a full GC. mark_compact_collector_.SetFlags(flags); - CollectGarbage(OLD_POINTER_SPACE, gc_reason); + CollectGarbage(OLD_POINTER_SPACE, gc_reason, gc_callback_flags); mark_compact_collector_.SetFlags(kNoGCFlags); } @@ -750,7 +752,8 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) { bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector, const char* gc_reason, - const char* collector_reason) { + const char* collector_reason, + const v8::GCCallbackFlags gc_callback_flags) { // The VM is in the GC state until exiting this function. VMState state(isolate_); @@ -805,7 +808,7 @@ bool Heap::CollectGarbage(AllocationSpace space, (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() : isolate_->counters()->gc_compactor()); next_gc_likely_to_collect_more = - PerformGarbageCollection(collector, &tracer); + PerformGarbageCollection(collector, &tracer, gc_callback_flags); } GarbageCollectionEpilogue(); @@ -1032,8 +1035,10 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { survival_rate_ = survival_rate; } -bool Heap::PerformGarbageCollection(GarbageCollector collector, - GCTracer* tracer) { +bool Heap::PerformGarbageCollection( + GarbageCollector collector, + GCTracer* tracer, + const v8::GCCallbackFlags gc_callback_flags) { bool next_gc_likely_to_collect_more = false; if (collector != SCAVENGER) { @@ -1164,7 +1169,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); VMState state(isolate_); HandleScope handle_scope(isolate_); - CallGCEpilogueCallbacks(gc_type); + CallGCEpilogueCallbacks(gc_type, gc_callback_flags); } #ifdef VERIFY_HEAP @@ -1194,18 +1199,19 @@ void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) { } -void Heap::CallGCEpilogueCallbacks(GCType gc_type) { +void Heap::CallGCEpilogueCallbacks(GCType gc_type, + GCCallbackFlags gc_callback_flags) { for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { if (gc_type & gc_epilogue_callbacks_[i].gc_type) { if (!gc_epilogue_callbacks_[i].pass_isolate_) { v8::GCPrologueCallback callback = reinterpret_cast( gc_epilogue_callbacks_[i].callback); - callback(gc_type, kNoGCCallbackFlags); + callback(gc_type, gc_callback_flags); } else { v8::Isolate* isolate = reinterpret_cast(this->isolate()); gc_epilogue_callbacks_[i].callback( - isolate, gc_type, kNoGCCallbackFlags); + isolate, gc_type, gc_callback_flags); } } } diff --git a/src/heap.h b/src/heap.h index 7134f06..19d91a9 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1157,8 +1157,10 @@ class Heap { // Performs garbage collection operation. // Returns whether there is a chance that another major GC could // collect more garbage. - inline bool CollectGarbage(AllocationSpace space, - const char* gc_reason = NULL); + inline bool CollectGarbage( + AllocationSpace space, + const char* gc_reason = NULL, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); static const int kNoGCFlags = 0; static const int kSweepPreciselyMask = 1; @@ -1173,7 +1175,10 @@ class Heap { // Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is // non-zero, then the slower precise sweeper is used, which leaves the heap // in a state where we can iterate over the heap visiting all objects. - void CollectAllGarbage(int flags, const char* gc_reason = NULL); + void CollectAllGarbage( + int flags, + const char* gc_reason = NULL, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); // Last hope GC, should try to squeeze as much as possible. void CollectAllAvailableGarbage(const char* gc_reason = NULL); @@ -1701,7 +1706,7 @@ class Heap { inline Isolate* isolate(); void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags); - void CallGCEpilogueCallbacks(GCType gc_type); + void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags); inline bool OldGenerationAllocationLimitReached(); @@ -2052,16 +2057,20 @@ class Heap { // Performs garbage collection operation. // Returns whether there is a chance that another major GC could // collect more garbage. - bool CollectGarbage(AllocationSpace space, - GarbageCollector collector, - const char* gc_reason, - const char* collector_reason); + bool CollectGarbage( + AllocationSpace space, + GarbageCollector collector, + const char* gc_reason, + const char* collector_reason, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); // Performs garbage collection // Returns whether there is a chance another major GC could // collect more garbage. - bool PerformGarbageCollection(GarbageCollector collector, - GCTracer* tracer); + bool PerformGarbageCollection( + GarbageCollector collector, + GCTracer* tracer, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); inline void UpdateOldSpaceLimits(); -- 2.7.4