diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-10-04 16:06:09 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-06-13 09:56:37 +0200 |
commit | ccad1b6e4ca295861ff50b8e84560dd9769930d1 (patch) | |
tree | fd180f05ac14f4f806711ce4f2316d899a1536d5 /src/3rdparty/v8/src/api.cc | |
parent | c010afb5a3c2948730ab9b35baa3deba1acb6531 (diff) |
[V8] Generalize external object resources
V8 was already able to manage and finalize an external string
resource. This change generalizes that mechanism to handle a
single generic external resource - a v8::Object::ExternalResource
derived instance - on normal JSObject's.
This is useful for mapping C++ objects to JS objects where the
C++ object's memory is effectively owned by the JS Object, and
thus needs to destroyed when the JS Object is garbage collected.
The V8 mailing list suggests using a weak persistent handle for
this purpose, but that seems to incur a fairly massive performance
penalty for short lived objects as weak persistent handle callbacks
are not called until the object has been promoted into the old
object space.
Change-Id: I8f1a1f2a2be052339e8507b98058b289c7f16b0a
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src/3rdparty/v8/src/api.cc')
-rw-r--r-- | src/3rdparty/v8/src/api.cc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/3rdparty/v8/src/api.cc b/src/3rdparty/v8/src/api.cc index d31269c..2de7bb8 100644 --- a/src/3rdparty/v8/src/api.cc +++ b/src/3rdparty/v8/src/api.cc @@ -1465,6 +1465,34 @@ void ObjectTemplate::SetInternalFieldCount(int value) { } +bool ObjectTemplate::HasExternalResource() +{ + if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(), + "v8::ObjectTemplate::HasExternalResource()")) { + return 0; + } + return !Utils::OpenHandle(this)->has_external_resource()->IsUndefined(); +} + + +void ObjectTemplate::SetHasExternalResource(bool value) +{ + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetHasExternalResource()")) { + return; + } + ENTER_V8(isolate); + if (value) { + EnsureConstructor(this); + } + if (value) { + Utils::OpenHandle(this)->set_has_external_resource(i::Smi::FromInt(1)); + } else { + Utils::OpenHandle(this)->set_has_external_resource(Utils::OpenHandle(this)->GetHeap()->undefined_value()); + } +} + + // --- S c r i p t D a t a --- @@ -4266,6 +4294,34 @@ void v8::Object::SetPointerInInternalField(int index, void* value) { } +void v8::Object::SetExternalResource(v8::Object::ExternalResource *resource) { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + ENTER_V8(isolate); + i::Handle<i::JSObject> obj = Utils::OpenHandle(this); + if (CanBeEncodedAsSmi(resource)) { + obj->SetExternalResourceObject(EncodeAsSmi(resource)); + } else { + obj->SetExternalResourceObject(*isolate->factory()->NewForeign(static_cast<i::Address>((void *)resource))); + } + if (!obj->IsSymbol()) { + isolate->heap()->external_string_table()->AddObject(*obj); + } +} + + +v8::Object::ExternalResource *v8::Object::GetExternalResource() { + i::Handle<i::JSObject> obj = Utils::OpenHandle(this); + i::Object* value = obj->GetExternalResourceObject(); + if (value->IsSmi()) { + return reinterpret_cast<v8::Object::ExternalResource*>(i::Internals::GetExternalPointerFromSmi(value)); + } else if (value->IsForeign()) { + return reinterpret_cast<v8::Object::ExternalResource*>(i::Foreign::cast(value)->foreign_address()); + } else { + return NULL; + } +} + + // --- E n v i r o n m e n t --- |