From 4354661a49e17740f99937a41d21fcdd8ef4f3cb Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Tue, 28 Jul 2009 14:46:06 +0000 Subject: [PATCH] Get rid of unnecessary handle management when invoking interceptors. Review URL: http://codereview.chromium.org/155682 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2562 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 9 ++++- src/ia32/stub-cache-ia32.cc | 47 +++++++++++++++------ src/objects.cc | 81 +++---------------------------------- src/objects.h | 10 ----- src/stub-cache.cc | 71 +++++++++++++++++++++++++++----- 5 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index d58817b919..5d206a8f93 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -505,10 +505,17 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, __ mov(scratch1, Operand(lookup_hint)); __ push(scratch1); + InterceptorInfo* interceptor = holder->GetNamedInterceptor(); + ASSERT(!Heap::InNewSpace(interceptor)); + __ mov(scratch1, Operand(Handle(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); } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 59712bf9d1..a9e2b663a3 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -152,6 +152,27 @@ void StubCache::GenerateProbe(MacroAssembler* masm, } +template +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(interceptor))); + __ push(receiver); + __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset)); +} + + void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, int index, Register prototype) { @@ -504,18 +525,18 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, // 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 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object, __ 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; diff --git a/src/objects.cc b/src/objects.cc index bba1e0beb3..7467475cc2 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -6028,12 +6028,12 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, } -Object* JSObject::GetPropertyWithInterceptorProper( +Object* JSObject::GetPropertyWithInterceptor( JSObject* receiver, String* name, PropertyAttributes* attributes) { + InterceptorInfo* interceptor = GetNamedInterceptor(); HandleScope scope; - Handle interceptor(GetNamedInterceptor()); Handle receiver_handle(receiver); Handle holder_handle(this); Handle name_handle(name); @@ -6052,85 +6052,14 @@ Object* JSObject::GetPropertyWithInterceptorProper( 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 receiver_handle(receiver); - Handle holder_handle(this); - Handle 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 receiver_handle(receiver); - Handle holder_handle(this); - Handle 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); diff --git a/src/objects.h b/src/objects.h index c42f531395..64e6b36c55 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1508,10 +1508,6 @@ class JSObject: public HeapObject { 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 @@ class JSObject: public HeapObject { 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); }; diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 859514885a..06abc999bb 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -789,19 +789,70 @@ Object* StoreCallbackProperty(Arguments args) { Object* LoadInterceptorProperty(Arguments args) { - JSObject* recv = JSObject::cast(args[0]); - JSObject* holder = JSObject::cast(args[1]); - String* name = String::cast(args[2]); + Handle receiver_handle = args.at(0); + Handle holder_handle = args.at(1); + Handle name_handle = args.at(2); Smi* lookup_hint = Smi::cast(args[3]); - ASSERT(holder->HasNamedInterceptor()); - PropertyAttributes attr = NONE; + Handle interceptor_info = args.at(4); + Handle data_handle = args.at(5); + + Address getter_address = v8::ToCData
(interceptor_info->getter()); + v8::NamedPropertyGetter getter = + FUNCTION_CAST(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 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(); + } + } - 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; + 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