Index: src/global-handles.cc |
=================================================================== |
--- src/global-handles.cc (revision 7267) |
+++ src/global-handles.cc (working copy) |
@@ -35,6 +35,12 @@ |
namespace v8 { |
namespace internal { |
+ |
+ObjectGroup::~ObjectGroup() { |
+ if (info_ != NULL) info_->Dispose(); |
+} |
+ |
+ |
class GlobalHandles::Node : public Malloced { |
public: |
@@ -58,7 +64,7 @@ |
} |
~Node() { |
- if (state_ != DESTROYED) Destroy(); |
+ if (state_ != DESTROYED) Destroy(Isolate::Current()->global_handles()); |
#ifdef DEBUG |
// Zap the values for eager trapping. |
object_ = NULL; |
@@ -67,11 +73,11 @@ |
#endif |
} |
- void Destroy() { |
+ void Destroy(GlobalHandles* global_handles) { |
if (state_ == WEAK || IsNearDeath()) { |
- GlobalHandles::number_of_weak_handles_--; |
+ global_handles->number_of_weak_handles_--; |
if (object_->IsJSGlobalObject()) { |
- GlobalHandles::number_of_global_object_weak_handles_--; |
+ global_handles->number_of_global_object_weak_handles_--; |
} |
} |
state_ = DESTROYED; |
@@ -102,13 +108,15 @@ |
Handle<Object> handle() { return Handle<Object>(&object_); } |
// Make this handle weak. |
- void MakeWeak(void* parameter, WeakReferenceCallback callback) { |
- LOG(HandleEvent("GlobalHandle::MakeWeak", handle().location())); |
+ void MakeWeak(GlobalHandles* global_handles, void* parameter, |
+ WeakReferenceCallback callback) { |
+ LOG(global_handles->isolate(), |
+ HandleEvent("GlobalHandle::MakeWeak", handle().location())); |
ASSERT(state_ != DESTROYED); |
if (state_ != WEAK && !IsNearDeath()) { |
- GlobalHandles::number_of_weak_handles_++; |
+ global_handles->number_of_weak_handles_++; |
if (object_->IsJSGlobalObject()) { |
- GlobalHandles::number_of_global_object_weak_handles_++; |
+ global_handles->number_of_global_object_weak_handles_++; |
} |
} |
state_ = WEAK; |
@@ -116,13 +124,14 @@ |
callback_ = callback; |
} |
- void ClearWeakness() { |
- LOG(HandleEvent("GlobalHandle::ClearWeakness", handle().location())); |
+ void ClearWeakness(GlobalHandles* global_handles) { |
+ LOG(global_handles->isolate(), |
+ HandleEvent("GlobalHandle::ClearWeakness", handle().location())); |
ASSERT(state_ != DESTROYED); |
if (state_ == WEAK || IsNearDeath()) { |
- GlobalHandles::number_of_weak_handles_--; |
+ global_handles->number_of_weak_handles_--; |
if (object_->IsJSGlobalObject()) { |
- GlobalHandles::number_of_global_object_weak_handles_--; |
+ global_handles->number_of_global_object_weak_handles_--; |
} |
} |
state_ = NORMAL; |
@@ -159,12 +168,13 @@ |
// Returns the callback for this weak handle. |
WeakReferenceCallback callback() { return callback_; } |
- bool PostGarbageCollectionProcessing() { |
+ bool PostGarbageCollectionProcessing(Isolate* isolate, |
+ GlobalHandles* global_handles) { |
if (state_ != Node::PENDING) return false; |
- LOG(HandleEvent("GlobalHandle::Processing", handle().location())); |
+ LOG(isolate, HandleEvent("GlobalHandle::Processing", handle().location())); |
WeakReferenceCallback func = callback(); |
if (func == NULL) { |
- Destroy(); |
+ Destroy(global_handles); |
return false; |
} |
void* par = parameter(); |
@@ -176,9 +186,9 @@ |
// Forbid reuse of destroyed nodes as they might be already deallocated. |
// It's fine though to reuse nodes that were destroyed in weak callback |
// as those cannot be deallocated until we are back from the callback. |
- set_first_free(NULL); |
- if (first_deallocated()) { |
- first_deallocated()->set_next(head()); |
+ global_handles->set_first_free(NULL); |
+ if (global_handles->first_deallocated()) { |
+ global_handles->first_deallocated()->set_next(global_handles->head()); |
} |
// Check that we are not passing a finalized external string to |
// the callback. |
@@ -187,7 +197,7 @@ |
ASSERT(!object_->IsExternalTwoByteString() || |
ExternalTwoByteString::cast(object_)->resource() != NULL); |
// Leaving V8. |
- VMState state(EXTERNAL); |
+ VMState state(isolate, EXTERNAL); |
func(object, par); |
} |
// Absense of explicit cleanup or revival of weak handle |
@@ -230,7 +240,7 @@ |
}; |
-class GlobalHandles::Pool BASE_EMBEDDED { |
+class GlobalHandles::Pool { |
public: |
Pool() { |
current_ = new Chunk(); |
@@ -288,11 +298,27 @@ |
}; |
-static GlobalHandles::Pool pool_; |
+GlobalHandles::GlobalHandles(Isolate* isolate) |
+ : isolate_(isolate), |
+ number_of_weak_handles_(0), |
+ number_of_global_object_weak_handles_(0), |
+ head_(NULL), |
+ first_free_(NULL), |
+ first_deallocated_(NULL), |
+ pool_(new Pool()), |
+ post_gc_processing_count_(0), |
+ object_groups_(4) { |
+} |
+GlobalHandles::~GlobalHandles() { |
+ delete pool_; |
+ pool_ = 0; |
+} |
+ |
+ |
Handle<Object> GlobalHandles::Create(Object* value) { |
- Counters::global_handles.Increment(); |
+ isolate_->counters()->global_handles()->Increment(); |
Node* result; |
if (first_free()) { |
// Take the first node in the free list. |
@@ -306,7 +332,7 @@ |
set_head(result); |
} else { |
// Allocate a new node. |
- result = pool_.Allocate(); |
+ result = pool_->Allocate(); |
result->set_next(head()); |
set_head(result); |
} |
@@ -316,10 +342,10 @@ |
void GlobalHandles::Destroy(Object** location) { |
- Counters::global_handles.Decrement(); |
+ isolate_->counters()->global_handles()->Decrement(); |
if (location == NULL) return; |
Node* node = Node::FromLocation(location); |
- node->Destroy(); |
+ node->Destroy(this); |
// Link the destroyed. |
node->set_next_free(first_free()); |
set_first_free(node); |
@@ -329,12 +355,12 @@ |
void GlobalHandles::MakeWeak(Object** location, void* parameter, |
WeakReferenceCallback callback) { |
ASSERT(callback != NULL); |
- Node::FromLocation(location)->MakeWeak(parameter, callback); |
+ Node::FromLocation(location)->MakeWeak(this, parameter, callback); |
} |
void GlobalHandles::ClearWeakness(Object** location) { |
- Node::FromLocation(location)->ClearWeakness(); |
+ Node::FromLocation(location)->ClearWeakness(this); |
} |
@@ -381,27 +407,26 @@ |
if (current->state_ == Node::WEAK) { |
if (f(¤t->object_)) { |
current->state_ = Node::PENDING; |
- LOG(HandleEvent("GlobalHandle::Pending", current->handle().location())); |
+ LOG(isolate_, |
+ HandleEvent("GlobalHandle::Pending", current->handle().location())); |
} |
} |
} |
} |
-int post_gc_processing_count = 0; |
- |
bool GlobalHandles::PostGarbageCollectionProcessing() { |
// Process weak global handle callbacks. This must be done after the |
// GC is completely done, because the callbacks may invoke arbitrary |
// API functions. |
// At the same time deallocate all DESTROYED nodes. |
- ASSERT(Heap::gc_state() == Heap::NOT_IN_GC); |
- const int initial_post_gc_processing_count = ++post_gc_processing_count; |
+ ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); |
+ const int initial_post_gc_processing_count = ++post_gc_processing_count_; |
bool next_gc_likely_to_collect_more = false; |
Node** p = &head_; |
while (*p != NULL) { |
- if ((*p)->PostGarbageCollectionProcessing()) { |
- if (initial_post_gc_processing_count != post_gc_processing_count) { |
+ if ((*p)->PostGarbageCollectionProcessing(isolate_, this)) { |
+ if (initial_post_gc_processing_count != post_gc_processing_count_) { |
// Weak callback triggered another GC and another round of |
// PostGarbageCollection processing. The current node might |
// have been deleted in that round, so we need to bail out (or |
@@ -466,17 +491,10 @@ |
set_head(NULL); |
set_first_free(NULL); |
set_first_deallocated(NULL); |
- pool_.Release(); |
+ pool_->Release(); |
} |
-int GlobalHandles::number_of_weak_handles_ = 0; |
-int GlobalHandles::number_of_global_object_weak_handles_ = 0; |
- |
-GlobalHandles::Node* GlobalHandles::head_ = NULL; |
-GlobalHandles::Node* GlobalHandles::first_free_ = NULL; |
-GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL; |
- |
void GlobalHandles::RecordStats(HeapStats* stats) { |
*stats->global_handle_count = 0; |
*stats->weak_global_handle_count = 0; |
@@ -535,11 +553,6 @@ |
#endif |
-List<ObjectGroup*>* GlobalHandles::ObjectGroups() { |
- // Lazily initialize the list to avoid startup time static constructors. |
- static List<ObjectGroup*> groups(4); |
- return &groups; |
-} |
void GlobalHandles::AddObjectGroup(Object*** handles, |
@@ -549,17 +562,10 @@ |
for (size_t i = 0; i < length; ++i) { |
new_entry->objects_.Add(handles[i]); |
} |
- ObjectGroups()->Add(new_entry); |
+ object_groups_.Add(new_entry); |
} |
-List<ImplicitRefGroup*>* GlobalHandles::ImplicitRefGroups() { |
- // Lazily initialize the list to avoid startup time static constructors. |
- static List<ImplicitRefGroup*> groups(4); |
- return &groups; |
-} |
- |
- |
void GlobalHandles::AddImplicitReferences(HeapObject* parent, |
Object*** children, |
size_t length) { |
@@ -567,25 +573,23 @@ |
for (size_t i = 0; i < length; ++i) { |
new_entry->children_.Add(children[i]); |
} |
- ImplicitRefGroups()->Add(new_entry); |
+ implicit_ref_groups_.Add(new_entry); |
} |
void GlobalHandles::RemoveObjectGroups() { |
- List<ObjectGroup*>* object_groups = ObjectGroups(); |
- for (int i = 0; i< object_groups->length(); i++) { |
- delete object_groups->at(i); |
+ for (int i = 0; i < object_groups_.length(); i++) { |
+ delete object_groups_.at(i); |
} |
- object_groups->Clear(); |
+ object_groups_.Clear(); |
} |
void GlobalHandles::RemoveImplicitRefGroups() { |
- List<ImplicitRefGroup*>* ref_groups = ImplicitRefGroups(); |
- for (int i = 0; i< ref_groups->length(); i++) { |
- delete ref_groups->at(i); |
+ for (int i = 0; i < implicit_ref_groups_.length(); i++) { |
+ delete implicit_ref_groups_.at(i); |
} |
- ref_groups->Clear(); |
+ implicit_ref_groups_.Clear(); |
} |