Commit 4354661a authored by antonm@chromium.org's avatar antonm@chromium.org

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
parent 1ed74621
...@@ -505,10 +505,17 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, ...@@ -505,10 +505,17 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
__ mov(scratch1, Operand(lookup_hint)); __ mov(scratch1, Operand(lookup_hint));
__ push(scratch1); __ 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. // Do tail-call to the runtime system.
ExternalReference load_ic_property = ExternalReference load_ic_property =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ TailCallRuntime(load_ic_property, 4); __ TailCallRuntime(load_ic_property, 6);
} }
......
...@@ -152,6 +152,27 @@ void StubCache::GenerateProbe(MacroAssembler* masm, ...@@ -152,6 +152,27 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
} }
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, void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
int index, int index,
Register prototype) { Register prototype) {
...@@ -504,18 +525,18 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, ...@@ -504,18 +525,18 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
// Push the arguments on the JS stack of the caller. // Push the arguments on the JS stack of the caller.
__ pop(scratch2); // remove return address __ pop(scratch2); // remove return address
__ push(receiver); // receiver PushInterceptorArguments(masm(),
__ push(reg); // holder receiver,
__ push(name_reg); // name reg,
// TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or name_reg,
// LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? holder,
__ push(Immediate(lookup_hint)); lookup_hint);
__ push(scratch2); // restore return address __ push(scratch2); // restore return address
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
ExternalReference load_ic_property = ExternalReference load_ic_property =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ TailCallRuntime(load_ic_property, 4); __ TailCallRuntime(load_ic_property, 6);
} }
...@@ -744,15 +765,17 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object, ...@@ -744,15 +765,17 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
__ EnterInternalFrame(); __ EnterInternalFrame();
// Push arguments on the expression stack. // Push arguments on the expression stack.
__ push(edx); // receiver PushInterceptorArguments(masm(),
__ push(reg); // holder edx,
__ push(Operand(ebp, (argc + 3) * kPointerSize)); // name reg,
__ push(Immediate(holder->InterceptorPropertyLookupHint(name))); Operand(ebp, (argc + 3) * kPointerSize),
holder,
holder->InterceptorPropertyLookupHint(name));
// Perform call. // Perform call.
ExternalReference load_interceptor = ExternalReference load_interceptor =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ mov(eax, Immediate(4)); __ mov(eax, Immediate(6));
__ mov(ebx, Immediate(load_interceptor)); __ mov(ebx, Immediate(load_interceptor));
CEntryStub stub; CEntryStub stub;
......
...@@ -6028,12 +6028,12 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, ...@@ -6028,12 +6028,12 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
} }
Object* JSObject::GetPropertyWithInterceptorProper( Object* JSObject::GetPropertyWithInterceptor(
JSObject* receiver, JSObject* receiver,
String* name, String* name,
PropertyAttributes* attributes) { PropertyAttributes* attributes) {
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope; HandleScope scope;
Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
Handle<JSObject> receiver_handle(receiver); Handle<JSObject> receiver_handle(receiver);
Handle<JSObject> holder_handle(this); Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name); Handle<String> name_handle(name);
...@@ -6052,85 +6052,14 @@ Object* JSObject::GetPropertyWithInterceptorProper( ...@@ -6052,85 +6052,14 @@ Object* JSObject::GetPropertyWithInterceptorProper(
VMState state(EXTERNAL); VMState state(EXTERNAL);
result = getter(v8::Utils::ToLocal(name_handle), info); result = getter(v8::Utils::ToLocal(name_handle), info);
} }
if (!Top::has_scheduled_exception() && !result.IsEmpty()) { RETURN_IF_SCHEDULED_EXCEPTION();
if (!result.IsEmpty()) {
*attributes = NONE; *attributes = NONE;
return *v8::Utils::OpenHandle(*result); return *v8::Utils::OpenHandle(*result);
} }
} }
*attributes = ABSENT; Object* result = holder_handle->GetPropertyPostInterceptor(
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(
*receiver_handle, *receiver_handle,
*name_handle, *name_handle,
attributes); attributes);
......
...@@ -1508,10 +1508,6 @@ class JSObject: public HeapObject { ...@@ -1508,10 +1508,6 @@ class JSObject: public HeapObject {
void LookupCallback(String* name, LookupResult* result); void LookupCallback(String* name, LookupResult* result);
inline Smi* InterceptorPropertyLookupHint(String* name); inline Smi* InterceptorPropertyLookupHint(String* name);
Object* GetInterceptorPropertyWithLookupHint(JSObject* receiver,
Smi* lookup_hint,
String* name,
PropertyAttributes* attributes);
static const int kLookupInHolder = -1; static const int kLookupInHolder = -1;
static const int kLookupInPrototype = -2; static const int kLookupInPrototype = -2;
...@@ -1706,12 +1702,6 @@ class JSObject: public HeapObject { ...@@ -1706,12 +1702,6 @@ class JSObject: public HeapObject {
void LookupInDescriptor(String* name, LookupResult* result); 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); DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
}; };
......
...@@ -789,19 +789,70 @@ Object* StoreCallbackProperty(Arguments args) { ...@@ -789,19 +789,70 @@ Object* StoreCallbackProperty(Arguments args) {
Object* LoadInterceptorProperty(Arguments args) { Object* LoadInterceptorProperty(Arguments args) {
JSObject* recv = JSObject::cast(args[0]); Handle<JSObject> receiver_handle = args.at<JSObject>(0);
JSObject* holder = JSObject::cast(args[1]); Handle<JSObject> holder_handle = args.at<JSObject>(1);
String* name = String::cast(args[2]); Handle<String> name_handle = args.at<String>(2);
Smi* lookup_hint = Smi::cast(args[3]); Smi* lookup_hint = Smi::cast(args[3]);
ASSERT(holder->HasNamedInterceptor()); Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(4);
PropertyAttributes attr = NONE; Handle<Object> data_handle = args.at<Object>(5);
Object* result = holder->GetInterceptorPropertyWithLookupHint( Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
recv, lookup_hint, name, &attr); v8::NamedPropertyGetter getter =
if (result->IsFailure()) return result; 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);
}
}
// If the property is present, return it. int property_index = lookup_hint->value();
if (attr != ABSENT) return result; 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 // If the top frame is an internal frame, this is really a call
// IC. In this case, we simply return the undefined result which // IC. In this case, we simply return the undefined result which
......
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