00001 // Copyright 2007-2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_GLOBAL_HANDLES_H_ 00029 #define V8_GLOBAL_HANDLES_H_ 00030 00031 #include "list-inl.h" 00032 00033 namespace v8 { namespace internal { 00034 00035 // Structure for tracking global handles. 00036 // A single list keeps all the allocated global handles. 00037 // Destroyed handles stay in the list but is added to the free list. 00038 // At GC the destroyed global handles are removed from the free list 00039 // and deallocated. 00040 00041 // Callback function on handling weak global handles. 00042 // typedef bool (*WeakSlotCallback)(Object** pointer); 00043 00044 // An object group is indexed by an id. An object group is treated like 00045 // a single JS object: if one of object in the group is alive, 00046 // all objects in the same group are considered alive. 00047 // An object group is used to simulate object relationship in a DOM tree. 00048 class ObjectGroup : public Malloced { 00049 public: 00050 explicit ObjectGroup(void* id) : id_(id), objects_(4) {} 00051 00052 void* id_; 00053 List<Object**> objects_; 00054 }; 00055 00056 00057 class GlobalHandles : public AllStatic { 00058 public: 00059 // Creates a new global handle that is alive until Destroy is called. 00060 static Handle<Object> Create(Object* value); 00061 00062 // Destroy a global handle. 00063 static void Destroy(Object** location); 00064 00065 // Make the global handle weak and set the callback parameter for the 00066 // handle. When the garbage collector recognizes that only weak global 00067 // handles point to an object the handles are cleared and the callback 00068 // function is invoked (for each handle) with the handle and corresponding 00069 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The 00070 // reason is that Smi::FromInt(0) does not change during garage collection. 00071 static void MakeWeak(Object** location, 00072 void* parameter, 00073 WeakReferenceCallback callback); 00074 00075 // Returns the current number of weak handles. 00076 static int NumberOfWeakHandles() { return number_of_weak_handles_; } 00077 00078 // Returns the current number of weak handles to global objects. 00079 // These handles are also included in NumberOfWeakHandles(). 00080 static int NumberOfGlobalObjectWeakHandles() { 00081 return number_of_global_object_weak_handles_; 00082 } 00083 00084 // Clear the weakness of a global handle. 00085 static void ClearWeakness(Object** location); 00086 00087 // Tells whether global handle is near death. 00088 static bool IsNearDeath(Object** location); 00089 00090 // Tells whether global handle is weak. 00091 static bool IsWeak(Object** location); 00092 00093 // Process pending weak handles. 00094 static void PostGarbageCollectionProcessing(); 00095 00096 // Iterates over all handles. 00097 static void IterateRoots(ObjectVisitor* v); 00098 00099 // Iterates over all weak roots in heap. 00100 static void IterateWeakRoots(ObjectVisitor* v); 00101 00102 // Mark the weak pointers based on the callback. 00103 static void MarkWeakRoots(WeakSlotCallback f); 00104 00105 // Add an object to a group indexed by an id. 00106 // Should only used in GC callback function before a collection. 00107 // All groups are destroyed after a mark-compact collection. 00108 static void AddToGroup(void* id, Object** location); 00109 00110 // Returns the object groups. 00111 static List<ObjectGroup*>& ObjectGroups() { 00112 return object_groups_; 00113 } 00114 00115 // Remove bags, this should only happen after GC. 00116 static void RemoveObjectGroups(); 00117 00118 // Tear down the global handle structure. 00119 static void TearDown(); 00120 00121 #ifdef DEBUG 00122 static void PrintStats(); 00123 static void Print(); 00124 #endif 00125 private: 00126 // Internal node structure, one for each global handle. 00127 class Node; 00128 00129 // Field always containing the number of weak and near-death handles. 00130 static int number_of_weak_handles_; 00131 00132 // Field always containing the number of weak and near-death handles 00133 // to global objects. These objects are also included in 00134 // number_of_weak_handles_. 00135 static int number_of_global_object_weak_handles_; 00136 00137 // Global handles are kept in a single linked list pointed to by head_. 00138 static Node* head_; 00139 static Node* head() { return head_; } 00140 static void set_head(Node* value) { head_ = value; } 00141 00142 // Free list for DESTROYED global handles not yet deallocated. 00143 static Node* first_free_; 00144 static Node* first_free() { return first_free_; } 00145 static void set_first_free(Node* value) { first_free_ = value; } 00146 00147 // A list of object groups. 00148 static List<ObjectGroup*> object_groups_; 00149 }; 00150 00151 00152 } } // namespace v8::internal 00153 00154 #endif // V8_GLOBAL_HANDLES_H_