global-handles.cc revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h" 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockObjectGroup::~ObjectGroup() { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info != NULL) info->Dispose(); 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete[] objects; 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImplicitRefGroup::~ImplicitRefGroup() { 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete[] children; 2444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 2544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass GlobalHandles::Node { 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // State transition diagram: 303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum State { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FREE = 0, 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NORMAL, // Normal global handle. 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WEAK, // Flagged as weak but not yet finalized. 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PENDING, // Has been recognized as only reachable by weak handles. 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NEAR_DEATH, // Callback has informed the handle is near death. 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NUMBER_OF_NODE_STATES 383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Maps handle location (slot) to the containing node. 413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Node* FromLocation(Object** location) { 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(OFFSET_OF(Node, object_) == 0); 433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return reinterpret_cast<Node*>(location); 44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node() { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(OFFSET_OF(Node, flags_) == Internals::kNodeFlagsOffset); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(static_cast<int>(NodeState::kMask) == 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Internals::kNodeStateMask); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(PENDING == Internals::kNodeStateIsPendingValue); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(NEAR_DEATH == Internals::kNodeStateIsNearDeathValue); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(static_cast<int>(IsIndependent::kShift) == 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Internals::kNodeIsIndependentShift); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(static_cast<int>(IsPartiallyDependent::kShift) == 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Internals::kNodeIsPartiallyDependentShift); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef ENABLE_HANDLE_ZAPPING 613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ~Node() { 623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // TODO(1428): if it's a weak handle we should have invoked its callback. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Zap the values for eager trapping. 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_ = 0; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_independent(false); 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_partially_dependent(false); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_in_new_space_list(false); 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parameter_or_next_free_.next_free = NULL; 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_callback_ = NULL; 723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Initialize(int index, Node** first_free) { 763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_ = static_cast<uint8_t>(index); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<int>(index_) == index); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(FREE); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_in_new_space_list(false); 803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameter_or_next_free_.next_free = *first_free; 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *first_free = this; 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Acquire(Object* object) { 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state() == FREE); 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch object_ = object; 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_independent(false); 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_partially_dependent(false); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(NORMAL); 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameter_or_next_free_.parameter = NULL; 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_callback_ = NULL; 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncreaseBlockUses(); 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Zap() { 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Zap the values for eager trapping. 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Release() { 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(FREE); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Zap the values for eager trapping. 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_independent(false); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_partially_dependent(false); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_callback_ = NULL; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecreaseBlockUses(); 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Object slot accessors. 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* object() const { return object_; } 1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object** location() { return &object_; } 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> handle() { return Handle<Object>(location()); } 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Wrapper class ID accessors. 1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool has_wrapper_class_id() const { 1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint16_t wrapper_class_id() const { return class_id_; } 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // State and flag accessors. 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch State state() const { 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NodeState::decode(flags_); 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_state(State state) { 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags_ = NodeState::update(flags_, state); 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_independent() { 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsIndependent::decode(flags_); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_independent(bool v) { 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags_ = IsIndependent::update(flags_, v); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_partially_dependent() { 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsPartiallyDependent::decode(flags_); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_partially_dependent(bool v) { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags_ = IsPartiallyDependent::update(flags_, v); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_in_new_space_list() { 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsInNewSpaceList::decode(flags_); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_in_new_space_list(bool v) { 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags_ = IsInNewSpaceList::update(flags_, v); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WeaknessType weakness_type() const { 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NodeWeaknessType::decode(flags_); 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_weakness_type(WeaknessType weakness_type) { 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier flags_ = NodeWeaknessType::update(flags_, weakness_type); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsNearDeath() const { 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check for PENDING to ensure correct answer when processing callbacks. 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return state() == PENDING || state() == NEAR_DEATH; 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsWeak() const { return state() == WEAK; } 1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool IsInUse() const { return state() != FREE; } 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsRetainer() const { return state() != FREE; } 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsStrongRetainer() const { return state() == NORMAL; } 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsWeakRetainer() const { 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return state() == WEAK || state() == PENDING || state() == NEAR_DEATH; 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void MarkPending() { 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state() == WEAK); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(PENDING); 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Independent flag accessors. 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void MarkIndependent() { 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_independent(true); 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkPartiallyDependent() { 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetGlobalHandles()->isolate()->heap()->InNewSpace(object_)) { 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_partially_dependent(true); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void clear_partially_dependent() { set_partially_dependent(false); } 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Callback accessor. 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(svenpanne) Re-enable or nuke later. 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // WeakReferenceCallback callback() { return callback_; } 2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Callback parameter accessors. 2043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void set_parameter(void* parameter) { 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == NORMAL_WEAK || weakness_type() == PHANTOM_WEAK); 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parameter_or_next_free_.parameter = parameter; 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void* parameter() const { 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return parameter_or_next_free_.parameter; 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_internal_fields(int internal_field_index1, 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int internal_field_index2) { 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // These are stored in an int16_t. 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index1 < 1 << 16); 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index1 >= -(1 << 16)); 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index2 < 1 << 16); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index2 >= -(1 << 16)); 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_or_next_free_.internal_field_indeces.internal_field1 = 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<int16_t>(internal_field_index1); 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_or_next_free_.internal_field_indeces.internal_field2 = 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<int16_t>(internal_field_index2); 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int internal_field1() const { 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return parameter_or_next_free_.internal_field_indeces.internal_field1; 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int internal_field2() const { 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK); 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return parameter_or_next_free_.internal_field_indeces.internal_field2; 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors for next free node in the free list. 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Node* next_free() { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state() == FREE); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return parameter_or_next_free_.next_free; 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_next_free(Node* value) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state() == FREE); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parameter_or_next_free_.next_free = value; 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MakeWeak(void* parameter, WeakCallback weak_callback) { 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(weak_callback != NULL); 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(object_ != NULL); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(WEAK); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_weakness_type(NORMAL_WEAK); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_parameter(parameter); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_callback_ = weak_callback; 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void MakePhantom(void* parameter, 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PhantomCallbackData<void>::Callback phantom_callback, 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t internal_field_index1, 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t internal_field_index2) { 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(phantom_callback != NULL); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(object_ != NULL); 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_state(WEAK); 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (parameter == NULL) { 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_weakness_type(INTERNAL_FIELDS_WEAK); 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_internal_fields(internal_field_index1, internal_field_index2); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index1 == v8::Object::kNoInternalFieldIndex); 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(internal_field_index2 == v8::Object::kNoInternalFieldIndex); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_weakness_type(PHANTOM_WEAK); 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_parameter(parameter); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback); 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* ClearWeakness() { 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsInUse()); 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* p = parameter(); 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(NORMAL); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_parameter(NULL); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return p; 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CollectPhantomCallbackData( 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Isolate* isolate, List<PendingPhantomCallback>* pending_phantom_callbacks, 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier List<PendingInternalFieldsCallback>* pending_internal_fields_callbacks) { 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (state() != Node::PENDING) return; 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool do_release = true; 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (weak_callback_ != NULL) { 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (weakness_type() == NORMAL_WEAK) return; 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate); 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (weakness_type() == PHANTOM_WEAK) { 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Phantom weak pointer case. Zap with harmless value. 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(*location() == Smi::FromInt(0)); 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef PhantomCallbackData<void> Data; 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Data data(api_isolate, parameter()); 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Data::Callback callback = 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Data::Callback>(weak_callback_); 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pending_phantom_callbacks->Add( 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PendingPhantomCallback(this, data, callback)); 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Postpone the release of the handle. The embedder can't use the 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // handle (it's zapped), but it may be using the location, and we 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // don't want to confuse things by reusing that. 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do_release = false; 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef InternalFieldsCallbackData<void, void> Data; 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Phantom weak pointer case, passing internal fields instead of 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // parameter. Don't use a handle here during GC, because it will 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // create a handle pointing to a dying object, which can confuse 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the next GC. 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSObject* jsobject = reinterpret_cast<JSObject*>(object()); 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(jsobject->IsJSObject()); 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Data data(api_isolate, jsobject->GetInternalField(internal_field1()), 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier jsobject->GetInternalField(internal_field2())); 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Data::Callback callback = 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Data::Callback>(weak_callback_); 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // In the future, we want to delay the callback. In that case we will 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // zap when we queue up, to stop the C++ side accessing the dead V8 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // object, but we will call Release only after the callback (allowing 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the node to be reused). 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pending_internal_fields_callbacks->Add( 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PendingInternalFieldsCallback(data, callback)); 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(erikcorry): At the moment the callbacks are not postponed much, 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // but if we really postpone them until after the mutator has run, we 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // need to divide things up, so that an early callback clears the handle, 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // while a later one destroys the objects involved, possibley triggering 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // some work when decremented ref counts hit zero. 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (do_release) Release(); 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool PostGarbageCollectionProcessing(Isolate* isolate) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (state() != Node::PENDING) return false; 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (weak_callback_ == NULL) { 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Release(); 34750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen return false; 34850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen } 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_state(NEAR_DEATH); 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that we are not passing a finalized external string to 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the callback. 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!object_->IsExternalOneByteString() || 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalOneByteString::cast(object_)->resource() != NULL); 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!object_->IsExternalTwoByteString() || 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalTwoByteString::cast(object_)->resource() != NULL); 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Leaving V8. 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VMState<EXTERNAL> vmstate(isolate); 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope handle_scope(isolate); 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (weakness_type() == PHANTOM_WEAK) return false; 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(weakness_type() == NORMAL_WEAK); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** object = location(); 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> handle(*object, isolate); 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::WeakCallbackData<v8::Value, void> data( 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<v8::Isolate*>(isolate), parameter(), 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::Utils::ToLocal(handle)); 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_parameter(NULL); 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier weak_callback_(data); 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Absence of explicit cleanup or revival of weak handle 37150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen // in most of the cases would lead to memory leak. 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(state() != NEAR_DEATH); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline GlobalHandles* GetGlobalHandles(); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 3793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline NodeBlock* FindBlock(); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void IncreaseBlockUses(); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void DecreaseBlockUses(); 3823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Storage for object pointer. 3843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Placed first to avoid offset computation. 3853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* object_; 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Next word stores class_id, index, state, and independent. 3883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Note: the most aligned fields should go first. 3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Wrapper class ID. 39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t class_id_; 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Index in the containing handle block. 3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint8_t index_; 3953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This stores three flags (independent, partially_dependent and 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in_new_space_list) and a State. 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class NodeState : public BitField<State, 0, 3> {}; 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class IsIndependent : public BitField<bool, 3, 1> {}; 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class IsPartiallyDependent : public BitField<bool, 4, 1> {}; 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class IsInNewSpaceList : public BitField<bool, 5, 1> {}; 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {}; 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t flags_; 405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle specific callback - might be a weak reference in disguise. 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WeakCallback weak_callback_; 4083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Provided data for callback. In FREE state, this is used for 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the free list link. 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block union { 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* parameter; 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier struct { 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t internal_field1; 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t internal_field2; 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } internal_field_indeces; 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Node* next_free; 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } parameter_or_next_free_; 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DISALLOW_COPY_AND_ASSIGN(Node); 4213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 4223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass GlobalHandles::NodeBlock { 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kSize = 256; 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit NodeBlock(GlobalHandles* global_handles, NodeBlock* next) 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : next_(next), 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch used_nodes_(0), 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_used_(NULL), 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_used_(NULL), 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles_(global_handles) {} 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void PutNodesOnFreeList(Node** first_free) { 4363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = kSize - 1; i >= 0; --i) { 4373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch nodes_[i].Initialize(i, first_free); 438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 440d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node_at(int index) { 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(0 <= index && index < kSize); 4433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return &nodes_[index]; 4443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncreaseUses() { 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(used_nodes_ < kSize); 4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (used_nodes_++ == 0) { 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeBlock* old_first = global_handles_->first_used_block_; 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles_->first_used_block_ = this; 4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_used_ = old_first; 4523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch prev_used_ = NULL; 4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (old_first == NULL) return; 4543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch old_first->prev_used_ = this; 455bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 457bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecreaseUses() { 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(used_nodes_ > 0); 4603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (--used_nodes_ == 0) { 4613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (next_used_ != NULL) next_used_->prev_used_ = prev_used_; 4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (prev_used_ != NULL) prev_used_->next_used_ = next_used_; 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (this == global_handles_->first_used_block_) { 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles_->first_used_block_ = next_used_; 465d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 466d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 468d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles* global_handles() { return global_handles_; } 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Next block in the list of all blocks. 4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* next() const { return next_; } 473d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Next/previous block in the list of blocks with used nodes. 4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* next_used() const { return next_used_; } 4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* prev_used() const { return prev_used_; } 4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node nodes_[kSize]; 4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* const next_; 4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int used_nodes_; 4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* next_used_; 4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* prev_used_; 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles* global_handles_; 4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 4863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochGlobalHandles* GlobalHandles::Node::GetGlobalHandles() { 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FindBlock()->global_handles(); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochGlobalHandles::NodeBlock* GlobalHandles::Node::FindBlock() { 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch intptr_t ptr = reinterpret_cast<intptr_t>(this); 4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ptr = ptr - index_ * sizeof(Node); 4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* block = reinterpret_cast<NodeBlock*>(ptr); 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block->node_at(index_) == this); 4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return block; 4993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::Node::IncreaseBlockUses() { 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeBlock* node_block = FindBlock(); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_block->IncreaseUses(); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles* global_handles = node_block->global_handles(); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles->isolate()->counters()->global_handles()->Increment(); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles->number_of_global_handles_++; 5083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::Node::DecreaseBlockUses() { 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeBlock* node_block = FindBlock(); 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles* global_handles = node_block->global_handles(); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parameter_or_next_free_.next_free = global_handles->first_free_; 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles->first_free_ = this; 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_block->DecreaseUses(); 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles->isolate()->counters()->global_handles()->Decrement(); 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_handles->number_of_global_handles_--; 5193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass GlobalHandles::NodeIterator { 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit NodeIterator(GlobalHandles* global_handles) 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : block_(global_handles->first_used_block_), 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_(0) {} 5273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool done() const { return block_ == NULL; } 5293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node() const { 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!done()); 5323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return block_->node_at(index_); 5333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 534d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Advance() { 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!done()); 5373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (++index_ < NodeBlock::kSize) return; 5383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_ = 0; 5393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_ = block_->next_used(); 5403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* block_; 5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int index_; 5453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DISALLOW_COPY_AND_ASSIGN(NodeIterator); 547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 548d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 549d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 55044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockGlobalHandles::GlobalHandles(Isolate* isolate) 55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch number_of_global_handles_(0), 5533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_block_(NULL), 5543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_used_block_(NULL), 55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block first_free_(NULL), 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch post_gc_processing_count_(0), 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_(kObjectGroupConnectionsCapacity) {} 55844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 55944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 56044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockGlobalHandles::~GlobalHandles() { 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* block = first_block_; 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (block != NULL) { 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* tmp = block->next(); 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch delete block; 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block = tmp; 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_block_ = NULL; 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 569d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 570d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GlobalHandles::Create(Object* value) { 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (first_free_ == NULL) { 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_block_ = new NodeBlock(this, first_block_); 5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_block_->PutNodesOnFreeList(&first_free_); 5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first_free_ != NULL); 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Take the first node in the free list. 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* result = first_free_; 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch first_free_ = result->next_free(); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Acquire(value); 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (isolate_->heap()->InNewSpace(value) && 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !result->is_in_new_space_list()) { 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch new_space_nodes_.Add(result); 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result->set_in_new_space_list(true); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result->handle(); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> GlobalHandles::CopyGlobal(Object** location) { 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(location != NULL); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Node::FromLocation(location)->GetGlobalHandles()->Create(*location); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid GlobalHandles::Destroy(Object** location) { 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (location != NULL) Node::FromLocation(location)->Release(); 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::MakeWeak(Object** location, void* parameter, 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WeakCallback weak_callback) { 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node::FromLocation(location)->MakeWeak(parameter, weak_callback); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef PhantomCallbackData<void>::Callback GenericCallback; 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::MakePhantom( 611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object** location, 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::InternalFieldsCallbackData<void, void>::Callback phantom_callback, 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t internal_field_index1, int16_t internal_field_index2) { 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node::FromLocation(location) 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->MakePhantom(NULL, reinterpret_cast<GenericCallback>(phantom_callback), 616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier internal_field_index1, internal_field_index2); 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::MakePhantom(Object** location, void* parameter, 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenericCallback phantom_callback) { 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node::FromLocation(location)->MakePhantom(parameter, phantom_callback, 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::Object::kNoInternalFieldIndex, 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::Object::kNoInternalFieldIndex); 625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::CollectPhantomCallbackData() { 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (NodeIterator it(this); !it.done(); it.Advance()) { 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* node = it.node(); 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->CollectPhantomCallbackData(isolate(), &pending_phantom_callbacks_, 632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &pending_internal_fields_callbacks_); 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* GlobalHandles::ClearWeakness(Object** location) { 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Node::FromLocation(location)->ClearWeakness(); 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 642257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid GlobalHandles::MarkIndependent(Object** location) { 6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node::FromLocation(location)->MarkIndependent(); 644257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 645257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 646257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::MarkPartiallyDependent(Object** location) { 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node::FromLocation(location)->MarkPartiallyDependent(); 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool GlobalHandles::IsIndependent(Object** location) { 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Node::FromLocation(location)->is_independent(); 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool GlobalHandles::IsNearDeath(Object** location) { 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Node::FromLocation(location)->IsNearDeath(); 65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool GlobalHandles::IsWeak(Object** location) { 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Node::FromLocation(location)->IsWeak(); 6643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 6683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* node = it.node(); 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->IsWeakRetainer()) { 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Weakness type can be normal, phantom or internal fields. 672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // For normal weakness we mark through the handle so that 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the object and things reachable from it are available 674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to the callback. 675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // In the case of phantom we can zap the object handle now 676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and we won't need it, so we don't need to mark through it. 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // In the internal fields case we will need the internal 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // fields, so we can't zap the handle, but we don't need to 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mark through it, because it will die in this GC round. 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->state() == Node::PENDING) { 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->weakness_type() == PHANTOM_WEAK) { 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(node->location()) = Smi::FromInt(0); 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (node->weakness_type() == NORMAL_WEAK) { 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v->VisitPointer(node->location()); 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(node->weakness_type() == INTERNAL_FIELDS_WEAK); 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Node is not pending, so that means the object survived. We still 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // need to visit the pointer in case the object moved, eg. because of 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // compaction. 692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v->VisitPointer(node->location()); 693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 6993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { 7003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 7013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->IsWeak() && f(it.node()->location())) { 7023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch it.node()->MarkPending(); 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) { 7093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < new_space_nodes_.length(); ++i) { 7103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node = new_space_nodes_[i]; 7113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (node->IsStrongRetainer() || 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (node->IsWeakRetainer() && !node->is_independent() && 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !node->is_partially_dependent())) { 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointer(node->location()); 7153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 7163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 7173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 7183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid GlobalHandles::IdentifyNewSpaceWeakIndependentHandles( 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WeakSlotCallbackWithHeap f) { 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < new_space_nodes_.length(); ++i) { 7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node = new_space_nodes_[i]; 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(node->is_in_new_space_list()); 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((node->is_independent() || node->is_partially_dependent()) && 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node->IsWeak() && f(isolate_->heap(), node->location())) { 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch node->MarkPending(); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { 7343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < new_space_nodes_.length(); ++i) { 7353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node = new_space_nodes_[i]; 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(node->is_in_new_space_list()); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((node->is_independent() || node->is_partially_dependent()) && 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node->IsWeakRetainer()) { 739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->weakness_type() == PHANTOM_WEAK) { 740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *(node->location()) = Smi::FromInt(0); 741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (node->weakness_type() == NORMAL_WEAK) { 742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v->VisitPointer(node->location()); 743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(node->weakness_type() == INTERNAL_FIELDS_WEAK); 745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // For this case we only need to trace if it's alive: The tracing of 746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // something that is already alive is just to get the pointer updated 747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to the new location of the object). 748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(node->state() != Node::NEAR_DEATH); 749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->state() != Node::PENDING) { 750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v->VisitPointer(node->location()); 751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 753257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 754257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WeakSlotCallbackWithHeap can_skip) { 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ComputeObjectGroupsAndImplicitReferences(); 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last = 0; 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool any_group_was_visited = false; 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < object_groups_.length(); i++) { 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectGroup* entry = object_groups_.at(i); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(entry != NULL); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** objects = entry->objects; 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool group_should_be_visited = false; 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t j = 0; j < entry->length; j++) { 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object = *objects[j]; 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsHeapObject()) { 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!can_skip(isolate_->heap(), &object)) { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group_should_be_visited = true; 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!group_should_be_visited) { 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_groups_[last++] = entry; 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // An object in the group requires visiting, so iterate over all 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects in the group. 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t j = 0; j < entry->length; ++j) { 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object = *objects[j]; 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsHeapObject()) { 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointer(&object); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch any_group_was_visited = true; 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Once the entire group has been iterated over, set the object 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // group to NULL so it won't be processed again. 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete entry; 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_groups_.at(i) = NULL; 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_groups_.Rewind(last); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return any_group_was_visited; 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint GlobalHandles::PostScavengeProcessing( 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int initial_post_gc_processing_count) { 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int freed_nodes = 0; 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < new_space_nodes_.length(); ++i) { 808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* node = new_space_nodes_[i]; 809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(node->is_in_new_space_list()); 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!node->IsRetainer()) { 811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Free nodes do not have weak callbacks. Do not use them to compute 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the freed_nodes. 813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Skip dependent handles. Their weak callbacks might expect to be 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // called between two global garbage collection callbacks which 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // are not called for minor collections. 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!node->is_independent() && !node->is_partially_dependent()) { 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->clear_partially_dependent(); 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->PostGarbageCollectionProcessing(isolate_)) { 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (initial_post_gc_processing_count != post_gc_processing_count_) { 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Weak callback triggered another GC and another round of 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // PostGarbageCollection processing. The current node might 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // have been deleted in that round, so we need to bail out (or 827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // restart the processing). 828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!node->IsRetainer()) { 832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes++; 833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint GlobalHandles::PostMarkSweepProcessing( 840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int initial_post_gc_processing_count) { 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int freed_nodes = 0; 842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (NodeIterator it(this); !it.done(); it.Advance()) { 843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!it.node()->IsRetainer()) { 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Free nodes do not have weak callbacks. Do not use them to compute 845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the freed_nodes. 846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier it.node()->clear_partially_dependent(); 849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (it.node()->PostGarbageCollectionProcessing(isolate_)) { 850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (initial_post_gc_processing_count != post_gc_processing_count_) { 851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See the comment above. 852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!it.node()->IsRetainer()) { 856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes++; 857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::UpdateListOfNewSpaceNodes() { 8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int last = 0; 8653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < new_space_nodes_.length(); ++i) { 8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Node* node = new_space_nodes_[i]; 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(node->is_in_new_space_list()); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (node->IsRetainer()) { 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->heap()->InNewSpace(node->object())) { 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_nodes_[last++] = node; 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->heap()->IncrementNodesCopiedInNewSpace(); 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node->set_in_new_space_list(false); 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->heap()->IncrementNodesPromoted(); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch node->set_in_new_space_list(false); 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->heap()->IncrementNodesDiedInNewSpace(); 8793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 880d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 8813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch new_space_nodes_.Rewind(last); 882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint GlobalHandles::DispatchPendingPhantomCallbacks() { 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int freed_nodes = 0; 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (pending_phantom_callbacks_.length() != 0) { 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PendingPhantomCallback callback = pending_phantom_callbacks_.RemoveLast(); 889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier callback.invoke(); 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes++; 891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (pending_internal_fields_callbacks_.length() != 0) { 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PendingInternalFieldsCallback callback = 894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pending_internal_fields_callbacks_.RemoveLast(); 895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier callback.invoke(); 896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes++; 897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return freed_nodes; 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint GlobalHandles::PostGarbageCollectionProcessing(GarbageCollector collector) { 903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Process weak global handle callbacks. This must be done after the 904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // GC is completely done, because the callbacks may invoke arbitrary 905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // API functions. 906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int initial_post_gc_processing_count = ++post_gc_processing_count_; 908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int freed_nodes = 0; 909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (collector == SCAVENGER) { 910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes = PostScavengeProcessing(initial_post_gc_processing_count); 911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes = PostMarkSweepProcessing(initial_post_gc_processing_count); 913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (initial_post_gc_processing_count != post_gc_processing_count_) { 915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the callbacks caused a nested GC, then return. See comment in 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // PostScavengeProcessing. 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier freed_nodes += DispatchPendingPhantomCallbacks(); 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (initial_post_gc_processing_count == post_gc_processing_count_) { 921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UpdateListOfNewSpaceNodes(); 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return freed_nodes; 924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid GlobalHandles::PendingPhantomCallback::invoke() { 928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node_->state() == Node::FREE) return; 929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(node_->state() == Node::NEAR_DEATH); 930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier callback_(data_); 931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node_->state() != Node::FREE) node_->Release(); 932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 935d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid GlobalHandles::IterateStrongRoots(ObjectVisitor* v) { 9363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 9373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->IsStrongRetainer()) { 9383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitPointer(it.node()->location()); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 944d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid GlobalHandles::IterateAllRoots(ObjectVisitor* v) { 9453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 9463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->IsRetainer()) { 9473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitPointer(it.node()->location()); 948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 95344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { 9543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.node()->IsRetainer() && it.node()->has_wrapper_class_id()) { 9563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v->VisitEmbedderReference(it.node()->location(), 9573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch it.node()->wrapper_class_id()); 95844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 95944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 96044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 96244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v) { 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < new_space_nodes_.length(); ++i) { 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node = new_space_nodes_[i]; 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (node->IsRetainer() && node->has_wrapper_class_id()) { 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitEmbedderReference(node->location(), 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node->wrapper_class_id()); 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint GlobalHandles::NumberOfWeakHandles() { 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.node()->IsWeakRetainer()) { 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count++; 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return count; 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint GlobalHandles::NumberOfGlobalObjectWeakHandles() { 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.node()->IsWeakRetainer() && 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.node()->object()->IsJSGlobalObject()) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count++; 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return count; 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 997d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid GlobalHandles::RecordStats(HeapStats* stats) { 998d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->global_handle_count = 0; 999d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->weak_global_handle_count = 0; 1000d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->pending_global_handle_count = 0; 1001d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->near_death_global_handle_count = 0; 10023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *stats->free_global_handle_count = 0; 10033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 1004d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->global_handle_count += 1; 10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->state() == Node::WEAK) { 1006d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->weak_global_handle_count += 1; 10073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (it.node()->state() == Node::PENDING) { 1008d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->pending_global_handle_count += 1; 10093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (it.node()->state() == Node::NEAR_DEATH) { 1010d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *stats->near_death_global_handle_count += 1; 10113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (it.node()->state() == Node::FREE) { 10123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *stats->free_global_handle_count += 1; 1013d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1014d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1015d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid GlobalHandles::PrintStats() { 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int total = 0; 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int weak = 0; 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pending = 0; 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int near_death = 0; 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int destroyed = 0; 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block total++; 10283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->state() == Node::WEAK) weak++; 10293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->state() == Node::PENDING) pending++; 10303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->state() == Node::NEAR_DEATH) near_death++; 10313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (it.node()->state() == Node::FREE) destroyed++; 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("Global Handle Statistics:\n"); 1035f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch PrintF(" allocated memory = %" V8_PTR_PREFIX "dB\n", sizeof(Node) * total); 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF(" # weak = %d\n", weak); 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF(" # pending = %d\n", pending); 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF(" # near_death = %d\n", near_death); 10393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF(" # free = %d\n", destroyed); 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF(" # total = %d\n", total); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid GlobalHandles::Print() { 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("Global handles:\n"); 10463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (NodeIterator it(this); !it.done(); it.Advance()) { 10473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF(" handle %p to %p%s\n", 10483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<void*>(it.node()->location()), 10493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<void*>(it.node()->object()), 10503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch it.node()->IsWeak() ? " (weak)" : ""); 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 105844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid GlobalHandles::AddObjectGroup(Object*** handles, 105944f0eee88ff00398ff7f715fab053374d808c90dSteve Block size_t length, 106044f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::RetainedObjectInfo* info) { 1061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG 1062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (size_t i = 0; i < length; ++i) { 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Node::FromLocation(handles[i])->is_independent()); 1064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 10668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (length == 0) { 10678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (info != NULL) info->Dispose(); 10688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return; 106944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectGroup* group = new ObjectGroup(length); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < length; ++i) 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->objects[i] = handles[i]; 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->info = info; 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_groups_.Add(group); 107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 107644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 107744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::SetObjectGroupId(Object** handle, 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueId id) { 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Add(ObjectGroupConnection(id, handle)); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::SetRetainedObjectInfo(UniqueId id, 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RetainedObjectInfo* info) { 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_.Add(ObjectGroupRetainerInfo(id, info)); 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::SetReferenceFromGroup(UniqueId id, Object** child) { 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Node::FromLocation(child)->is_independent()); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_.Add(ObjectGroupConnection(id, child)); 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::SetReference(HeapObject** parent, Object** child) { 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Node::FromLocation(child)->is_independent()); 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImplicitRefGroup* group = new ImplicitRefGroup(parent, 1); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->children[0] = child; 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_groups_.Add(group); 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid GlobalHandles::RemoveObjectGroups() { 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < object_groups_.length(); i++) 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete object_groups_.at(i); 110744f0eee88ff00398ff7f715fab053374d808c90dSteve Block object_groups_.Clear(); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < retainer_infos_.length(); ++i) 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_[i].info->Dispose(); 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_.Clear(); 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Clear(); 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Initialize(kObjectGroupConnectionsCapacity); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 111644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid GlobalHandles::RemoveImplicitRefGroups() { 111744f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < implicit_ref_groups_.length(); i++) { 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete implicit_ref_groups_.at(i); 111944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 112044f0eee88ff00398ff7f715fab053374d808c90dSteve Block implicit_ref_groups_.Clear(); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_.Clear(); 112244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 112344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 112444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid GlobalHandles::TearDown() { 11263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // TODO(1428): invoke weak callbacks. 11273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 11283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid GlobalHandles::ComputeObjectGroupsAndImplicitReferences() { 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_group_connections_.length() == 0) { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < retainer_infos_.length(); ++i) 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_[i].info->Dispose(); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_.Clear(); 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_.Clear(); 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Sort(); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_.Sort(); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_.Sort(); 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int info_index = 0; // For iterating retainer_infos_. 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueId current_group_id(0); 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_group_start = 0; 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_implicit_refs_start = 0; 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_implicit_refs_end = 0; 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i <= object_group_connections_.length(); ++i) { 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == 0) 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_id = object_group_connections_[i].id; 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == object_group_connections_.length() || 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_id != object_group_connections_[i].id) { 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Group detected: objects in indices [current_group_start, i[. 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find out which implicit references are related to this group. (We want 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to ignore object groups which only have 1 object, but that object is 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // needed as a representative object for the implicit refrerence group.) 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current_implicit_refs_start < implicit_ref_connections_.length() && 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_[current_implicit_refs_start].id < 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_id) 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++current_implicit_refs_start; 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_implicit_refs_end = current_implicit_refs_start; 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current_implicit_refs_end < implicit_ref_connections_.length() && 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_[current_implicit_refs_end].id == 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_id) 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++current_implicit_refs_end; 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_implicit_refs_end > current_implicit_refs_start) { 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find a representative object for the implicit references. 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** representative = NULL; 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = current_group_start; j < i; ++j) { 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** object = object_group_connections_[j].object; 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*object)->IsHeapObject()) { 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch representative = reinterpret_cast<HeapObject**>(object); 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (representative) { 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImplicitRefGroup* group = new ImplicitRefGroup( 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch representative, 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_implicit_refs_end - current_implicit_refs_start); 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = current_implicit_refs_start; 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j < current_implicit_refs_end; 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++j) { 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->children[j - current_implicit_refs_start] = 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_[j].object; 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_groups_.Add(group); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_implicit_refs_start = current_implicit_refs_end; 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find a RetainedObjectInfo for the group. 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RetainedObjectInfo* info = NULL; 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (info_index < retainer_infos_.length() && 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_[info_index].id < current_group_id) { 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_[info_index].info->Dispose(); 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++info_index; 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info_index < retainer_infos_.length() && 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_[info_index].id == current_group_id) { 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This object group has an associated ObjectGroupRetainerInfo. 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info = retainer_infos_[info_index].info; 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++info_index; 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ignore groups which only contain one object. 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i > current_group_start + 1) { 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectGroup* group = new ObjectGroup(i - current_group_start); 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = current_group_start; j < i; ++j) { 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->objects[j - current_group_start] = 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_[j].object; 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch group->info = info; 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_groups_.Add(group); 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (info) { 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->Dispose(); 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < object_group_connections_.length()) { 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_id = object_group_connections_[i].id; 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_group_start = i; 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Clear(); 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_group_connections_.Initialize(kObjectGroupConnectionsCapacity); 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch retainer_infos_.Clear(); 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_ref_connections_.Clear(); 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEternalHandles::EternalHandles() : size_(0) { 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < arraysize(singleton_handles_); i++) { 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch singleton_handles_[i] = kInvalidIndex; 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEternalHandles::~EternalHandles() { 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); i++) delete[] blocks_[i]; 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EternalHandles::IterateAllRoots(ObjectVisitor* visitor) { 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit = size_; 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); i++) { 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(limit > 0); 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** block = blocks_[i]; 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitPointers(block, block + Min(limit, kSize)); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch limit -= kSize; 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EternalHandles::IterateNewSpaceRoots(ObjectVisitor* visitor) { 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < new_space_indices_.length(); i++) { 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitPointer(GetLocation(new_space_indices_[i])); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EternalHandles::PostGarbageCollectionProcessing(Heap* heap) { 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last = 0; 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < new_space_indices_.length(); i++) { 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = new_space_indices_[i]; 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (heap->InNewSpace(*GetLocation(index))) { 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_indices_[last++] = index; 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_indices_.Rewind(last); 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EternalHandles::Create(Isolate* isolate, Object* object, int* index) { 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(kInvalidIndex, *index); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object == NULL) return; 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(isolate->heap()->the_hole_value(), object); 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block = size_ >> kShift; 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset = size_ & kMask; 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // need to resize 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (offset == 0) { 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** next_block = new Object*[kSize]; 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* the_hole = isolate->heap()->the_hole_value(); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemsetPointer(next_block, the_hole, kSize); 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Add(next_block); 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[block][offset] = object; 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate->heap()->InNewSpace(object)) { 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_indices_.Add(size_); 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *index = size_++; 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1299