| Index: src/stub-cache.cc
|
| diff --git a/src/stub-cache.cc b/src/stub-cache.cc
|
| index f959e924988a8f0a72ab1e9961b668dbea345328..d812588a3790a6c90e3e815e3993c0362222d463 100644
|
| --- a/src/stub-cache.cc
|
| +++ b/src/stub-cache.cc
|
| @@ -893,43 +893,62 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
|
|
|
|
|
| Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
|
| - Handle<Name> name) {
|
| - // Perform a lookup after the interceptor.
|
| - LookupResult lookup(isolate());
|
| - holder()->LookupOwnRealNamedProperty(name, &lookup);
|
| - if (!lookup.IsFound()) {
|
| - PrototypeIterator iter(holder()->GetIsolate(), holder());
|
| - if (!iter.IsAtEnd()) {
|
| - PrototypeIterator::GetCurrent(iter)->Lookup(name, &lookup);
|
| + LookupIterator* it, Handle<Name> name) {
|
| + // So far the most popular follow ups for interceptor loads are FIELD and
|
| + // ExecutableAccessorInfo, so inline only them. Other cases may be added
|
| + // later.
|
| + bool inline_followup = it->state() == LookupIterator::PROPERTY;
|
| + if (inline_followup) {
|
| + switch (it->property_kind()) {
|
| + case LookupIterator::DATA:
|
| + inline_followup = it->property_details().type() == FIELD;
|
| + break;
|
| + case LookupIterator::ACCESSOR: {
|
| + Handle<Object> accessors = it->GetAccessors();
|
| + inline_followup = accessors->IsExecutableAccessorInfo();
|
| + if (!inline_followup) break;
|
| + Handle<ExecutableAccessorInfo> info =
|
| + Handle<ExecutableAccessorInfo>::cast(accessors);
|
| + inline_followup = info->getter() != NULL &&
|
| + ExecutableAccessorInfo::IsCompatibleReceiverType(
|
| + isolate(), info, type());
|
| + }
|
| }
|
| }
|
|
|
| Register reg = Frontend(receiver(), name);
|
| - // TODO(368): Compile in the whole chain: all the interceptors in
|
| - // prototypes and ultimate answer.
|
| - GenerateLoadInterceptor(reg, &lookup, name);
|
| + if (inline_followup) {
|
| + // TODO(368): Compile in the whole chain: all the interceptors in
|
| + // prototypes and ultimate answer.
|
| + GenerateLoadInterceptorWithFollowup(it, reg);
|
| + } else {
|
| + GenerateLoadInterceptor(reg);
|
| + }
|
| return GetCode(kind(), Code::FAST, name);
|
| }
|
|
|
|
|
| void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
|
| - Register interceptor_reg, Handle<Name> name, LookupResult* lookup) {
|
| - Handle<JSObject> real_named_property_holder(lookup->holder());
|
| + LookupIterator* it, Register interceptor_reg) {
|
| + Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
|
|
|
| set_type_for_object(holder());
|
| set_holder(real_named_property_holder);
|
| - Register reg = Frontend(interceptor_reg, name);
|
| -
|
| - if (lookup->IsField()) {
|
| - __ Move(receiver(), reg);
|
| - LoadFieldStub stub(isolate(), lookup->GetFieldIndex());
|
| - GenerateTailCall(masm(), stub.GetCode());
|
| - } else {
|
| - DCHECK(lookup->type() == CALLBACKS);
|
| - Handle<ExecutableAccessorInfo> callback(
|
| - ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
|
| - DCHECK(callback->getter() != NULL);
|
| - GenerateLoadCallback(reg, callback);
|
| + Register reg = Frontend(interceptor_reg, it->name());
|
| +
|
| + switch (it->property_kind()) {
|
| + case LookupIterator::DATA: {
|
| + DCHECK_EQ(FIELD, it->property_details().type());
|
| + __ Move(receiver(), reg);
|
| + LoadFieldStub stub(isolate(), it->GetFieldIndex());
|
| + GenerateTailCall(masm(), stub.GetCode());
|
| + break;
|
| + }
|
| + case LookupIterator::ACCESSOR:
|
| + Handle<ExecutableAccessorInfo> info =
|
| + Handle<ExecutableAccessorInfo>::cast(it->GetAccessors());
|
| + DCHECK_NE(NULL, info->getter());
|
| + GenerateLoadCallback(reg, info);
|
| }
|
| }
|
|
|
|
|