| Index: src/global-handles.cc
|
| diff --git a/src/global-handles.cc b/src/global-handles.cc
|
| index 4a2aad3d0e06cd1345a00ff4424638a1fb604ee3..1a98e49ff375a055babc8a0394301128273ad22f 100644
|
| --- a/src/global-handles.cc
|
| +++ b/src/global-handles.cc
|
| @@ -90,7 +90,7 @@ class GlobalHandles::Node {
|
| set_partially_dependent(false);
|
| set_in_new_space_list(false);
|
| parameter_or_next_free_.next_free = NULL;
|
| - weak_reference_callback_ = NULL;
|
| + weak_callback_ = NULL;
|
| }
|
| #endif
|
|
|
| @@ -111,7 +111,7 @@ class GlobalHandles::Node {
|
| set_partially_dependent(false);
|
| set_state(NORMAL);
|
| parameter_or_next_free_.parameter = NULL;
|
| - weak_reference_callback_ = NULL;
|
| + weak_callback_ = NULL;
|
| IncreaseBlockUses();
|
| }
|
|
|
| @@ -123,7 +123,7 @@ class GlobalHandles::Node {
|
| class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
|
| set_independent(false);
|
| set_partially_dependent(false);
|
| - weak_reference_callback_ = NULL;
|
| + weak_callback_ = NULL;
|
| DecreaseBlockUses();
|
| }
|
|
|
| @@ -169,6 +169,13 @@ class GlobalHandles::Node {
|
| flags_ = IsInNewSpaceList::update(flags_, v);
|
| }
|
|
|
| + bool is_revivable_callback() {
|
| + return IsRevivableCallback::decode(flags_);
|
| + }
|
| + void set_revivable_callback(bool v) {
|
| + flags_ = IsRevivableCallback::update(flags_, v);
|
| + }
|
| +
|
| bool IsNearDeath() const {
|
| // Check for PENDING to ensure correct answer when processing callbacks.
|
| return state() == PENDING || state() == NEAR_DEATH;
|
| @@ -228,11 +235,20 @@ class GlobalHandles::Node {
|
| }
|
|
|
| void MakeWeak(void* parameter,
|
| - RevivableCallback weak_reference_callback) {
|
| + WeakCallback weak_callback,
|
| + RevivableCallback revivable_callback) {
|
| + ASSERT((weak_callback == NULL) != (revivable_callback == NULL));
|
| ASSERT(state() != FREE);
|
| set_state(WEAK);
|
| set_parameter(parameter);
|
| - weak_reference_callback_ = weak_reference_callback;
|
| + if (weak_callback != NULL) {
|
| + weak_callback_ = weak_callback;
|
| + set_revivable_callback(false);
|
| + } else {
|
| + weak_callback_ =
|
| + reinterpret_cast<WeakCallback>(revivable_callback);
|
| + set_revivable_callback(true);
|
| + }
|
| }
|
|
|
| void ClearWeakness() {
|
| @@ -243,7 +259,7 @@ class GlobalHandles::Node {
|
|
|
| bool PostGarbageCollectionProcessing(Isolate* isolate) {
|
| if (state() != Node::PENDING) return false;
|
| - if (weak_reference_callback_ == NULL) {
|
| + if (weak_callback_ == NULL) {
|
| Release();
|
| return false;
|
| }
|
| @@ -262,9 +278,20 @@ class GlobalHandles::Node {
|
| // Leaving V8.
|
| VMState<EXTERNAL> state(isolate);
|
| HandleScope handle_scope(isolate);
|
| - weak_reference_callback_(reinterpret_cast<v8::Isolate*>(isolate),
|
| - reinterpret_cast<Persistent<Value>*>(&object),
|
| - par);
|
| + if (is_revivable_callback()) {
|
| + RevivableCallback revivable =
|
| + reinterpret_cast<RevivableCallback>(weak_callback_);
|
| + revivable(reinterpret_cast<v8::Isolate*>(isolate),
|
| + reinterpret_cast<Persistent<Value>*>(&object),
|
| + par);
|
| + } else {
|
| + Handle<Object> handle(*object, isolate);
|
| + v8::WeakCallbackData<v8::Value, void> data(
|
| + reinterpret_cast<v8::Isolate*>(isolate),
|
| + v8::Utils::ToLocal(handle),
|
| + par);
|
| + weak_callback_(data);
|
| + }
|
| }
|
| // Absence of explicit cleanup or revival of weak handle
|
| // in most of the cases would lead to memory leak.
|
| @@ -272,9 +299,10 @@ class GlobalHandles::Node {
|
| return true;
|
| }
|
|
|
| + inline GlobalHandles* GetGlobalHandles();
|
| +
|
| private:
|
| inline NodeBlock* FindBlock();
|
| - inline GlobalHandles* GetGlobalHandles();
|
| inline void IncreaseBlockUses();
|
| inline void DecreaseBlockUses();
|
|
|
| @@ -297,11 +325,12 @@ 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 IsRevivableCallback: public BitField<bool, 7, 1> {};
|
|
|
| uint8_t flags_;
|
|
|
| // Handle specific callback - might be a weak reference in disguise.
|
| - RevivableCallback weak_reference_callback_;
|
| + WeakCallback weak_callback_;
|
|
|
| // Provided data for callback. In FREE state, this is used for
|
| // the free list link.
|
| @@ -480,6 +509,12 @@ Handle<Object> GlobalHandles::Create(Object* value) {
|
| }
|
|
|
|
|
| +Handle<Object> GlobalHandles::CopyGlobal(Object** location) {
|
| + ASSERT(location != NULL);
|
| + return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
|
| +}
|
| +
|
| +
|
| void GlobalHandles::Destroy(Object** location) {
|
| if (location != NULL) Node::FromLocation(location)->Release();
|
| }
|
| @@ -487,9 +522,10 @@ void GlobalHandles::Destroy(Object** location) {
|
|
|
| void GlobalHandles::MakeWeak(Object** location,
|
| void* parameter,
|
| - RevivableCallback weak_reference_callback) {
|
| - ASSERT(weak_reference_callback != NULL);
|
| - Node::FromLocation(location)->MakeWeak(parameter, weak_reference_callback);
|
| + WeakCallback weak_callback,
|
| + RevivableCallback revivable_callback) {
|
| + Node::FromLocation(location)->MakeWeak(
|
| + parameter, weak_callback, revivable_callback);
|
| }
|
|
|
|
|
|
|