Reviewers: Christian Plesner Hansen, Description: Partially revert r2761.
Do not create handles for values of internal fields---this operation is performance critical and plain pointers are safe. Please review this at http://codereview.chromium.org/270085 SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/ Affected files: M include/v8.h M src/api.cc Index: include/v8.h =================================================================== --- include/v8.h (revision 3045) +++ include/v8.h (working copy) @@ -1194,7 +1194,7 @@ /** Gets a native pointer from an internal field. */ inline void* GetPointerFromInternalField(int index); - + /** Sets a native pointer in an internal field. */ void SetPointerInInternalField(int index, void* value); @@ -1278,6 +1278,8 @@ Object(); static void CheckCast(Value* obj); Local<Value> CheckedGetInternalField(int index); + void* SlowGetPointerFromInternalField(int index); + static void* SlowGetPointerFromObject(v8::internal::Object* object); /** * If quick access to the internal field is possible this method @@ -2987,7 +2989,23 @@ void* Object::GetPointerFromInternalField(int index) { - return External::Unwrap(GetInternalField(index)); + typedef internal::Object O; + typedef internal::Internals I; + + O* obj = *reinterpret_cast<O**>(this); + + O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); + int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset); + if (instance_type == I::kJSObjectType) { + // If the object is a plain JSObject, which is the common case, + // we know where to find the internal fields and can return the + // value directly. + int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); + O* value = I::ReadField<O*>(obj, offset); + return I::HasSmiTag(value) ? value : SlowGetPointerFromObject(value); + } + + return SlowGetPointerFromInternalField(index); } Index: src/api.cc =================================================================== --- src/api.cc (revision 3045) +++ src/api.cc (working copy) @@ -2578,7 +2578,16 @@ void v8::Object::SetPointerInInternalField(int index, void* value) { - SetInternalField(index, External::Wrap(value)); + i::Object* as_object = reinterpret_cast<i::Object*>(value); + if (as_object->IsSmi()) { + Utils::OpenHandle(this)->SetInternalField(index, as_object); + return; + } + HandleScope scope; + i::Handle<i::Proxy> proxy = + i::Factory::NewProxy(reinterpret_cast<i::Address>(value), i::TENURED); + if (!proxy.is_null()) + Utils::OpenHandle(this)->SetInternalField(index, *proxy); } @@ -2860,6 +2869,22 @@ } +void* v8::Object::SlowGetPointerFromObject(i::Object* object) { + if (object->IsProxy()) { + return reinterpret_cast<void*>(i::Proxy::cast(object)->proxy()); + } else { + return NULL; + } +} + + +void* v8::Object::SlowGetPointerFromInternalField(int index) { + i::Handle<i::JSObject> obj = Utils::OpenHandle(this); + i::Object* value = obj->GetInternalField(index); + return value->IsSmi() ? value : SlowGetPointerFromObject(value); +} + + void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) { if (IsDeadCheck("v8::External::Unwrap()")) return 0; i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
