Revision: 2562 Author: [email protected] Date: Tue Jul 28 07:46:06 2009 Log: Get rid of unnecessary handle management when invoking interceptors.
Review URL: http://codereview.chromium.org/155682 http://code.google.com/p/v8/source/detail?r=2562 Modified: /branches/bleeding_edge/src/arm/stub-cache-arm.cc /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc /branches/bleeding_edge/src/objects.cc /branches/bleeding_edge/src/objects.h /branches/bleeding_edge/src/stub-cache.cc ======================================= --- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Jul 28 05:46:08 2009 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Jul 28 07:46:06 2009 @@ -505,10 +505,17 @@ __ mov(scratch1, Operand(lookup_hint)); __ push(scratch1); + InterceptorInfo* interceptor = holder->GetNamedInterceptor(); + ASSERT(!Heap::InNewSpace(interceptor)); + __ mov(scratch1, Operand(Handle<Object>(interceptor))); + __ push(scratch1); + __ ldr(scratch2, FieldMemOperand(scratch1, InterceptorInfo::kDataOffset)); + __ push(scratch2); + // Do tail-call to the runtime system. ExternalReference load_ic_property = ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); - __ TailCallRuntime(load_ic_property, 4); + __ TailCallRuntime(load_ic_property, 6); } ======================================= --- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Jul 28 05:46:08 2009 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Jul 28 07:46:06 2009 @@ -150,6 +150,27 @@ // entering the runtime system. __ bind(&miss); } + + +template <typename Pushable> +static void PushInterceptorArguments(MacroAssembler* masm, + Register receiver, + Register holder, + Pushable name, + JSObject* holder_obj, + Smi* lookup_hint) { + __ push(receiver); + __ push(holder); + __ push(name); + // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or + // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? + __ push(Immediate(lookup_hint)); + + InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); + __ mov(receiver, Immediate(Handle<Object>(interceptor))); + __ push(receiver); + __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset)); +} void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, @@ -504,18 +525,18 @@ // Push the arguments on the JS stack of the caller. __ pop(scratch2); // remove return address - __ push(receiver); // receiver - __ push(reg); // holder - __ push(name_reg); // name - // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or - // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? - __ push(Immediate(lookup_hint)); + PushInterceptorArguments(masm(), + receiver, + reg, + name_reg, + holder, + lookup_hint); __ push(scratch2); // restore return address // Do tail-call to the runtime system. ExternalReference load_ic_property = ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); - __ TailCallRuntime(load_ic_property, 4); + __ TailCallRuntime(load_ic_property, 6); } @@ -744,15 +765,17 @@ __ EnterInternalFrame(); // Push arguments on the expression stack. - __ push(edx); // receiver - __ push(reg); // holder - __ push(Operand(ebp, (argc + 3) * kPointerSize)); // name - __ push(Immediate(holder->InterceptorPropertyLookupHint(name))); + PushInterceptorArguments(masm(), + edx, + reg, + Operand(ebp, (argc + 3) * kPointerSize), + holder, + holder->InterceptorPropertyLookupHint(name)); // Perform call. ExternalReference load_interceptor = ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); - __ mov(eax, Immediate(4)); + __ mov(eax, Immediate(6)); __ mov(ebx, Immediate(load_interceptor)); CEntryStub stub; ======================================= --- /branches/bleeding_edge/src/objects.cc Tue Jul 28 05:50:58 2009 +++ /branches/bleeding_edge/src/objects.cc Tue Jul 28 07:46:06 2009 @@ -6028,12 +6028,12 @@ } -Object* JSObject::GetPropertyWithInterceptorProper( +Object* JSObject::GetPropertyWithInterceptor( JSObject* receiver, String* name, PropertyAttributes* attributes) { + InterceptorInfo* interceptor = GetNamedInterceptor(); HandleScope scope; - Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); Handle<JSObject> receiver_handle(receiver); Handle<JSObject> holder_handle(this); Handle<String> name_handle(name); @@ -6052,85 +6052,14 @@ VMState state(EXTERNAL); result = getter(v8::Utils::ToLocal(name_handle), info); } - if (!Top::has_scheduled_exception() && !result.IsEmpty()) { + RETURN_IF_SCHEDULED_EXCEPTION(); + if (!result.IsEmpty()) { *attributes = NONE; return *v8::Utils::OpenHandle(*result); } } - *attributes = ABSENT; - return Heap::undefined_value(); -} - - -Object* JSObject::GetInterceptorPropertyWithLookupHint( - JSObject* receiver, - Smi* lookup_hint, - String* name, - PropertyAttributes* attributes) { - HandleScope scope; - Handle<JSObject> receiver_handle(receiver); - Handle<JSObject> holder_handle(this); - Handle<String> name_handle(name); - - Object* result = GetPropertyWithInterceptorProper(receiver, - name, - attributes); - if (*attributes != ABSENT) { - return result; - } - RETURN_IF_SCHEDULED_EXCEPTION(); - - int property_index = lookup_hint->value(); - if (property_index >= 0) { - result = holder_handle->FastPropertyAt(property_index); - } else { - switch (property_index) { - case kLookupInPrototype: { - Object* pt = holder_handle->GetPrototype(); - *attributes = ABSENT; - if (pt == Heap::null_value()) return Heap::undefined_value(); - result = pt->GetPropertyWithReceiver( - *receiver_handle, - *name_handle, - attributes); - RETURN_IF_SCHEDULED_EXCEPTION(); - } - break; - - case kLookupInHolder: - result = holder_handle->GetPropertyPostInterceptor( - *receiver_handle, - *name_handle, - attributes); - RETURN_IF_SCHEDULED_EXCEPTION(); - break; - - default: - UNREACHABLE(); - } - } - - return result; -} - - -Object* JSObject::GetPropertyWithInterceptor( - JSObject* receiver, - String* name, - PropertyAttributes* attributes) { - HandleScope scope; - Handle<JSObject> receiver_handle(receiver); - Handle<JSObject> holder_handle(this); - Handle<String> name_handle(name); - - Object* result = GetPropertyWithInterceptorProper(receiver, name, attributes); - if (*attributes != ABSENT) { - return result; - } - RETURN_IF_SCHEDULED_EXCEPTION(); - - result = holder_handle->GetPropertyPostInterceptor( + Object* result = holder_handle->GetPropertyPostInterceptor( *receiver_handle, *name_handle, attributes); ======================================= --- /branches/bleeding_edge/src/objects.h Tue Jul 28 02:05:05 2009 +++ /branches/bleeding_edge/src/objects.h Tue Jul 28 07:46:06 2009 @@ -1508,10 +1508,6 @@ void LookupCallback(String* name, LookupResult* result); inline Smi* InterceptorPropertyLookupHint(String* name); - Object* GetInterceptorPropertyWithLookupHint(JSObject* receiver, - Smi* lookup_hint, - String* name, - PropertyAttributes* attributes); static const int kLookupInHolder = -1; static const int kLookupInPrototype = -2; @@ -1706,12 +1702,6 @@ void LookupInDescriptor(String* name, LookupResult* result); - // Attempts to get property with a named interceptor getter. - // Sets |attributes| to ABSENT if interceptor didn't return anything - Object* GetPropertyWithInterceptorProper(JSObject* receiver, - String* name, - PropertyAttributes* attributes); - DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject); }; ======================================= --- /branches/bleeding_edge/src/stub-cache.cc Mon Jul 27 02:54:59 2009 +++ /branches/bleeding_edge/src/stub-cache.cc Tue Jul 28 07:46:06 2009 @@ -789,19 +789,70 @@ Object* LoadInterceptorProperty(Arguments args) { - JSObject* recv = JSObject::cast(args[0]); - JSObject* holder = JSObject::cast(args[1]); - String* name = String::cast(args[2]); + Handle<JSObject> receiver_handle = args.at<JSObject>(0); + Handle<JSObject> holder_handle = args.at<JSObject>(1); + Handle<String> name_handle = args.at<String>(2); Smi* lookup_hint = Smi::cast(args[3]); - ASSERT(holder->HasNamedInterceptor()); - PropertyAttributes attr = NONE; - - Object* result = holder->GetInterceptorPropertyWithLookupHint( - recv, lookup_hint, name, &attr); - if (result->IsFailure()) return result; - - // If the property is present, return it. - if (attr != ABSENT) return result; + Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(4); + Handle<Object> data_handle = args.at<Object>(5); + + Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); + v8::NamedPropertyGetter getter = + FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); + ASSERT(getter != NULL); + + PropertyAttributes attributes = ABSENT; + Object* result = Heap::undefined_value(); + + { + // Use the interceptor getter. + v8::AccessorInfo info(v8::Utils::ToLocal(receiver_handle), + v8::Utils::ToLocal(data_handle), + v8::Utils::ToLocal(holder_handle)); + HandleScope scope; + v8::Handle<v8::Value> r; + { + // Leaving JavaScript. + VMState state(EXTERNAL); + r = getter(v8::Utils::ToLocal(name_handle), info); + } + RETURN_IF_SCHEDULED_EXCEPTION(); + if (!r.IsEmpty()) { + return *v8::Utils::OpenHandle(*r); + } + } + + int property_index = lookup_hint->value(); + if (property_index >= 0) { + result = holder_handle->FastPropertyAt(property_index); + } else { + switch (property_index) { + case JSObject::kLookupInPrototype: { + Object* pt = holder_handle->GetPrototype(); + if (pt == Heap::null_value()) return Heap::undefined_value(); + result = pt->GetPropertyWithReceiver( + *receiver_handle, + *name_handle, + &attributes); + RETURN_IF_SCHEDULED_EXCEPTION(); + } + break; + + case JSObject::kLookupInHolder: + result = holder_handle->GetPropertyPostInterceptor( + *receiver_handle, + *name_handle, + &attributes); + RETURN_IF_SCHEDULED_EXCEPTION(); + break; + + default: + UNREACHABLE(); + } + } + + if (result->IsFailure()) return result; + if (attributes != ABSENT) return result; // If the top frame is an internal frame, this is really a call // IC. In this case, we simply return the undefined result which --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
