Commit 44ec65b1 authored by dcarney@chromium.org's avatar dcarney@chromium.org

Add Persistent<T>::Reset which disposes the handle and redirects it to point to another object.

BUG=
R=dcarney@chromium.org, svenpanne@chromium.org

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

Patch from Marja Hölttä <marja@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14570 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 97c83b29
......@@ -690,6 +690,11 @@ template <class T> class Persistent // NOLINT
// TODO(dcarney): remove before cutover
V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const);
/**
* Disposes the current contents of the handle and replaces it.
*/
V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other));
#ifndef V8_USE_UNSAFE_HANDLES
#ifndef V8_ALLOW_ACCESS_TO_PERSISTENT_IMPLICIT
......@@ -5379,6 +5384,22 @@ void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
SetWrapperClassId(Isolate::GetCurrent(), class_id);
}
template <class T>
void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) {
Dispose(isolate);
#ifdef V8_USE_UNSAFE_HANDLES
*this = *New(isolate, other);
#else
if (other.IsEmpty()) {
this->val_ = NULL;
return;
}
internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
this->val_ = reinterpret_cast<T*>(
V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p));
#endif
}
template <class T>
void Persistent<T>::SetWrapperClassId(Isolate* isolate, uint16_t class_id) {
typedef internal::Internals I;
......
......@@ -2487,6 +2487,58 @@ THREADED_TEST(GlobalHandle) {
}
THREADED_TEST(ResettingGlobalHandle) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::internal::GlobalHandles* global_handles = NULL;
int initial_handle_count = 0;
v8::Persistent<String> global;
{
v8::HandleScope scope(isolate);
Local<String> str = v8_str("str");
global_handles =
reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
initial_handle_count = global_handles->NumberOfGlobalHandles();
global = v8::Persistent<String>::New(isolate, str);
}
CHECK_EQ(global->Length(), 3);
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
{
v8::HandleScope scope(isolate);
Local<String> str = v8_str("longer");
global.Reset(isolate, str);
}
CHECK_EQ(global->Length(), 6);
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
global.Dispose(isolate);
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count);
}
THREADED_TEST(ResettingGlobalHandleToEmpty) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::internal::GlobalHandles* global_handles = NULL;
int initial_handle_count = 0;
v8::Persistent<String> global;
{
v8::HandleScope scope(isolate);
Local<String> str = v8_str("str");
global_handles =
reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
initial_handle_count = global_handles->NumberOfGlobalHandles();
global = v8::Persistent<String>::New(isolate, str);
}
CHECK_EQ(global->Length(), 3);
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
{
v8::HandleScope scope(isolate);
Local<String> empty;
global.Reset(isolate, empty);
}
CHECK(global.IsEmpty());
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count);
}
THREADED_TEST(LocalHandle) {
v8::HandleScope scope(v8::Isolate::GetCurrent());
v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
......
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