Version 2.1.8
Added fine-grained garbage collection callbacks to the API.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@4238 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index b477b45..13ffa29 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -98,6 +98,9 @@
// 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;
@@ -114,7 +117,7 @@
int Heap::mc_count_ = 0;
int Heap::gc_count_ = 0;
-int Heap::unflattended_strings_length_ = 0;
+int Heap::unflattened_strings_length_ = 0;
int Heap::always_allocate_scope_depth_ = 0;
int Heap::linear_allocation_scope_depth_ = 0;
@@ -304,7 +307,7 @@
void Heap::GarbageCollectionPrologue() {
TranscendentalCache::Clear();
gc_count_++;
- unflattended_strings_length_ = 0;
+ unflattened_strings_length_ = 0;
#ifdef DEBUG
ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
allow_allocation(false);
@@ -547,6 +550,16 @@
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 @@
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);
@@ -1269,7 +1291,7 @@
if (obj->IsFailure()) return false;
set_oddball_map(Map::cast(obj));
- // Allocate the empty array
+ // Allocate the empty array.
obj = AllocateEmptyFixedArray();
if (obj->IsFailure()) return false;
set_empty_fixed_array(FixedArray::cast(obj));
@@ -1415,7 +1437,8 @@
if (obj->IsFailure()) return false;
set_boilerplate_function_map(Map::cast(obj));
- obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kSize);
+ obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE,
+ SharedFunctionInfo::kAlignedSize);
if (obj->IsFailure()) return false;
set_shared_function_info_map(Map::cast(obj));
@@ -3786,6 +3809,46 @@
#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 {