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:
parent
7bd0c1d5bb
commit
4acdb5eec2
23
include/v8.h
23
include/v8.h
@ -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_);
|
||||
}
|
||||
|
||||
|
||||
|
14
src/api.cc
14
src/api.cc
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user