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 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <utility>
#include <vector>
#include "v8-version.h" // NOLINT(build/include)
#include "v8config.h" // NOLINT(build/include)
......@@ -593,6 +595,13 @@ template <class T> class PersistentBase {
// TODO(dcarney): remove this.
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
* to ignore any object groups containing this object. Weak callback for an
......@@ -5360,6 +5369,43 @@ class V8_EXPORT PersistentHandleVisitor { // NOLINT
*/
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
* completely separate states. Objects from one isolate must not be used in
......@@ -5828,6 +5874,11 @@ class V8_EXPORT Isolate {
*/
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
* garbage collection. Allocations are allowed in the callback function,
......@@ -6585,6 +6636,8 @@ class V8_EXPORT V8 {
static internal::Object** CopyPersistent(internal::Object** handle);
static void DisposeGlobal(internal::Object** global_handle);
typedef WeakCallbackData<Value, void>::Callback WeakCallback;
static void RegisterExternallyReferencedObject(internal::Object** object,
internal::Isolate* isolate);
static void MakeWeak(internal::Object** global_handle, void* data,
WeakCallback weak_callback);
static void MakeWeak(internal::Object** global_handle, void* data,
......@@ -7602,6 +7655,13 @@ P* PersistentBase<T>::ClearWeak() {
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>
void PersistentBase<T>::MarkIndependent() {
......
......@@ -677,6 +677,10 @@ i::Object** V8::CopyPersistent(i::Object** obj) {
return result.location();
}
void V8::RegisterExternallyReferencedObject(i::Object** object,
i::Isolate* isolate) {
isolate->heap()->RegisterExternallyReferencedObject(object);
}
void V8::MakeWeak(i::Object** object, void* parameter,
WeakCallback weak_callback) {
......@@ -7174,6 +7178,10 @@ void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
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,
ObjectSpace space,
......
......@@ -644,7 +644,6 @@ bool GlobalHandles::IsWeak(Object** location) {
return Node::FromLocation(location)->IsWeak();
}
void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
for (NodeIterator it(this); !it.done(); it.Advance()) {
Node* node = it.node();
......
......@@ -116,6 +116,7 @@ Heap::Heap()
inline_allocation_disabled_(false),
total_regexp_code_generated_(0),
tracer_(nullptr),
embedder_heap_tracer_(nullptr),
high_survival_rate_period_length_(0),
promoted_objects_size_(0),
promotion_ratio_(0),
......@@ -5418,6 +5419,13 @@ void Heap::NotifyDeserializationComplete() {
#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() {
#ifdef VERIFY_HEAP
......@@ -5583,6 +5591,11 @@ void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
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.
void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj,
......
......@@ -914,12 +914,22 @@ class Heap {
// Returns name of the space.
const char* GetSpaceName(int idx);
// ===========================================================================
// API. ======================================================================
// ===========================================================================
void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
void RegisterExternallyReferencedObject(Object** object);
// ===========================================================================
// Getters to other components. ==============================================
// ===========================================================================
GCTracer* tracer() { return tracer_; }
EmbedderHeapTracer* embedder_heap_tracer() { return embedder_heap_tracer_; }
PromotionQueue* promotion_queue() { return &promotion_queue_; }
inline Isolate* isolate();
......@@ -2096,6 +2106,7 @@ class Heap {
int deferred_counters_[v8::Isolate::kUseCounterFeatureCount];
GCTracer* tracer_;
EmbedderHeapTracer* embedder_heap_tracer_;
int high_survival_rate_period_length_;
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