summaryrefslogtreecommitdiff
path: root/deps/v8/src/global-handles.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/global-handles.h')
-rw-r--r--deps/v8/src/global-handles.h197
1 files changed, 74 insertions, 123 deletions
diff --git a/deps/v8/src/global-handles.h b/deps/v8/src/global-handles.h
index d5e5628c3d..d12e0c10fd 100644
--- a/deps/v8/src/global-handles.h
+++ b/deps/v8/src/global-handles.h
@@ -12,6 +12,7 @@
#include "include/v8-profiler.h"
#include "src/handles.h"
+#include "src/objects.h"
#include "src/utils.h"
namespace v8 {
@@ -20,12 +21,6 @@ namespace internal {
class HeapStats;
class RootVisitor;
-// Structure for tracking global handles.
-// A single list keeps all the allocated global handles.
-// Destroyed handles stay in the list but is added to the free list.
-// At GC the destroyed global handles are removed from the free list
-// and deallocated.
-
enum WeaknessType {
// Embedder gets a handle to the dying object.
FINALIZER_WEAK,
@@ -41,26 +36,15 @@ enum WeaknessType {
PHANTOM_WEAK_RESET_HANDLE
};
-class GlobalHandles {
+// Global handles hold handles that are independent of stack-state and can have
+// callbacks and finalizers attached to them.
+class GlobalHandles final {
public:
- ~GlobalHandles();
-
- // Creates a new global handle that is alive until Destroy is called.
- Handle<Object> Create(Object* value);
-
- template <typename T>
- Handle<T> Create(T* value) {
- static_assert(std::is_base_of<Object, T>::value, "static type violation");
- // The compiler should only pick this method if T is not Object.
- static_assert(!std::is_same<Object, T>::value, "compiler error");
- return Handle<T>::cast(Create(static_cast<Object*>(value)));
- }
-
// Copy a global handle
- static Handle<Object> CopyGlobal(Object** location);
+ static Handle<Object> CopyGlobal(Address* location);
// Destroy a global handle.
- static void Destroy(Object** location);
+ static void Destroy(Address* location);
// Make the global handle weak and set the callback parameter for the
// handle. When the garbage collector recognizes that only weak global
@@ -71,53 +55,53 @@ class GlobalHandles {
// GC. For a phantom weak handle the handle is cleared (set to a Smi)
// before the callback is invoked, but the handle can still be identified
// in the callback by using the location() of the handle.
- static void MakeWeak(Object** location, void* parameter,
+ static void MakeWeak(Address* location, void* parameter,
WeakCallbackInfo<void>::Callback weak_callback,
v8::WeakCallbackType type);
- static void MakeWeak(Object*** location_addr);
+ static void MakeWeak(Address** location_addr);
- static void AnnotateStrongRetainer(Object** location, const char* label);
+ static void AnnotateStrongRetainer(Address* location, const char* label);
- void RecordStats(HeapStats* stats);
+ // Clear the weakness of a global handle.
+ static void* ClearWeakness(Address* location);
- // Returns the current number of handles to global objects.
- int global_handles_count() const {
- return number_of_global_handles_;
- }
+ // Tells whether global handle is near death.
+ static bool IsNearDeath(Address* location);
- size_t NumberOfPhantomHandleResets() {
- return number_of_phantom_handle_resets_;
- }
+ // Tells whether global handle is weak.
+ static bool IsWeak(Address* location);
- void ResetNumberOfPhantomHandleResets() {
- number_of_phantom_handle_resets_ = 0;
- }
+ explicit GlobalHandles(Isolate* isolate);
+ ~GlobalHandles();
- size_t NumberOfNewSpaceNodes() { return new_space_nodes_.size(); }
+ // Creates a new global handle that is alive until Destroy is called.
+ Handle<Object> Create(Object value);
+ Handle<Object> Create(Address value);
- // Clear the weakness of a global handle.
- static void* ClearWeakness(Object** location);
+ template <typename T>
+ Handle<T> Create(T value) {
+ static_assert(std::is_base_of<Object, T>::value, "static type violation");
+ // The compiler should only pick this method if T is not Object.
+ static_assert(!std::is_same<Object, T>::value, "compiler error");
+ return Handle<T>::cast(Create(Object(value)));
+ }
- // Tells whether global handle is near death.
- static bool IsNearDeath(Object** location);
+ void RecordStats(HeapStats* stats);
- // Tells whether global handle is weak.
- static bool IsWeak(Object** location);
+ size_t InvokeFirstPassWeakCallbacks();
+ void InvokeSecondPassPhantomCallbacks();
// Process pending weak handles.
// Returns the number of freed nodes.
- int PostGarbageCollectionProcessing(
+ size_t PostGarbageCollectionProcessing(
GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
void IterateStrongRoots(RootVisitor* v);
-
void IterateWeakRoots(RootVisitor* v);
-
void IterateAllRoots(RootVisitor* v);
void IterateAllNewSpaceRoots(RootVisitor* v);
- void IterateNewSpaceRoots(RootVisitor* v, size_t start, size_t end);
// Iterates over all handles that have embedder-assigned class ID.
void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v);
@@ -139,19 +123,14 @@ class GlobalHandles {
// |should_reset_handle| as pending.
void IdentifyWeakHandles(WeakSlotCallbackWithHeap should_reset_handle);
- // NOTE: Five ...NewSpace... functions below are used during
- // scavenge collections and iterate over sets of handles that are
- // guaranteed to contain all handles holding new space objects (but
- // may also include old space objects).
+ // Note: The following *NewSpace* methods are used for the Scavenger to
+ // identify and process handles in new space. The set of new space handles is
+ // complete but the methods may encounter handles that are already in old
+ // space.
// Iterates over strong and dependent handles. See the note above.
void IterateNewSpaceStrongAndDependentRoots(RootVisitor* v);
- // Iterates over strong and dependent handles. See the note above.
- // Also marks unmodified nodes in the same iteration.
- void IterateNewSpaceStrongAndDependentRootsAndIdentifyUnmodified(
- RootVisitor* v, size_t start, size_t end);
-
// Marks weak unmodified handles satisfying |is_dead| as pending.
void MarkNewSpaceWeakUnmodifiedObjectsPending(
WeakSlotCallbackWithHeap is_dead);
@@ -166,68 +145,67 @@ class GlobalHandles {
// unmodified
void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
- // Tear down the global handle structure.
- void TearDown();
+ Isolate* isolate() const { return isolate_; }
- Isolate* isolate() { return isolate_; }
+ // Number of global handles.
+ size_t handles_count() const { return handles_count_; }
+
+ size_t GetAndResetGlobalHandleResetCount() {
+ size_t old = number_of_phantom_handle_resets_;
+ number_of_phantom_handle_resets_ = 0;
+ return old;
+ }
#ifdef DEBUG
void PrintStats();
void Print();
#endif // DEBUG
- void InvokeSecondPassPhantomCallbacks();
-
private:
// Internal node structures.
class Node;
+ template <class NodeType>
class NodeBlock;
+ template <class BlockType>
class NodeIterator;
+ template <class NodeType>
+ class NodeSpace;
class PendingPhantomCallback;
- explicit GlobalHandles(Isolate* isolate);
+ bool InRecursiveGC(unsigned gc_processing_counter);
void InvokeSecondPassPhantomCallbacksFromTask();
- int PostScavengeProcessing(int initial_post_gc_processing_count);
- int PostMarkSweepProcessing(int initial_post_gc_processing_count);
- int DispatchPendingPhantomCallbacks(bool synchronous_second_pass);
+ void InvokeOrScheduleSecondPassPhantomCallbacks(bool synchronous_second_pass);
+ size_t PostScavengeProcessing(unsigned post_processing_count);
+ size_t PostMarkSweepProcessing(unsigned post_processing_count);
+
void UpdateListOfNewSpaceNodes();
+
void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor,
Node* node);
- Isolate* isolate_;
-
- // Field always containing the number of handles to global objects.
- int number_of_global_handles_;
-
- // List of all allocated node blocks.
- NodeBlock* first_block_;
-
- // List of node blocks with used nodes.
- NodeBlock* first_used_block_;
-
- // Free list of nodes.
- Node* first_free_;
+ Isolate* const isolate_;
+ std::unique_ptr<NodeSpace<Node>> regular_nodes_;
// Contains all nodes holding new space objects. Note: when the list
// is accessed, some of the objects may have been promoted already.
std::vector<Node*> new_space_nodes_;
- int post_gc_processing_count_;
-
- size_t number_of_phantom_handle_resets_;
+ // Field always containing the number of handles to global objects.
+ size_t handles_count_ = 0;
+ size_t number_of_phantom_handle_resets_ = 0;
std::vector<PendingPhantomCallback> pending_phantom_callbacks_;
std::vector<PendingPhantomCallback> second_pass_callbacks_;
bool second_pass_callbacks_task_posted_ = false;
- friend class Isolate;
+ // Counter for recursive garbage collections during callback processing.
+ unsigned post_gc_processing_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
};
-
-class GlobalHandles::PendingPhantomCallback {
+class GlobalHandles::PendingPhantomCallback final {
public:
typedef v8::WeakCallbackInfo<void> Data;
PendingPhantomCallback(
@@ -241,8 +219,8 @@ class GlobalHandles::PendingPhantomCallback {
void Invoke(Isolate* isolate);
- Node* node() { return node_; }
- Data::Callback callback() { return callback_; }
+ Node* node() const { return node_; }
+ Data::Callback callback() const { return callback_; }
private:
Node* node_;
@@ -251,47 +229,19 @@ class GlobalHandles::PendingPhantomCallback {
void* embedder_fields_[v8::kEmbedderFieldsInWeakCallback];
};
-
-class EternalHandles {
+class EternalHandles final {
public:
- enum SingletonHandle {
- DATE_CACHE_VERSION,
-
- NUMBER_OF_SINGLETON_HANDLES
- };
-
- EternalHandles();
+ EternalHandles() = default;
~EternalHandles();
- int NumberOfHandles() { return size_; }
-
// Create an EternalHandle, overwriting the index.
- void Create(Isolate* isolate, Object* object, int* index);
+ void Create(Isolate* isolate, Object object, int* index);
// Grab the handle for an existing EternalHandle.
inline Handle<Object> Get(int index) {
return Handle<Object>(GetLocation(index));
}
- // Grab the handle for an existing SingletonHandle.
- inline Handle<Object> GetSingleton(SingletonHandle singleton) {
- DCHECK(Exists(singleton));
- return Get(singleton_handles_[singleton]);
- }
-
- // Checks whether a SingletonHandle has been assigned.
- inline bool Exists(SingletonHandle singleton) {
- return singleton_handles_[singleton] != kInvalidIndex;
- }
-
- // Assign a SingletonHandle to an empty slot and returns the handle.
- Handle<Object> CreateSingleton(Isolate* isolate,
- Object* object,
- SingletonHandle singleton) {
- Create(isolate, object, &singleton_handles_[singleton]);
- return Get(singleton_handles_[singleton]);
- }
-
// Iterates over all handles.
void IterateAllRoots(RootVisitor* visitor);
// Iterates over all handles which might be in new space.
@@ -299,27 +249,28 @@ class EternalHandles {
// Rebuilds new space list.
void PostGarbageCollectionProcessing();
+ size_t handles_count() const { return size_; }
+
private:
static const int kInvalidIndex = -1;
static const int kShift = 8;
static const int kSize = 1 << kShift;
static const int kMask = 0xff;
- // Gets the slot for an index
- inline Object** GetLocation(int index) {
+ // Gets the slot for an index. This returns an Address* rather than an
+ // ObjectSlot in order to avoid #including slots.h in this header file.
+ inline Address* GetLocation(int index) {
DCHECK(index >= 0 && index < size_);
return &blocks_[index >> kShift][index & kMask];
}
- int size_;
- std::vector<Object**> blocks_;
+ int size_ = 0;
+ std::vector<Address*> blocks_;
std::vector<int> new_space_indices_;
- int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES];
DISALLOW_COPY_AND_ASSIGN(EternalHandles);
};
-
} // namespace internal
} // namespace v8