Index: src/global-handles.cc |
diff --git a/src/global-handles.cc b/src/global-handles.cc |
index 3f4e3bea59d5fb8d96e9435d3dbb0f6932ffd532..609dc6efa306ce6673443ba0f56e0eb90fc31cb2 100644 |
--- a/src/global-handles.cc |
+++ b/src/global-handles.cc |
@@ -78,8 +78,9 @@ class GlobalHandles::Node { |
set_independent(false); |
set_partially_dependent(false); |
set_in_new_space_list(false); |
+ set_is_new_callback(false); |
+ callback_.new_callback = NULL; |
parameter_or_next_free_.next_free = NULL; |
- callback_ = NULL; |
} |
#endif |
@@ -100,7 +101,8 @@ class GlobalHandles::Node { |
set_partially_dependent(false); |
set_state(NORMAL); |
parameter_or_next_free_.parameter = NULL; |
- callback_ = NULL; |
+ set_is_new_callback(false); |
+ callback_.new_callback = NULL; |
IncreaseBlockUses(global_handles); |
} |
@@ -161,6 +163,13 @@ class GlobalHandles::Node { |
flags_ = IsInNewSpaceList::update(flags_, v); |
} |
+ bool is_new_callback() { |
+ return IsNewCallback::decode(flags_); |
+ } |
+ void set_is_new_callback(bool v) { |
+ flags_ = IsNewCallback::update(flags_, v); |
+ } |
+ |
bool IsNearDeath() const { |
// Check for PENDING to ensure correct answer when processing callbacks. |
return state() == PENDING || state() == NEAR_DEATH; |
@@ -195,8 +204,9 @@ class GlobalHandles::Node { |
} |
void clear_partially_dependent() { set_partially_dependent(false); } |
- // Callback accessor. |
- WeakReferenceCallback callback() { return callback_; } |
+ // Callback accessors. |
+ WeakReferenceCallback old_callback() { return callback_.old_callback; } |
+ WeakenedReferenceCallback new_callback() { return callback_.new_callback; } |
// Callback parameter accessors. |
void set_parameter(void* parameter) { |
@@ -230,7 +240,24 @@ class GlobalHandles::Node { |
} |
set_state(WEAK); |
set_parameter(parameter); |
- callback_ = callback; |
+ set_is_new_callback(false); |
+ callback_.old_callback = callback; |
+ } |
+ |
+ void MakeWeak(GlobalHandles* global_handles, |
+ void* parameter, |
+ WeakenedReferenceCallback callback) { |
+ ASSERT(state() != FREE); |
+ if (!IsWeakRetainer()) { |
+ global_handles->number_of_weak_handles_++; |
+ if (object_->IsJSGlobalObject()) { |
+ global_handles->number_of_global_object_weak_handles_++; |
+ } |
+ } |
+ set_state(WEAK); |
+ set_parameter(parameter); |
+ set_is_new_callback(true); |
+ callback_.new_callback = callback; |
} |
void ClearWeakness(GlobalHandles* global_handles) { |
@@ -248,8 +275,7 @@ class GlobalHandles::Node { |
bool PostGarbageCollectionProcessing(Isolate* isolate, |
GlobalHandles* global_handles) { |
if (state() != Node::PENDING) return false; |
- WeakReferenceCallback func = callback(); |
- if (func == NULL) { |
+ if (new_callback() == NULL) { |
Sven Panne
2013/01/18 08:08:12
This is a hack and works only because we don't act
haraken
2013/01/22 00:27:37
Done.
|
Release(global_handles); |
return false; |
} |
@@ -267,7 +293,13 @@ class GlobalHandles::Node { |
ExternalTwoByteString::cast(object_)->resource() != NULL); |
// Leaving V8. |
VMState state(isolate, EXTERNAL); |
- func(object, par); |
+ if (is_new_callback()) { |
+ WeakenedReferenceCallback callback = new_callback(); |
+ callback(reinterpret_cast<v8::Isolate*>(isolate), object, par); |
+ } else { |
+ WeakReferenceCallback callback = old_callback(); |
+ callback(object, par); |
+ } |
} |
// Absence of explicit cleanup or revival of weak handle |
// in most of the cases would lead to memory leak. |
@@ -299,11 +331,15 @@ class GlobalHandles::Node { |
class IsIndependent: public BitField<bool, 4, 1> {}; |
class IsPartiallyDependent: public BitField<bool, 5, 1> {}; |
class IsInNewSpaceList: public BitField<bool, 6, 1> {}; |
+ class IsNewCallback: public BitField<bool, 7, 1> {}; |
uint8_t flags_; |
// Handle specific callback. |
- WeakReferenceCallback callback_; |
+ union { |
+ WeakReferenceCallback old_callback; |
+ WeakenedReferenceCallback new_callback; |
+ } callback_; |
// Provided data for callback. In FREE state, this is used for |
// the free list link. |
@@ -478,6 +514,13 @@ void GlobalHandles::MakeWeak(Object** location, void* parameter, |
} |
+void GlobalHandles::MakeWeak(Object** location, void* parameter, |
+ WeakenedReferenceCallback callback) { |
+ ASSERT(callback != NULL); |
+ Node::FromLocation(location)->MakeWeak(this, parameter, callback); |
+} |
+ |
+ |
void GlobalHandles::ClearWeakness(Object** location) { |
Node::FromLocation(location)->ClearWeakness(this); |
} |
@@ -523,16 +566,6 @@ void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { |
} |
-void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f, |
- WeakReferenceCallback callback) { |
- for (NodeIterator it(this); !it.done(); it.Advance()) { |
- if (it.node()->IsWeak() && it.node()->callback() == callback) { |
- f(it.node()->object(), it.node()->parameter()); |
- } |
- } |
-} |
- |
- |
void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { |
for (NodeIterator it(this); !it.done(); it.Advance()) { |
if (it.node()->IsWeak() && f(it.node()->location())) { |