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,
__ 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);
}
......
......@@ -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,
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;
......
......@@ -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<InterceptorInfo> interceptor(GetNamedInterceptor());
Handle<JSObject> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> 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<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);
......
......@@ -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);
};
......
......@@ -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<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;
Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(4);
Handle<Object> data_handle = args.at<Object>(5);
Object* result = holder->GetInterceptorPropertyWithLookupHint(
recv, lookup_hint, name, &attr);
if (result->IsFailure()) return result;
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);
}
}
// If the property is present, return it.
if (attr != ABSENT) return result;
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
......
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