1fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_GLOBAL_HANDLES_H_
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_GLOBAL_HANDLES_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "include/v8.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "include/v8-profiler.h"
108b0c11e7c3572e417fc6a6c7238430b49c8031eericow@chromium.org
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/handles.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/list.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgclass HeapStats;
19e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgclass ObjectVisitor;
20e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Structure for tracking global handles.
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A single list keeps all the allocated global handles.
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Destroyed handles stay in the list but is added to the free list.
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// At GC the destroyed global handles are removed from the free list
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and deallocated.
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Data structures for tracking object groups and implicit references.
28ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
298bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org// An object group is treated like a single JS object: if one of object in
308bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org// the group is alive, all objects in the same group are considered alive.
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// An object group is used to simulate object relationship in a DOM tree.
32ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
33ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// An implicit references group consists of two parts: a parent object and a
34ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// list of children objects.  If the parent is alive, all the children are alive
35ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// too.
36ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
37ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgstruct ObjectGroup {
38ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  explicit ObjectGroup(size_t length)
39ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : info(NULL), length(length) {
40e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(length > 0);
41ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    objects = new Object**[length];
4244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
43ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ~ObjectGroup();
4444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
45ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  v8::RetainedObjectInfo* info;
46ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Object*** objects;
47ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  size_t length;
48ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org};
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
51ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgstruct ImplicitRefGroup {
52ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ImplicitRefGroup(HeapObject** parent, size_t length)
53ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : parent(parent), length(length) {
54e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(length > 0);
55ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    children = new Object**[length];
56ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
57ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ~ImplicitRefGroup();
58ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
59ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HeapObject** parent;
60ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Object*** children;
61ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  size_t length;
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// For internal bookkeeping.
66ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgstruct ObjectGroupConnection {
67ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ObjectGroupConnection(UniqueId id, Object** object)
68ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : id(id), object(object) {}
69ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
70ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool operator==(const ObjectGroupConnection& other) const {
71ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    return id == other.id;
7244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
7344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
74ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool operator<(const ObjectGroupConnection& other) const {
75ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    return id < other.id;
7644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
77badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
78ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  UniqueId id;
79ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Object** object;
80ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org};
81badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
82ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
83ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgstruct ObjectGroupRetainerInfo {
84ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info)
85ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : id(id), info(info) {}
86ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
87ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool operator==(const ObjectGroupRetainerInfo& other) const {
88ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    return id == other.id;
89ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
90ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
91ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool operator<(const ObjectGroupRetainerInfo& other) const {
92ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    return id < other.id;
93ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
94ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
95ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  UniqueId id;
96ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  RetainedObjectInfo* info;
97badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org};
98badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
99badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass GlobalHandles {
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ~GlobalHandles();
103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Creates a new global handle that is alive until Destroy is called.
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> Create(Object* value);
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  // Copy a global handle
108639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  static Handle<Object> CopyGlobal(Object** location);
109639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Destroy a global handle.
111a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  static void Destroy(Object** location);
11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback;
11457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make the global handle weak and set the callback parameter for the
11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // handle.  When the garbage collector recognizes that only weak global
11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // handles point to an object the handles are cleared and the callback
11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // function is invoked (for each handle) with the handle and corresponding
11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parameter as arguments.  Note: cleared means set to Smi::FromInt(0). The
12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reason is that Smi::FromInt(0) does not change during garage collection.
121b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  static void MakeWeak(Object** location,
122b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                       void* parameter,
1234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                       WeakCallback weak_callback);
12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
125ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void RecordStats(HeapStats* stats);
1266012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org
12728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  // Returns the current number of weak handles.
12828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  int NumberOfWeakHandles();
12928381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org
13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns the current number of weak handles to global objects.
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // These handles are also included in NumberOfWeakHandles().
13228381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  int NumberOfGlobalObjectWeakHandles();
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Returns the current number of handles to global objects.
1351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int global_handles_count() const {
136bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    return number_of_global_handles_;
137bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
138bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear the weakness of a global handle.
140381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  static void* ClearWeakness(Object** location);
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Clear the weakness of a global handle.
143b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  static void MarkIndependent(Object** location);
14489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
145e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Mark the reference to this object externaly unreachable.
146b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  static void MarkPartiallyDependent(Object** location);
147e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool IsIndependent(Object** location);
149c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Tells whether global handle is near death.
15143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static bool IsNearDeath(Object** location);
15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Tells whether global handle is weak.
15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static bool IsWeak(Object** location);
15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
156303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Process pending weak handles.
157c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // Returns the number of freed nodes.
15893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  int PostGarbageCollectionProcessing(GarbageCollector collector);
15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Iterates over all strong handles.
161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void IterateStrongRoots(ObjectVisitor* v);
162c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterates over all handles.
164ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void IterateAllRoots(ObjectVisitor* v);
16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
166b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // Iterates over all handles that have embedder-assigned class ID.
167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void IterateAllRootsWithClassIds(ObjectVisitor* v);
168b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
169003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Iterates over all handles in the new space that have embedder-assigned
170003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // class ID.
171003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v);
172003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterates over all weak roots in heap.
174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void IterateWeakRoots(ObjectVisitor* v);
17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Find all weak handles satisfying the callback predicate, mark
1779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // them as pending.
178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void IdentifyWeakHandles(WeakSlotCallback f);
17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
180e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // NOTE: Three ...NewSpace... functions below are used during
181e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // scavenge collections and iterate over sets of handles that are
182e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // guaranteed to contain all handles holding new space objects (but
183e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // may also include old space objects).
184e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
185e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // Iterates over strong and dependent handles. See the node above.
186e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
187e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
188e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Finds weak independent or partially independent handles satisfying
189e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // the callback predicate and marks them as pending. See the note above.
190e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
191e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
192e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Iterates over weak independent or partially independent handles.
193e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // See the note above.
194e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
19649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Iterate over objects in object groups that have at least one object
19749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // which requires visiting. The callback has to return true if objects
19849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // can be skipped and false otherwise.
19949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  bool IterateObjectGroups(ObjectVisitor* v, WeakSlotCallbackWithHeap can_skip);
20049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
2018bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // Add an object group.
202badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // Should be only used in GC callback function before a collection.
203e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // All groups are destroyed after a garbage collection.
204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void AddObjectGroup(Object*** handles,
205ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      size_t length,
206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      v8::RetainedObjectInfo* info);
207badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
208ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Associates handle with the object group represented by id.
209ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Should be only used in GC callback function before a collection.
210ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // All groups are destroyed after a garbage collection.
211ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void SetObjectGroupId(Object** handle, UniqueId id);
212ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
213ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Set RetainedObjectInfo for an object group. Should not be called more than
214ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // once for a group. Should not be called for a group which contains no
215ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // handles.
216ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
217ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
218ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Adds an implicit reference from a group to an object. Should be only used
219ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // in GC callback function before a collection. All implicit references are
220ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // destroyed after a mark-compact collection.
221ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void SetReferenceFromGroup(UniqueId id, Object** child);
222ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
223ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Adds an implicit reference from a parent object to a child object. Should
224ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // be only used in GC callback function before a collection. All implicit
225ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // references are destroyed after a mark-compact collection.
226ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void SetReference(HeapObject** parent, Object** child);
227ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
228ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  List<ObjectGroup*>* object_groups() {
229ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    ComputeObjectGroupsAndImplicitReferences();
230ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    return &object_groups_;
231ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
233ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  List<ImplicitRefGroup*>* implicit_ref_groups() {
234ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    ComputeObjectGroupsAndImplicitReferences();
235ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return &implicit_ref_groups_;
236ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
237badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Remove bags, this should only happen after GC.
239ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void RemoveObjectGroups();
240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void RemoveImplicitRefGroups();
24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Tear down the global handle structure.
243ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void TearDown();
244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
245ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate() { return isolate_; }
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
248ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void PrintStats();
249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void Print();
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
251e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
253ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit GlobalHandles(Isolate* isolate);
254ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
255ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Migrates data from the internal representation (object_group_connections_,
256ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // retainer_infos_ and implicit_ref_connections_) to the public and more
257ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // efficient representation (object_groups_ and implicit_ref_groups_).
258ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void ComputeObjectGroupsAndImplicitReferences();
259ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
260ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // v8::internal::List is inefficient even for small number of elements, if we
261ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // don't assign any initial capacity.
262ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  static const int kObjectGroupConnectionsCapacity = 20;
263ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
264e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // Internal node structures.
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  class Node;
266e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  class NodeBlock;
267e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  class NodeIterator;
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
269ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
271bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Field always containing the number of handles to global objects.
272bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  int number_of_global_handles_;
273bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
274c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  // List of all allocated node blocks.
275c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  NodeBlock* first_block_;
276c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
277c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  // List of node blocks with used nodes.
278c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  NodeBlock* first_used_block_;
27954d8a9855f2c6a6c3c33b5b66cbfbbac2cbcaa00danno@chromium.org
280c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  // Free list of nodes.
281c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  Node* first_free_;
282ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
283e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // Contains all nodes holding new space objects. Note: when the list
284e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // is accessed, some of the objects may have been promoted already.
285e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  List<Node*> new_space_nodes_;
286e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int post_gc_processing_count_;
288e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
289ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Object groups and implicit references, public and more efficient
290ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // representation.
291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  List<ObjectGroup*> object_groups_;
292ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  List<ImplicitRefGroup*> implicit_ref_groups_;
293ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
294ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Object groups and implicit references, temporary representation while
295ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // constructing the groups.
296ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  List<ObjectGroupConnection> object_group_connections_;
297ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  List<ObjectGroupRetainerInfo> retainer_infos_;
298ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  List<ObjectGroupConnection> implicit_ref_connections_;
299ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  friend class Isolate;
301ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
302ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
306594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgclass EternalHandles {
307594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org public:
308594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  enum SingletonHandle {
309594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    I18N_TEMPLATE_ONE,
310594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    I18N_TEMPLATE_TWO,
311486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    DATE_CACHE_VERSION,
312594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
313594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    NUMBER_OF_SINGLETON_HANDLES
314594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  };
315594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
316594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  EternalHandles();
317594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ~EternalHandles();
318594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
319594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int NumberOfHandles() { return size_; }
320594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
3211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Create an EternalHandle, overwriting the index.
3221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  void Create(Isolate* isolate, Object* object, int* index);
323594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
324594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Grab the handle for an existing EternalHandle.
325594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  inline Handle<Object> Get(int index) {
326594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Handle<Object>(GetLocation(index));
327594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
328594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
329594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Grab the handle for an existing SingletonHandle.
330594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  inline Handle<Object> GetSingleton(SingletonHandle singleton) {
331e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Exists(singleton));
332594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Get(singleton_handles_[singleton]);
333594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
334594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
335594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Checks whether a SingletonHandle has been assigned.
336594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  inline bool Exists(SingletonHandle singleton) {
337594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return singleton_handles_[singleton] != kInvalidIndex;
338594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
339594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
340594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Assign a SingletonHandle to an empty slot and returns the handle.
341594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<Object> CreateSingleton(Isolate* isolate,
342594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                 Object* object,
343594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                 SingletonHandle singleton) {
3441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Create(isolate, object, &singleton_handles_[singleton]);
345594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Get(singleton_handles_[singleton]);
346594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
347594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
348594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Iterates over all handles.
349594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void IterateAllRoots(ObjectVisitor* visitor);
350594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Iterates over all handles which might be in new space.
351594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void IterateNewSpaceRoots(ObjectVisitor* visitor);
352594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Rebuilds new space list.
353594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void PostGarbageCollectionProcessing(Heap* heap);
354594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
355594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org private:
356594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  static const int kInvalidIndex = -1;
357594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  static const int kShift = 8;
358594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  static const int kSize = 1 << kShift;
359594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  static const int kMask = 0xff;
360594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
361594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Gets the slot for an index
362594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  inline Object** GetLocation(int index) {
363e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index >= 0 && index < size_);
364594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return &blocks_[index >> kShift][index & kMask];
365594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
366594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
367594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int size_;
368594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  List<Object**> blocks_;
369594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  List<int> new_space_indices_;
370594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES];
371594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
372594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  DISALLOW_COPY_AND_ASSIGN(EternalHandles);
373594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org};
374594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
375594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // V8_GLOBAL_HANDLES_H_
379