Commit cd74a098 authored by dcarney@chromium.org's avatar dcarney@chromium.org

expose eternal handle api

R=svenpanne@chromium.org
BUG=

Review URL: https://codereview.chromium.org/22384003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a9efd655
......@@ -388,6 +388,11 @@ template <class T> class Handle {
};
// A value which will never be returned by Local::Eternalize
// Useful for static initialization
const int kUninitializedEternalIndex = -1;
/**
* A light-weight stack-allocated object handle. All operations
* that return objects from within v8 return them in local handles. They
......@@ -433,6 +438,11 @@ template <class T> class Local : public Handle<T> {
return Local<S>::Cast(*this);
}
// Keep this Local alive for the lifetime of the Isolate.
// It remains retrievable via the returned index,
V8_INLINE(int Eternalize(Isolate* isolate));
V8_INLINE(static Local<T> GetEternal(Isolate* isolate, int index));
/**
* Create a local handle for the content of another handle.
* The referee is kept alive by the local handle even when
......@@ -4787,6 +4797,9 @@ class V8_EXPORT V8 {
void* data,
RevivableCallback weak_reference_callback);
static void ClearWeak(internal::Object** global_handle);
static int Eternalize(internal::Isolate* isolate,
internal::Object** handle);
static internal::Object** GetEternal(internal::Isolate* isolate, int index);
template <class T> friend class Handle;
template <class T> friend class Local;
......@@ -5650,6 +5663,21 @@ Local<T> Local<T>::New(Isolate* isolate, T* that) {
}
template<class T>
int Local<T>::Eternalize(Isolate* isolate) {
return V8::Eternalize(reinterpret_cast<internal::Isolate*>(isolate),
reinterpret_cast<internal::Object**>(this->val_));
}
template<class T>
Local<T> Local<T>::GetEternal(Isolate* isolate, int index) {
internal::Object** handle =
V8::GetEternal(reinterpret_cast<internal::Isolate*>(isolate), index);
return Local<T>(T::Cast(reinterpret_cast<Value*>(handle)));
}
#ifdef V8_USE_UNSAFE_HANDLES
template <class T>
Persistent<T> Persistent<T>::New(Handle<T> that) {
......
......@@ -676,6 +676,16 @@ void V8::DisposeGlobal(i::Object** obj) {
}
int V8::Eternalize(i::Isolate* isolate, i::Object** handle) {
return isolate->eternal_handles()->Create(isolate, *handle);
}
i::Object** V8::GetEternal(i::Isolate* isolate, int index) {
return isolate->eternal_handles()->Get(index).location();
}
// --- H a n d l e s ---
......
......@@ -1251,6 +1251,7 @@ void GlobalHandles::ComputeObjectGroupsAndImplicitReferences() {
EternalHandles::EternalHandles() : size_(0) {
STATIC_ASSERT(v8::kUninitializedEternalIndex == kInvalidIndex);
for (unsigned i = 0; i < ARRAY_SIZE(singleton_handles_); i++) {
singleton_handles_[i] = kInvalidIndex;
}
......
......@@ -484,21 +484,36 @@ TEST(EternalHandles) {
CHECK_EQ(0, eternals->NumberOfHandles());
for (int i = 0; i < kArrayLength; i++) {
HandleScope scope(isolate);
v8::Handle<v8::Object> object = v8::Object::New();
v8::Local<v8::Object> object = v8::Object::New();
object->Set(i, v8::Integer::New(i, v8_isolate));
indices[i] = eternals->Create(isolate, *v8::Utils::OpenHandle(*object));
if (i % 2 == 0) {
// Create with internal api
indices[i] = eternals->Create(isolate, *v8::Utils::OpenHandle(*object));
} else {
// Create with external api
indices[i] = object.Eternalize(v8_isolate);
}
}
isolate->heap()->CollectAllAvailableGarbage();
for (int i = 0; i < kArrayLength; i++) {
HandleScope scope(isolate);
v8::Handle<v8::Value> local =
v8::Utils::ToLocal(eternals->Get(indices[i]));
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(local);
v8::Handle<v8::Value> value = object->Get(i);
CHECK(value->IsInt32());
CHECK_EQ(i, value->Int32Value());
for (int j = 0; j < 2; j++) {
HandleScope scope(isolate);
v8::Local<v8::Object> object;
if (j == 0) {
// Test internal api
v8::Local<v8::Value> local =
v8::Utils::ToLocal(eternals->Get(indices[i]));
object = v8::Handle<v8::Object>::Cast(local);
} else {
// Test external api
object = v8::Local<v8::Object>::GetEternal(v8_isolate, indices[i]);
}
v8::Local<v8::Value> value = object->Get(i);
CHECK(value->IsInt32());
CHECK_EQ(i, value->Int32Value());
}
}
CHECK_EQ(kArrayLength, eternals->NumberOfHandles());
......
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