Commit 4acdb5ee authored by jbroman's avatar jbroman Committed by Commit bot

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}
parent 7bd0c1d5
...@@ -360,19 +360,18 @@ class MaybeLocal { ...@@ -360,19 +360,18 @@ class MaybeLocal {
// Eternal handles are set-once handles that live for the life of the isolate. // Eternal handles are set-once handles that live for the life of the isolate.
template <class T> class Eternal { template <class T> class Eternal {
public: public:
V8_INLINE Eternal() : index_(kInitialValue) { } V8_INLINE Eternal() : val_(nullptr) {}
template<class S> template <class S>
V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : index_(kInitialValue) { V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : val_(nullptr) {
Set(isolate, handle); Set(isolate, handle);
} }
// Can only be safely called if already set. // Can only be safely called if already set.
V8_INLINE Local<T> Get(Isolate* isolate) const; 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); template<class S> V8_INLINE void Set(Isolate* isolate, Local<S> handle);
private: private:
static const int kInitialValue = -1; T* val_;
int index_;
}; };
...@@ -7673,10 +7672,7 @@ class V8_EXPORT V8 { ...@@ -7673,10 +7672,7 @@ class V8_EXPORT V8 {
WeakCallbackInfo<void>::Callback weak_callback); WeakCallbackInfo<void>::Callback weak_callback);
static void MakeWeak(internal::Object*** location_addr); static void MakeWeak(internal::Object*** location_addr);
static void* ClearWeak(internal::Object** location); static void* ClearWeak(internal::Object** location);
static void Eternalize(Isolate* isolate, static Value* Eternalize(Isolate* isolate, Value* handle);
Value* handle,
int* index);
static Local<Value> GetEternal(Isolate* isolate, int index);
static void RegisterExternallyReferencedObject(internal::Object** object, static void RegisterExternallyReferencedObject(internal::Object** object,
internal::Isolate* isolate); internal::Isolate* isolate);
...@@ -8641,12 +8637,15 @@ template<class T> ...@@ -8641,12 +8637,15 @@ template<class T>
template<class S> template<class S>
void Eternal<T>::Set(Isolate* isolate, Local<S> handle) { void Eternal<T>::Set(Isolate* isolate, Local<S> handle) {
TYPE_CHECK(T, S); 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> template <class T>
Local<T> Eternal<T>::Get(Isolate* isolate) const { 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_);
} }
......
...@@ -948,17 +948,13 @@ void V8::DisposeGlobal(i::Object** location) { ...@@ -948,17 +948,13 @@ void V8::DisposeGlobal(i::Object** location) {
i::GlobalHandles::Destroy(location); i::GlobalHandles::Destroy(location);
} }
Value* V8::Eternalize(Isolate* v8_isolate, Value* value) {
void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::Object* object = *Utils::OpenHandle(value); i::Object* object = *Utils::OpenHandle(value);
isolate->eternal_handles()->Create(isolate, object, index); int index = -1;
} isolate->eternal_handles()->Create(isolate, object, &index);
return reinterpret_cast<Value*>(
isolate->eternal_handles()->Get(index).location());
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));
} }
......
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