Browse files

deps: backport 4acdb5eec2c from upstream v8

Original commit message:

    Give v8::Eternal a direct reference to the handle.

    This makes it more similar to other handle types (like PersistentBase),
    by simply storing an i::Object** cast to T*. This means that it is not
    necessary to look up the handle in the eternal handles table to access
    the underlying value.

    Like the built-in roots (null, etc.), an eternal handle can never be
    destroyed, so we don't even need to allocate a separate local handle.
    Instead, the Local<T> can point directly at the eternal reference.
    This makes Eternal<T>::Get trivial.

    Cr-Commit-Position: refs/heads/master@{#43912}

Ref: v8/v8@4acdb5e

PR-URL: #12875
Reviewed-By: James M Snell <>
  • Loading branch information...
jeremyroman authored and jasnell committed Mar 17, 2017
1 parent 69161b5 commit 385499ccf8d55ca2a91342703ca543f64474a7bb
Showing with 16 additions and 21 deletions.
  1. +11 −12 deps/v8/include/v8.h
  2. +5 −9 deps/v8/src/
@@ -360,19 +360,18 @@ class MaybeLocal {
// Eternal handles are set-once handles that live for the life of the isolate.
template <class T> class Eternal {
V8_INLINE Eternal() : index_(kInitialValue) { }
template<class S>
V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : index_(kInitialValue) {
V8_INLINE Eternal() : val_(nullptr) {}
template <class S>
V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : val_(nullptr) {
Set(isolate, handle);
// Can only be safely called if already set.
V8_INLINE Local<T> Get(Isolate* isolate) const;
V8_INLINE bool IsEmpty() const { return index_ == kInitialValue; }
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
template<class S> V8_INLINE void Set(Isolate* isolate, Local<S> handle);
static const int kInitialValue = -1;
int index_;
T* val_;
@@ -7628,10 +7627,7 @@ class V8_EXPORT V8 {
WeakCallbackInfo<void>::Callback weak_callback);
static void MakeWeak(internal::Object*** location_addr);
static void* ClearWeak(internal::Object** location);
static void Eternalize(Isolate* isolate,
Value* handle,
int* index);
static Local<Value> GetEternal(Isolate* isolate, int index);
static Value* Eternalize(Isolate* isolate, Value* handle);
static void RegisterExternallyReferencedObject(internal::Object** object,
internal::Isolate* isolate);
@@ -8601,12 +8597,15 @@ template<class T>
template<class S>
void Eternal<T>::Set(Isolate* isolate, Local<S> handle) {
V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle), &this->index_);
val_ = reinterpret_cast<T*>(
V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle)));
template <class T>
Local<T> Eternal<T>::Get(Isolate* isolate) const {
return Local<T>(reinterpret_cast<T*>(*V8::GetEternal(isolate, index_)));
// The eternal handle will never go away, so as with the roots, we don't even
// need to open a handle.
return Local<T>(val_);
@@ -936,17 +936,13 @@ void V8::DisposeGlobal(i::Object** location) {
void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
Value* V8::Eternalize(Isolate* v8_isolate, Value* value) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::Object* object = *Utils::OpenHandle(value);
isolate->eternal_handles()->Create(isolate, object, index);
Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
return Utils::ToLocal(isolate->eternal_handles()->Get(index));
int index = -1;
isolate->eternal_handles()->Create(isolate, object, &index);
return reinterpret_cast<Value*>(

0 comments on commit 385499c

Please sign in to comment.