Commit 289f3824 authored by hlopko's avatar hlopko Committed by Commit bot

Introduce EmbedderHeapTracer

BUG=468240
LOG=no

Review URL: https://codereview.chromium.org/1815153002

Cr-Commit-Position: refs/heads/master@{#35162}
parent 8cf73ae1
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <utility>
#include <vector>
#include "v8-version.h" // NOLINT(build/include) #include "v8-version.h" // NOLINT(build/include)
#include "v8config.h" // NOLINT(build/include) #include "v8config.h" // NOLINT(build/include)
...@@ -593,6 +595,13 @@ template <class T> class PersistentBase { ...@@ -593,6 +595,13 @@ template <class T> class PersistentBase {
// TODO(dcarney): remove this. // TODO(dcarney): remove this.
V8_INLINE void ClearWeak() { ClearWeak<void>(); } V8_INLINE void ClearWeak() { ClearWeak<void>(); }
/**
* Allows the embedder to tell the v8 garbage collector that a certain object
* is alive. Only allowed when the embedder is asked to trace its heap by
* EmbedderHeapTracer.
*/
V8_INLINE void RegisterExternalReference(Isolate* isolate);
/** /**
* Marks the reference to this object independent. Garbage collector is free * Marks the reference to this object independent. Garbage collector is free
* to ignore any object groups containing this object. Weak callback for an * to ignore any object groups containing this object. Weak callback for an
...@@ -5360,6 +5369,43 @@ class V8_EXPORT PersistentHandleVisitor { // NOLINT ...@@ -5360,6 +5369,43 @@ class V8_EXPORT PersistentHandleVisitor { // NOLINT
*/ */
enum class MemoryPressureLevel { kNone, kModerate, kCritical }; enum class MemoryPressureLevel { kNone, kModerate, kCritical };
/**
* Interface for tracing through the embedder heap. During the v8 garbage
* collection, v8 collects hidden fields of all potential wrappers, and at the
* end of its marking phase iterates the collection and asks the embedder to
* trace through its heap and call PersistentBase::RegisterExternalReference on
* each js object reachable from any of the given wrappers.
*
* Before the first call to the TraceWrappableFrom function v8 will call
* TraceRoots. When the v8 garbage collection is finished, v8 will call
* ClearTracingMarks.
*/
class EmbedderHeapTracer {
public:
/**
* V8 will call this method at the beginning of the gc cycle.
*/
virtual void TraceRoots(Isolate* isolate) = 0;
/**
* V8 will call this method with internal fields of a potential wrappers.
* Embedder is expected to trace its heap (synchronously) and call
* PersistentBase::RegisterExternalReference() on all wrappers reachable from
* any of the given wrappers.
*/
virtual void TraceWrappableFrom(
Isolate* isolate,
const std::vector<std::pair<void*, void*> >& internal_fields) = 0;
/**
* V8 will call this method at the end of the gc cycle. Allocation is *not*
* allowed in the ClearTracingMarks.
*/
virtual void ClearTracingMarks(Isolate* isolate) = 0;
protected:
virtual ~EmbedderHeapTracer() = default;
};
/** /**
* Isolate represents an isolated instance of the V8 engine. V8 isolates have * Isolate represents an isolated instance of the V8 engine. V8 isolates have
* completely separate states. Objects from one isolate must not be used in * completely separate states. Objects from one isolate must not be used in
...@@ -5828,6 +5874,11 @@ class V8_EXPORT Isolate { ...@@ -5828,6 +5874,11 @@ class V8_EXPORT Isolate {
*/ */
void RemoveGCPrologueCallback(GCCallback callback); void RemoveGCPrologueCallback(GCCallback callback);
/**
* Sets the embedder heap tracer for the isolate.
*/
void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
/** /**
* Enables the host application to receive a notification after a * Enables the host application to receive a notification after a
* garbage collection. Allocations are allowed in the callback function, * garbage collection. Allocations are allowed in the callback function,
...@@ -6585,6 +6636,8 @@ class V8_EXPORT V8 { ...@@ -6585,6 +6636,8 @@ class V8_EXPORT V8 {
static internal::Object** CopyPersistent(internal::Object** handle); static internal::Object** CopyPersistent(internal::Object** handle);
static void DisposeGlobal(internal::Object** global_handle); static void DisposeGlobal(internal::Object** global_handle);
typedef WeakCallbackData<Value, void>::Callback WeakCallback; typedef WeakCallbackData<Value, void>::Callback WeakCallback;
static void RegisterExternallyReferencedObject(internal::Object** object,
internal::Isolate* isolate);
static void MakeWeak(internal::Object** global_handle, void* data, static void MakeWeak(internal::Object** global_handle, void* data,
WeakCallback weak_callback); WeakCallback weak_callback);
static void MakeWeak(internal::Object** global_handle, void* data, static void MakeWeak(internal::Object** global_handle, void* data,
...@@ -7602,6 +7655,13 @@ P* PersistentBase<T>::ClearWeak() { ...@@ -7602,6 +7655,13 @@ P* PersistentBase<T>::ClearWeak() {
V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_))); V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)));
} }
template <class T>
void PersistentBase<T>::RegisterExternalReference(Isolate* isolate) {
if (IsEmpty()) return;
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(this->val_),
reinterpret_cast<internal::Isolate*>(isolate));
}
template <class T> template <class T>
void PersistentBase<T>::MarkIndependent() { void PersistentBase<T>::MarkIndependent() {
......
...@@ -677,6 +677,10 @@ i::Object** V8::CopyPersistent(i::Object** obj) { ...@@ -677,6 +677,10 @@ i::Object** V8::CopyPersistent(i::Object** obj) {
return result.location(); return result.location();
} }
void V8::RegisterExternallyReferencedObject(i::Object** object,
i::Isolate* isolate) {
isolate->heap()->RegisterExternallyReferencedObject(object);
}
void V8::MakeWeak(i::Object** object, void* parameter, void V8::MakeWeak(i::Object** object, void* parameter,
WeakCallback weak_callback) { WeakCallback weak_callback) {
...@@ -7174,6 +7178,10 @@ void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) { ...@@ -7174,6 +7178,10 @@ void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false); reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
} }
void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->SetEmbedderHeapTracer(tracer);
}
void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback, void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
ObjectSpace space, ObjectSpace space,
......
...@@ -644,7 +644,6 @@ bool GlobalHandles::IsWeak(Object** location) { ...@@ -644,7 +644,6 @@ bool GlobalHandles::IsWeak(Object** location) {
return Node::FromLocation(location)->IsWeak(); return Node::FromLocation(location)->IsWeak();
} }
void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
for (NodeIterator it(this); !it.done(); it.Advance()) { for (NodeIterator it(this); !it.done(); it.Advance()) {
Node* node = it.node(); Node* node = it.node();
......
...@@ -116,6 +116,7 @@ Heap::Heap() ...@@ -116,6 +116,7 @@ Heap::Heap()
inline_allocation_disabled_(false), inline_allocation_disabled_(false),
total_regexp_code_generated_(0), total_regexp_code_generated_(0),
tracer_(nullptr), tracer_(nullptr),
embedder_heap_tracer_(nullptr),
high_survival_rate_period_length_(0), high_survival_rate_period_length_(0),
promoted_objects_size_(0), promoted_objects_size_(0),
promotion_ratio_(0), promotion_ratio_(0),
...@@ -5418,6 +5419,13 @@ void Heap::NotifyDeserializationComplete() { ...@@ -5418,6 +5419,13 @@ void Heap::NotifyDeserializationComplete() {
#endif // DEBUG #endif // DEBUG
} }
void Heap::RegisterExternallyReferencedObject(Object** object) {
DCHECK(mark_compact_collector()->in_use());
HeapObject* heap_object = HeapObject::cast(*object);
DCHECK(Contains(heap_object));
MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
mark_compact_collector()->MarkObject(heap_object, mark_bit);
}
void Heap::TearDown() { void Heap::TearDown() {
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
...@@ -5583,6 +5591,11 @@ void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) { ...@@ -5583,6 +5591,11 @@ void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
UNREACHABLE(); UNREACHABLE();
} }
void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
DCHECK_NOT_NULL(tracer);
CHECK_NULL(embedder_heap_tracer_);
embedder_heap_tracer_ = tracer;
}
// TODO(ishell): Find a better place for this. // TODO(ishell): Find a better place for this.
void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj,
......
...@@ -914,12 +914,22 @@ class Heap { ...@@ -914,12 +914,22 @@ class Heap {
// Returns name of the space. // Returns name of the space.
const char* GetSpaceName(int idx); const char* GetSpaceName(int idx);
// ===========================================================================
// API. ======================================================================
// ===========================================================================
void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
void RegisterExternallyReferencedObject(Object** object);
// =========================================================================== // ===========================================================================
// Getters to other components. ============================================== // Getters to other components. ==============================================
// =========================================================================== // ===========================================================================
GCTracer* tracer() { return tracer_; } GCTracer* tracer() { return tracer_; }
EmbedderHeapTracer* embedder_heap_tracer() { return embedder_heap_tracer_; }
PromotionQueue* promotion_queue() { return &promotion_queue_; } PromotionQueue* promotion_queue() { return &promotion_queue_; }
inline Isolate* isolate(); inline Isolate* isolate();
...@@ -2096,6 +2106,7 @@ class Heap { ...@@ -2096,6 +2106,7 @@ class Heap {
int deferred_counters_[v8::Isolate::kUseCounterFeatureCount]; int deferred_counters_[v8::Isolate::kUseCounterFeatureCount];
GCTracer* tracer_; GCTracer* tracer_;
EmbedderHeapTracer* embedder_heap_tracer_;
int high_survival_rate_period_length_; int high_survival_rate_period_length_;
intptr_t promoted_objects_size_; intptr_t promoted_objects_size_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment