Commit 3c6c3993 authored by antonm@chromium.org's avatar antonm@chromium.org

Introduce faster utilty methods for storing and retrieving native pointers

in internal fields.



git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2498 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4f2cc410
......@@ -1113,6 +1113,13 @@ class V8EXPORT Object : public Value {
/** Sets the value in an internal field. */
void SetInternalField(int index, Handle<Value> value);
// The two functions below do not perform index bounds checks and
// they do not check that the VM is still running. Use with caution.
/** Gets a native pointer from an internal field. */
void* GetPointerFromInternalField(int index);
/** Sets a native pointer in an internal field. */
void SetPointerInInternalField(int index, void* value);
// Testers for local properties.
bool HasRealNamedProperty(Handle<String> key);
bool HasRealIndexedProperty(uint32_t index);
......
......@@ -2465,6 +2465,43 @@ void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
}
void* v8::Object::GetPointerFromInternalField(int index) {
i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
i::Object* pointer = obj->GetInternalField(index);
if (pointer->IsSmi()) {
// Fast case, aligned native pointer.
return pointer;
}
// Read from uninitialized field.
if (!pointer->IsProxy()) {
// Play safe even if it's something unexpected.
ASSERT(pointer->IsUndefined());
return NULL;
}
// Unaligned native pointer
return reinterpret_cast<void*>(i::Proxy::cast(pointer)->proxy());
}
void v8::Object::SetPointerInInternalField(int index, void* value) {
i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
i::Object* as_object = reinterpret_cast<i::Object*>(value);
if (as_object->IsSmi()) {
// Aligned pointer, store as is.
obj->SetInternalField(index, as_object);
} else {
// Currently internal fields are used by DOM wrappers which
// only get GCed by the mark-sweep collector,
// so let's put proxy into old space.
i::Proxy* proxy = *i::Factory::NewProxy(reinterpret_cast<i::Address>(value),
i::TENURED);
obj->SetInternalField(index, proxy);
}
}
// --- E n v i r o n m e n t ---
bool v8::V8::Initialize() {
......
......@@ -1266,6 +1266,38 @@ THREADED_TEST(InternalFields) {
}
THREADED_TEST(InternalFieldsNativePointers) {
v8::HandleScope scope;
LocalContext env;
Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetInternalFieldCount(1);
Local<v8::Object> obj = templ->GetFunction()->NewInstance();
CHECK_EQ(1, obj->InternalFieldCount());
CHECK(obj->GetPointerFromInternalField(0) == NULL);
char* data = new char[100];
void* aligned = data;
CHECK_EQ(0, reinterpret_cast<uintptr_t>(aligned) & 0x1);
void* unaligned = data + 1;
CHECK_EQ(1, reinterpret_cast<uintptr_t>(unaligned) & 0x1);
// Check reading and writing aligned pointers.
obj->SetPointerInInternalField(0, aligned);
i::Heap::CollectAllGarbage();
CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
// Check reading and writing unaligned pointers.
obj->SetPointerInInternalField(0, unaligned);
i::Heap::CollectAllGarbage();
CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
delete[] data;
}
THREADED_TEST(IdentityHash) {
v8::HandleScope scope;
LocalContext env;
......
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