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.

Review-Url: https://codereview.chromium.org/2751263003
Cr-Commit-Position: refs/heads/master@{#43912}
This commit is contained in:
jbroman 2017-03-17 10:23:34 -07:00 committed by Commit bot
parent 7bd0c1d5bb
commit 4acdb5eec2
2 changed files with 16 additions and 21 deletions

View File

@ -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 {
public:
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);
private:
static const int kInitialValue = -1;
int index_;
T* val_;
};
@ -7673,10 +7672,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);
@ -8641,12 +8637,15 @@ template<class T>
template<class S>
void Eternal<T>::Set(Isolate* isolate, Local<S> handle) {
TYPE_CHECK(T, S);
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_);
}

View File

@ -948,17 +948,13 @@ void V8::DisposeGlobal(i::Object** location) {
i::GlobalHandles::Destroy(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*>(
isolate->eternal_handles()->Get(index).location());
}