Commit 42a8ff87 authored by dcarney@chromium.org's avatar dcarney@chromium.org

add weakcallback without persistent copying

R=svenpanne@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14566 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 46d39cab
...@@ -191,8 +191,13 @@ class UniqueId { ...@@ -191,8 +191,13 @@ class UniqueId {
* \param object the weak global object to be reclaimed by the garbage collector * \param object the weak global object to be reclaimed by the garbage collector
* \param parameter the value passed in when making the weak global object * \param parameter the value passed in when making the weak global object
*/ */
typedef void (*WeakReferenceCallback)(Persistent<Value> object, template<typename T, typename P>
void* parameter); class WeakReferenceCallbacks {
public:
typedef void (*Revivable)(Isolate* isolate,
Persistent<T>* object,
P* parameter);
};
// TODO(svenpanne) Temporary definition until Chrome is in sync. // TODO(svenpanne) Temporary definition until Chrome is in sync.
typedef void (*NearDeathCallback)(Isolate* isolate, typedef void (*NearDeathCallback)(Isolate* isolate,
...@@ -598,8 +603,17 @@ template <class T> class Persistent // NOLINT ...@@ -598,8 +603,17 @@ template <class T> class Persistent // NOLINT
// TODO(dcarney): remove before cutover // TODO(dcarney): remove before cutover
V8_INLINE(void Dispose(Isolate* isolate)); V8_INLINE(void Dispose(Isolate* isolate));
V8_INLINE(void MakeWeak(void* parameters, template<typename S, typename P>
WeakReferenceCallback callback)); V8_INLINE(void MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<S, P>::Revivable callback));
template<typename P>
V8_INLINE(void MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<T, P>::Revivable callback));
/** /**
* Make the reference to this object weak. When only weak handles * Make the reference to this object weak. When only weak handles
...@@ -4363,10 +4377,11 @@ class V8EXPORT V8 { ...@@ -4363,10 +4377,11 @@ class V8EXPORT V8 {
internal::Object** handle); internal::Object** handle);
static void DisposeGlobal(internal::Isolate* isolate, static void DisposeGlobal(internal::Isolate* isolate,
internal::Object** global_handle); internal::Object** global_handle);
typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback;
static void MakeWeak(internal::Isolate* isolate, static void MakeWeak(internal::Isolate* isolate,
internal::Object** global_handle, internal::Object** global_handle,
void* data, void* data,
WeakReferenceCallback weak_reference_callback, RevivableCallback weak_reference_callback,
NearDeathCallback near_death_callback); NearDeathCallback near_death_callback);
static void ClearWeak(internal::Isolate* isolate, static void ClearWeak(internal::Isolate* isolate,
internal::Object** global_handle); internal::Object** global_handle);
...@@ -5282,15 +5297,31 @@ void Persistent<T>::Dispose(Isolate* isolate) { ...@@ -5282,15 +5297,31 @@ void Persistent<T>::Dispose(Isolate* isolate) {
template <class T> template <class T>
void Persistent<T>::MakeWeak(void* parameters, WeakReferenceCallback callback) { template <typename S, typename P>
Isolate* isolate = Isolate::GetCurrent(); void Persistent<T>::MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<S, P>::Revivable callback) {
TYPE_CHECK(S, T);
typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable;
V8::MakeWeak(reinterpret_cast<internal::Isolate*>(isolate), V8::MakeWeak(reinterpret_cast<internal::Isolate*>(isolate),
reinterpret_cast<internal::Object**>(this->val_), reinterpret_cast<internal::Object**>(this->val_),
parameters, parameters,
callback, reinterpret_cast<Revivable>(callback),
NULL); NULL);
} }
template <class T>
template <typename P>
void Persistent<T>::MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<T, P>::Revivable callback) {
MakeWeak<T, P>(isolate, parameters, callback);
}
template <class T> template <class T>
void Persistent<T>::MakeWeak(Isolate* isolate, void Persistent<T>::MakeWeak(Isolate* isolate,
void* parameters, void* parameters,
......
...@@ -628,7 +628,7 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) { ...@@ -628,7 +628,7 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
void V8::MakeWeak(i::Isolate* isolate, void V8::MakeWeak(i::Isolate* isolate,
i::Object** object, i::Object** object,
void* parameters, void* parameters,
WeakReferenceCallback weak_reference_callback, RevivableCallback weak_reference_callback,
NearDeathCallback near_death_callback) { NearDeathCallback near_death_callback) {
ASSERT(isolate == i::Isolate::Current()); ASSERT(isolate == i::Isolate::Current());
LOG_API(isolate, "MakeWeak"); LOG_API(isolate, "MakeWeak");
......
...@@ -1062,14 +1062,14 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { ...@@ -1062,14 +1062,14 @@ Handle<Value> Shell::ArraySet(const Arguments& args) {
void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate, void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate,
Persistent<Value> object, Persistent<Object>* object,
void* data) { uint8_t* data) {
HandleScope scope(isolate); HandleScope scope(isolate);
int32_t length = object->ToObject()->Get( int32_t length = (*object)->Get(
PerIsolateData::byteLength_string(isolate))->Uint32Value(); PerIsolateData::byteLength_string(isolate))->Uint32Value();
isolate->AdjustAmountOfExternalAllocatedMemory(-length); isolate->AdjustAmountOfExternalAllocatedMemory(-length);
delete[] static_cast<uint8_t*>(data); delete[] data;
object.Dispose(isolate); object->Dispose(isolate);
} }
......
...@@ -416,8 +416,8 @@ class Shell : public i::AllStatic { ...@@ -416,8 +416,8 @@ class Shell : public i::AllStatic {
ExternalArrayType type, ExternalArrayType type,
int32_t element_size); int32_t element_size);
static void ExternalArrayWeakCallback(Isolate* isolate, static void ExternalArrayWeakCallback(Isolate* isolate,
Persistent<Value> object, Persistent<Object>* object,
void* data); uint8_t* data);
}; };
......
...@@ -235,7 +235,7 @@ class GlobalHandles::Node { ...@@ -235,7 +235,7 @@ class GlobalHandles::Node {
void MakeWeak(GlobalHandles* global_handles, void MakeWeak(GlobalHandles* global_handles,
void* parameter, void* parameter,
WeakReferenceCallback weak_reference_callback, RevivableCallback weak_reference_callback,
NearDeathCallback near_death_callback) { NearDeathCallback near_death_callback) {
ASSERT(state() != FREE); ASSERT(state() != FREE);
set_state(WEAK); set_state(WEAK);
...@@ -267,7 +267,7 @@ class GlobalHandles::Node { ...@@ -267,7 +267,7 @@ class GlobalHandles::Node {
set_state(NEAR_DEATH); set_state(NEAR_DEATH);
set_parameter(NULL); set_parameter(NULL);
v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle()); v8::Persistent<v8::Value> object = ToApi<v8::Value>(handle());
{ {
// Check that we are not passing a finalized external string to // Check that we are not passing a finalized external string to
// the callback. // the callback.
...@@ -279,9 +279,11 @@ class GlobalHandles::Node { ...@@ -279,9 +279,11 @@ class GlobalHandles::Node {
VMState<EXTERNAL> state(isolate); VMState<EXTERNAL> state(isolate);
if (near_death_callback_ != NULL) { if (near_death_callback_ != NULL) {
if (IsWeakCallback::decode(flags_)) { if (IsWeakCallback::decode(flags_)) {
WeakReferenceCallback callback = RevivableCallback callback =
reinterpret_cast<WeakReferenceCallback>(near_death_callback_); reinterpret_cast<RevivableCallback>(near_death_callback_);
callback(object, par); callback(reinterpret_cast<v8::Isolate*>(isolate),
&object,
par);
} else { } else {
near_death_callback_(reinterpret_cast<v8::Isolate*>(isolate), near_death_callback_(reinterpret_cast<v8::Isolate*>(isolate),
object, object,
...@@ -493,9 +495,9 @@ void GlobalHandles::Destroy(Object** location) { ...@@ -493,9 +495,9 @@ void GlobalHandles::Destroy(Object** location) {
void GlobalHandles::MakeWeak(Object** location, void GlobalHandles::MakeWeak(Object** location,
void* parameter, void* parameter,
WeakReferenceCallback weak_reference_callback, RevivableCallback weak_reference_callback,
NearDeathCallback near_death_callback) { NearDeathCallback near_death_callback) {
ASSERT(near_death_callback != NULL); ASSERT((weak_reference_callback == NULL) != (near_death_callback == NULL));
Node::FromLocation(location)->MakeWeak(this, Node::FromLocation(location)->MakeWeak(this,
parameter, parameter,
weak_reference_callback, weak_reference_callback,
......
...@@ -130,6 +130,8 @@ class GlobalHandles { ...@@ -130,6 +130,8 @@ class GlobalHandles {
// Destroy a global handle. // Destroy a global handle.
void Destroy(Object** location); void Destroy(Object** location);
typedef WeakReferenceCallbacks<v8::Value, void>::Revivable RevivableCallback;
// Make the global handle weak and set the callback parameter for the // Make the global handle weak and set the callback parameter for the
// handle. When the garbage collector recognizes that only weak global // handle. When the garbage collector recognizes that only weak global
// handles point to an object the handles are cleared and the callback // handles point to an object the handles are cleared and the callback
...@@ -138,7 +140,7 @@ class GlobalHandles { ...@@ -138,7 +140,7 @@ class GlobalHandles {
// reason is that Smi::FromInt(0) does not change during garage collection. // reason is that Smi::FromInt(0) does not change during garage collection.
void MakeWeak(Object** location, void MakeWeak(Object** location,
void* parameter, void* parameter,
WeakReferenceCallback weak_reference_callback, RevivableCallback weak_reference_callback,
NearDeathCallback near_death_callback); NearDeathCallback near_death_callback);
void RecordStats(HeapStats* stats); void RecordStats(HeapStats* stats);
......
...@@ -653,11 +653,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { ...@@ -653,11 +653,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, static void ArrayBufferWeakCallback(v8::Isolate* external_isolate,
Persistent<Value> object, Persistent<Value>* object,
void* data) { void* data) {
Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> internal_object = Utils::OpenHandle(*object); Handle<Object> internal_object = Utils::OpenHandle(**object);
size_t allocated_length = NumberToSize( size_t allocated_length = NumberToSize(
isolate, JSArrayBuffer::cast(*internal_object)->byte_length()); isolate, JSArrayBuffer::cast(*internal_object)->byte_length());
...@@ -665,7 +665,7 @@ static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, ...@@ -665,7 +665,7 @@ static void ArrayBufferWeakCallback(v8::Isolate* external_isolate,
-static_cast<intptr_t>(allocated_length)); -static_cast<intptr_t>(allocated_length));
if (data != NULL) if (data != NULL)
free(data); free(data);
object.Dispose(external_isolate); object->Dispose(external_isolate);
} }
......
This diff is collapsed.
...@@ -1586,9 +1586,9 @@ bool HasWeakGlobalHandle() { ...@@ -1586,9 +1586,9 @@ bool HasWeakGlobalHandle() {
static void PersistentHandleCallback(v8::Isolate* isolate, static void PersistentHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value> handle, v8::Persistent<v8::Value>* handle,
void*) { void*) {
handle.Dispose(isolate); handle->Dispose(isolate);
} }
...@@ -1600,7 +1600,9 @@ TEST(WeakGlobalHandle) { ...@@ -1600,7 +1600,9 @@ TEST(WeakGlobalHandle) {
v8::Persistent<v8::Object> handle = v8::Persistent<v8::Object> handle =
v8::Persistent<v8::Object>::New(env->GetIsolate(), v8::Object::New()); v8::Persistent<v8::Object>::New(env->GetIsolate(), v8::Object::New());
handle.MakeWeak(env->GetIsolate(), NULL, PersistentHandleCallback); handle.MakeWeak<v8::Value, void>(env->GetIsolate(),
NULL,
PersistentHandleCallback);
CHECK(HasWeakGlobalHandle()); CHECK(HasWeakGlobalHandle());
} }
......
...@@ -396,10 +396,10 @@ TEST(GlobalHandles) { ...@@ -396,10 +396,10 @@ TEST(GlobalHandles) {
static bool WeakPointerCleared = false; static bool WeakPointerCleared = false;
static void TestWeakGlobalHandleCallback(v8::Isolate* isolate, static void TestWeakGlobalHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value> handle, v8::Persistent<v8::Value>* handle,
void* id) { void* id) {
if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true;
handle.Dispose(isolate); handle->Dispose(isolate);
} }
...@@ -427,8 +427,8 @@ TEST(WeakGlobalHandlesScavenge) { ...@@ -427,8 +427,8 @@ TEST(WeakGlobalHandlesScavenge) {
global_handles->MakeWeak(h2.location(), global_handles->MakeWeak(h2.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &TestWeakGlobalHandleCallback,
&TestWeakGlobalHandleCallback); NULL);
// Scavenge treats weak pointers as normal roots. // Scavenge treats weak pointers as normal roots.
heap->PerformScavenge(); heap->PerformScavenge();
...@@ -474,8 +474,8 @@ TEST(WeakGlobalHandlesMark) { ...@@ -474,8 +474,8 @@ TEST(WeakGlobalHandlesMark) {
global_handles->MakeWeak(h2.location(), global_handles->MakeWeak(h2.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &TestWeakGlobalHandleCallback,
&TestWeakGlobalHandleCallback); NULL);
CHECK(!GlobalHandles::IsNearDeath(h1.location())); CHECK(!GlobalHandles::IsNearDeath(h1.location()));
CHECK(!GlobalHandles::IsNearDeath(h2.location())); CHECK(!GlobalHandles::IsNearDeath(h2.location()));
...@@ -511,8 +511,8 @@ TEST(DeleteWeakGlobalHandle) { ...@@ -511,8 +511,8 @@ TEST(DeleteWeakGlobalHandle) {
global_handles->MakeWeak(h.location(), global_handles->MakeWeak(h.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &TestWeakGlobalHandleCallback,
&TestWeakGlobalHandleCallback); NULL);
// Scanvenge does not recognize weak reference. // Scanvenge does not recognize weak reference.
heap->PerformScavenge(); heap->PerformScavenge();
......
...@@ -304,11 +304,11 @@ TEST(GCCallback) { ...@@ -304,11 +304,11 @@ TEST(GCCallback) {
static int NumberOfWeakCalls = 0; static int NumberOfWeakCalls = 0;
static void WeakPointerCallback(v8::Isolate* isolate, static void WeakPointerCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value> handle, v8::Persistent<v8::Value>* handle,
void* id) { void* id) {
ASSERT(id == reinterpret_cast<void*>(1234)); ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++; NumberOfWeakCalls++;
handle.Dispose(isolate); handle->Dispose(isolate);
} }
TEST(ObjectGroups) { TEST(ObjectGroups) {
...@@ -327,16 +327,16 @@ TEST(ObjectGroups) { ...@@ -327,16 +327,16 @@ TEST(ObjectGroups) {
global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
global_handles->MakeWeak(g1s1.location(), global_handles->MakeWeak(g1s1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
global_handles->MakeWeak(g1s2.location(), global_handles->MakeWeak(g1s2.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
global_handles->MakeWeak(g1c1.location(), global_handles->MakeWeak(g1c1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
Handle<Object> g2s1 = Handle<Object> g2s1 =
global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
...@@ -346,16 +346,16 @@ TEST(ObjectGroups) { ...@@ -346,16 +346,16 @@ TEST(ObjectGroups) {
global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
global_handles->MakeWeak(g2s1.location(), global_handles->MakeWeak(g2s1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
global_handles->MakeWeak(g2s2.location(), global_handles->MakeWeak(g2s2.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
global_handles->MakeWeak(g2c1.location(), global_handles->MakeWeak(g2c1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
Handle<Object> root = global_handles->Create(*g1s1); // make a root. Handle<Object> root = global_handles->Create(*g1s1); // make a root.
...@@ -384,8 +384,8 @@ TEST(ObjectGroups) { ...@@ -384,8 +384,8 @@ TEST(ObjectGroups) {
// Weaken the root. // Weaken the root.
global_handles->MakeWeak(root.location(), global_handles->MakeWeak(root.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
// But make children strong roots---all the objects (except for children) // But make children strong roots---all the objects (except for children)
// should be collectable now. // should be collectable now.
global_handles->ClearWeakness(g1c1.location()); global_handles->ClearWeakness(g1c1.location());
...@@ -413,12 +413,12 @@ TEST(ObjectGroups) { ...@@ -413,12 +413,12 @@ TEST(ObjectGroups) {
// And now make children weak again and collect them. // And now make children weak again and collect them.
global_handles->MakeWeak(g1c1.location(), global_handles->MakeWeak(g1c1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
global_handles->MakeWeak(g2c1.location(), global_handles->MakeWeak(g2c1.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
HEAP->CollectGarbage(OLD_POINTER_SPACE); HEAP->CollectGarbage(OLD_POINTER_SPACE);
CHECK_EQ(7, NumberOfWeakCalls); CHECK_EQ(7, NumberOfWeakCalls);
......
...@@ -65,11 +65,11 @@ static void PutIntoWeakMap(Handle<JSWeakMap> weakmap, ...@@ -65,11 +65,11 @@ static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
static int NumberOfWeakCalls = 0; static int NumberOfWeakCalls = 0;
static void WeakPointerCallback(v8::Isolate* isolate, static void WeakPointerCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value> handle, v8::Persistent<v8::Value>* handle,
void* id) { void* id) {
ASSERT(id == reinterpret_cast<void*>(1234)); ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++; NumberOfWeakCalls++;
handle.Dispose(isolate); handle->Dispose(isolate);
} }
...@@ -114,8 +114,8 @@ TEST(Weakness) { ...@@ -114,8 +114,8 @@ TEST(Weakness) {
HandleScope scope(isolate); HandleScope scope(isolate);
global_handles->MakeWeak(key.location(), global_handles->MakeWeak(key.location(),
reinterpret_cast<void*>(1234), reinterpret_cast<void*>(1234),
NULL, &WeakPointerCallback,
&WeakPointerCallback); NULL);
} }
CHECK(global_handles->IsWeak(key.location())); CHECK(global_handles->IsWeak(key.location()));
......
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