1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 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. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_GLOBAL_HANDLES_H_ 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_GLOBAL_HANDLES_H_ 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-profiler.h" 108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/handles.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/list.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapStats; 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ObjectVisitor; 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Structure for tracking global handles. 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A single list keeps all the allocated global handles. 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Destroyed handles stay in the list but is added to the free list. 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// At GC the destroyed global handles are removed from the free list 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and deallocated. 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Data structures for tracking object groups and implicit references. 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An object group is treated like a single JS object: if one of object in 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the group is alive, all objects in the same group are considered alive. 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An object group is used to simulate object relationship in a DOM tree. 328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An implicit references group consists of two parts: a parent object and a 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// list of children objects. If the parent is alive, all the children are alive 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// too. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ObjectGroup { 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ObjectGroup(size_t length) 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : info(NULL), length(length) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length > 0); 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch objects = new Object**[length]; 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~ObjectGroup(); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::RetainedObjectInfo* info; 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** objects; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t length; 4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ImplicitRefGroup { 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImplicitRefGroup(HeapObject** parent, size_t length) 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : parent(parent), length(length) { 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length > 0); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch children = new Object**[length]; 568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~ImplicitRefGroup(); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject** parent; 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** children; 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t length; 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// For internal bookkeeping. 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ObjectGroupConnection { 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectGroupConnection(UniqueId id, Object** object) 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : id(id), object(object) {} 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator==(const ObjectGroupConnection& other) const { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return id == other.id; 728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator<(const ObjectGroupConnection& other) const { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return id < other.id; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueId id; 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** object; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ObjectGroupRetainerInfo { 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info) 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : id(id), info(info) {} 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator==(const ObjectGroupRetainerInfo& other) const { 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return id == other.id; 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator<(const ObjectGroupRetainerInfo& other) const { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return id < other.id; 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueId id; 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RetainedObjectInfo* info; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass GlobalHandles { 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ~GlobalHandles(); 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Creates a new global handle that is alive until Destroy is called. 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> Create(Object* value); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy a global handle 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Handle<Object> CopyGlobal(Object** location); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Destroy a global handle. 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Destroy(Object** location); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback; 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make the global handle weak and set the callback parameter for the 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handle. When the garbage collector recognizes that only weak global 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handles point to an object the handles are cleared and the callback 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function is invoked (for each handle) with the handle and corresponding 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reason is that Smi::FromInt(0) does not change during garage collection. 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MakeWeak(Object** location, 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* parameter, 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WeakCallback weak_callback); 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordStats(HeapStats* stats); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the current number of weak handles. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int NumberOfWeakHandles(); 129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the current number of weak handles to global objects. 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // These handles are also included in NumberOfWeakHandles(). 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int NumberOfGlobalObjectWeakHandles(); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the current number of handles to global objects. 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int global_handles_count() const { 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return number_of_global_handles_; 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the weakness of a global handle. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void* ClearWeakness(Object** location); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Clear the weakness of a global handle. 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MarkIndependent(Object** location); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark the reference to this object externaly unreachable. 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void MarkPartiallyDependent(Object** location); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsIndependent(Object** location); 149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether global handle is near death. 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsNearDeath(Object** location); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether global handle is weak. 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsWeak(Object** location); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Process pending weak handles. 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the number of freed nodes. 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int PostGarbageCollectionProcessing(GarbageCollector collector); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Iterates over all strong handles. 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void IterateStrongRoots(ObjectVisitor* v); 162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterates over all handles. 16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void IterateAllRoots(ObjectVisitor* v); 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Iterates over all handles that have embedder-assigned class ID. 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void IterateAllRootsWithClassIds(ObjectVisitor* v); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterates over all handles in the new space that have embedder-assigned 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // class ID. 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterates over all weak roots in heap. 17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void IterateWeakRoots(ObjectVisitor* v); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find all weak handles satisfying the callback predicate, mark 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // them as pending. 17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void IdentifyWeakHandles(WeakSlotCallback f); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // NOTE: Three ...NewSpace... functions below are used during 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // scavenge collections and iterate over sets of handles that are 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // guaranteed to contain all handles holding new space objects (but 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // may also include old space objects). 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Iterates over strong and dependent handles. See the node above. 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v); 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finds weak independent or partially independent handles satisfying 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the callback predicate and marks them as pending. See the note above. 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f); 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterates over weak independent or partially independent handles. 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // See the note above. 1943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v); 195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over objects in object groups that have at least one object 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // which requires visiting. The callback has to return true if objects 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can be skipped and false otherwise. 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IterateObjectGroups(ObjectVisitor* v, WeakSlotCallbackWithHeap can_skip); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add an object group. 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be only used in GC callback function before a collection. 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All groups are destroyed after a garbage collection. 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void AddObjectGroup(Object*** handles, 20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block size_t length, 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::RetainedObjectInfo* info); 20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Associates handle with the object group represented by id. 20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be only used in GC callback function before a collection. 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All groups are destroyed after a garbage collection. 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetObjectGroupId(Object** handle, UniqueId id); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set RetainedObjectInfo for an object group. Should not be called more than 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // once for a group. Should not be called for a group which contains no 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // handles. 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Adds an implicit reference from a group to an object. Should be only used 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in GC callback function before a collection. All implicit references are 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // destroyed after a mark-compact collection. 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetReferenceFromGroup(UniqueId id, Object** child); 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Adds an implicit reference from a parent object to a child object. Should 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be only used in GC callback function before a collection. All implicit 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // references are destroyed after a mark-compact collection. 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetReference(HeapObject** parent, Object** child); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ObjectGroup*>* object_groups() { 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ComputeObjectGroupsAndImplicitReferences(); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &object_groups_; 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<ImplicitRefGroup*>* implicit_ref_groups() { 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ComputeObjectGroupsAndImplicitReferences(); 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return &implicit_ref_groups_; 23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove bags, this should only happen after GC. 23944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveObjectGroups(); 24044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveImplicitRefGroups(); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tear down the global handle structure. 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void TearDown(); 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate() { return isolate_; } 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void PrintStats(); 24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Print(); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit GlobalHandles(Isolate* isolate); 25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Migrates data from the internal representation (object_group_connections_, 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // retainer_infos_ and implicit_ref_connections_) to the public and more 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // efficient representation (object_groups_ and implicit_ref_groups_). 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ComputeObjectGroupsAndImplicitReferences(); 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // v8::internal::List is inefficient even for small number of elements, if we 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // don't assign any initial capacity. 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kObjectGroupConnectionsCapacity = 20; 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Internal node structures. 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class Node; 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class NodeBlock; 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class NodeIterator; 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 27044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Field always containing the number of handles to global objects. 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int number_of_global_handles_; 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // List of all allocated node blocks. 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* first_block_; 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // List of node blocks with used nodes. 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NodeBlock* first_used_block_; 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Free list of nodes. 28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Node* first_free_; 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Contains all nodes holding new space objects. Note: when the list 2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // is accessed, some of the objects may have been promoted already. 2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch List<Node*> new_space_nodes_; 2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int post_gc_processing_count_; 2883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Object groups and implicit references, public and more efficient 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // representation. 29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<ObjectGroup*> object_groups_; 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<ImplicitRefGroup*> implicit_ref_groups_; 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Object groups and implicit references, temporary representation while 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constructing the groups. 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ObjectGroupConnection> object_group_connections_; 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ObjectGroupRetainerInfo> retainer_infos_; 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ObjectGroupConnection> implicit_ref_connections_; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class Isolate; 30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(GlobalHandles); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass EternalHandles { 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SingletonHandle { 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch I18N_TEMPLATE_ONE, 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch I18N_TEMPLATE_TWO, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DATE_CACHE_VERSION, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NUMBER_OF_SINGLETON_HANDLES 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EternalHandles(); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~EternalHandles(); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int NumberOfHandles() { return size_; } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an EternalHandle, overwriting the index. 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Create(Isolate* isolate, Object* object, int* index); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Grab the handle for an existing EternalHandle. 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Handle<Object> Get(int index) { 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Object>(GetLocation(index)); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Grab the handle for an existing SingletonHandle. 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Handle<Object> GetSingleton(SingletonHandle singleton) { 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Exists(singleton)); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Get(singleton_handles_[singleton]); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks whether a SingletonHandle has been assigned. 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool Exists(SingletonHandle singleton) { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return singleton_handles_[singleton] != kInvalidIndex; 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assign a SingletonHandle to an empty slot and returns the handle. 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> CreateSingleton(Isolate* isolate, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object, 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SingletonHandle singleton) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Create(isolate, object, &singleton_handles_[singleton]); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Get(singleton_handles_[singleton]); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterates over all handles. 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IterateAllRoots(ObjectVisitor* visitor); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterates over all handles which might be in new space. 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IterateNewSpaceRoots(ObjectVisitor* visitor); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Rebuilds new space list. 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PostGarbageCollectionProcessing(Heap* heap); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kInvalidIndex = -1; 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kShift = 8; 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kSize = 1 << kShift; 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMask = 0xff; 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Gets the slot for an index 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Object** GetLocation(int index) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(index >= 0 && index < size_); 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &blocks_[index >> kShift][index & kMask]; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<Object**> blocks_; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<int> new_space_indices_; 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES]; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(EternalHandles); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_GLOBAL_HANDLES_H_ 379