Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index d5779126be2f3650c9b94fb77cf1e859e3d8460f..6de1af9b292cf3cad84e62053a42c9701131ba39 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -98,6 +98,9 @@ size_t Heap::code_range_size_ = 0; |
// set up by ConfigureHeap otherwise. |
int Heap::reserved_semispace_size_ = Heap::max_semispace_size_; |
+List<Heap::GCPrologueCallbackPair> Heap::gc_prologue_callbacks_; |
+List<Heap::GCEpilogueCallbackPair> Heap::gc_epilogue_callbacks_; |
+ |
GCCallback Heap::global_gc_prologue_callback_ = NULL; |
GCCallback Heap::global_gc_epilogue_callback_ = NULL; |
@@ -547,6 +550,16 @@ void Heap::PerformGarbageCollection(AllocationSpace space, |
GCTracer::ExternalScope scope(tracer); |
global_gc_prologue_callback_(); |
} |
+ |
+ GCType gc_type = |
+ collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; |
+ |
+ for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { |
+ if (gc_type & gc_prologue_callbacks_[i].gc_type) { |
+ gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags); |
+ } |
+ } |
+ |
EnsureFromSpaceIsCommitted(); |
// Perform mark-sweep with optional compaction. |
@@ -585,6 +598,15 @@ void Heap::PerformGarbageCollection(AllocationSpace space, |
amount_of_external_allocated_memory_; |
} |
+ GCCallbackFlags callback_flags = tracer->is_compacting() |
+ ? kGCCallbackFlagCompacted |
+ : kNoGCCallbackFlags; |
+ for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
+ if (gc_type & gc_epilogue_callbacks_[i].gc_type) { |
+ gc_epilogue_callbacks_[i].callback(gc_type, callback_flags); |
+ } |
+ } |
+ |
if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { |
ASSERT(!allocation_allowed_); |
GCTracer::ExternalScope scope(tracer); |
@@ -3787,6 +3809,46 @@ void Heap::Unprotect() { |
#endif |
+void Heap::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) { |
+ ASSERT(callback != NULL); |
+ GCPrologueCallbackPair pair(callback, gc_type); |
+ ASSERT(!gc_prologue_callbacks_.Contains(pair)); |
+ return gc_prologue_callbacks_.Add(pair); |
+} |
+ |
+ |
+void Heap::RemoveGCPrologueCallback(GCPrologueCallback callback) { |
+ ASSERT(callback != NULL); |
+ for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { |
+ if (gc_prologue_callbacks_[i].callback == callback) { |
+ gc_prologue_callbacks_.Remove(i); |
+ return; |
+ } |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+void Heap::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) { |
+ ASSERT(callback != NULL); |
+ GCEpilogueCallbackPair pair(callback, gc_type); |
+ ASSERT(!gc_epilogue_callbacks_.Contains(pair)); |
+ return gc_epilogue_callbacks_.Add(pair); |
+} |
+ |
+ |
+void Heap::RemoveGCEpilogueCallback(GCEpilogueCallback callback) { |
+ ASSERT(callback != NULL); |
+ for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
+ if (gc_epilogue_callbacks_[i].callback == callback) { |
+ gc_epilogue_callbacks_.Remove(i); |
+ return; |
+ } |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
#ifdef DEBUG |
class PrintHandleVisitor: public ObjectVisitor { |