Revision: 23173
Author: [email protected]
Date: Mon Aug 18 19:37:49 2014 UTC
Log: MIPS: Use LookupIterator for CompileLoadInterceptor and delete
Object::Lookup.
Port r23168 (d860963)
BUG=
[email protected]
Review URL: https://codereview.chromium.org/473243003
Patch from Balazs Kilvady <[email protected]>.
http://code.google.com/p/v8/source/detail?r=23173
Modified:
/branches/bleeding_edge/src/mips/stub-cache-mips.cc
/branches/bleeding_edge/src/mips64/stub-cache-mips64.cc
=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Wed Aug 6 15:11:09
2014 UTC
+++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Mon Aug 18 19:37:49
2014 UTC
@@ -794,88 +794,75 @@
}
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
- LookupResult*
lookup,
- Handle<Name> name) {
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+ LookupIterator* it, Register holder_reg) {
DCHECK(holder()->HasNamedInterceptor());
DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
- // So far the most popular follow ups for interceptor loads are FIELD
- // and CALLBACKS, so inline only them, other cases may be added
- // later.
- bool compile_followup_inline = false;
- if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->IsField()) {
- compile_followup_inline = true;
- } else if (lookup->type() == CALLBACKS &&
- lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> callback(
- ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
- compile_followup_inline =
- callback->getter() != NULL &&
- ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(),
callback,
- type());
+ // Compile the interceptor call, followed by inline code to load the
+ // property from further up the prototype chain if the call fails.
+ // Check that the maps haven't changed.
+ DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+
+ // Preserve the receiver register explicitly whenever it is different
from the
+ // holder and it is needed should the interceptor return without any
result.
+ // The ACCESSOR case needs the receiver to be passed into C++ code, the
FIELD
+ // case might cause a miss during the prototype check.
+ bool must_perform_prototype_check =
+ !holder().is_identical_to(it->GetHolder<JSObject>());
+ bool must_preserve_receiver_reg =
+ !receiver().is(holder_reg) &&
+ (it->property_kind() == LookupIterator::ACCESSOR ||
+ must_perform_prototype_check);
+
+ // Save necessary data before invoking an interceptor.
+ // Requires a frame to make GC aware of pushed pointers.
+ {
+ FrameScope frame_scope(masm(), StackFrame::INTERNAL);
+ if (must_preserve_receiver_reg) {
+ __ Push(receiver(), holder_reg, this->name());
+ } else {
+ __ Push(holder_reg, this->name());
}
- }
+ // Invoke an interceptor. Note: map checks from receiver to
+ // interceptor's holder has been compiled before (see a caller
+ // of this method).
+ CompileCallLoadPropertyWithInterceptor(
+ masm(), receiver(), holder_reg, this->name(), holder(),
+ IC::kLoadPropertyWithInterceptorOnly);
- if (compile_followup_inline) {
- // Compile the interceptor call, followed by inline code to load the
- // property from further up the prototype chain if the call fails.
- // Check that the maps haven't changed.
- DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+ // Check if interceptor provided a value for property. If it's
+ // the case, return immediately.
+ Label interceptor_failed;
+ __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
+ __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
+ frame_scope.GenerateLeaveFrame();
+ __ Ret();
- // Preserve the receiver register explicitly whenever it is different
from
- // the holder and it is needed should the interceptor return without
any
- // result. The CALLBACKS case needs the receiver to be passed into C++
code,
- // the FIELD case might cause a miss during the prototype check.
- bool must_perfrom_prototype_check = *holder() != lookup->holder();
- bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
- (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+ __ bind(&interceptor_failed);
+ if (must_preserve_receiver_reg) {
+ __ Pop(receiver(), holder_reg, this->name());
+ } else {
+ __ Pop(holder_reg, this->name());
+ }
+ // Leave the internal frame.
+ }
- // Save necessary data before invoking an interceptor.
- // Requires a frame to make GC aware of pushed pointers.
- {
- FrameScope frame_scope(masm(), StackFrame::INTERNAL);
- if (must_preserve_receiver_reg) {
- __ Push(receiver(), holder_reg, this->name());
- } else {
- __ Push(holder_reg, this->name());
- }
- // Invoke an interceptor. Note: map checks from receiver to
- // interceptor's holder has been compiled before (see a caller
- // of this method).
- CompileCallLoadPropertyWithInterceptor(
- masm(), receiver(), holder_reg, this->name(), holder(),
- IC::kLoadPropertyWithInterceptorOnly);
+ GenerateLoadPostInterceptor(it, holder_reg);
+}
- // Check if interceptor provided a value for property. If it's
- // the case, return immediately.
- Label interceptor_failed;
- __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
- __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
- frame_scope.GenerateLeaveFrame();
- __ Ret();
- __ bind(&interceptor_failed);
- __ pop(this->name());
- __ pop(holder_reg);
- if (must_preserve_receiver_reg) {
- __ pop(receiver());
- }
- // Leave the internal frame.
- }
- GenerateLoadPostInterceptor(holder_reg, name, lookup);
- } else { // !compile_followup_inline
- // Call the runtime system to load the interceptor.
- // Check that the maps haven't changed.
- PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
- holder());
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register
holder_reg) {
+ // Call the runtime system to load the interceptor.
+ DCHECK(holder()->HasNamedInterceptor());
+ DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+ PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+ holder());
- ExternalReference ref = ExternalReference(
- IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
- __ TailCallExternalReference(
- ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
- }
+ ExternalReference ref = ExternalReference(
+ IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+ __ TailCallExternalReference(
+ ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
}
=======================================
--- /branches/bleeding_edge/src/mips64/stub-cache-mips64.cc Wed Aug 6
15:11:09 2014 UTC
+++ /branches/bleeding_edge/src/mips64/stub-cache-mips64.cc Mon Aug 18
19:37:49 2014 UTC
@@ -798,88 +798,75 @@
}
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
- LookupResult*
lookup,
- Handle<Name> name) {
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+ LookupIterator* it, Register holder_reg) {
DCHECK(holder()->HasNamedInterceptor());
DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
- // So far the most popular follow ups for interceptor loads are FIELD
- // and CALLBACKS, so inline only them, other cases may be added
- // later.
- bool compile_followup_inline = false;
- if (lookup->IsFound() && lookup->IsCacheable()) {
- if (lookup->IsField()) {
- compile_followup_inline = true;
- } else if (lookup->type() == CALLBACKS &&
- lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> callback(
- ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
- compile_followup_inline =
- callback->getter() != NULL &&
- ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(),
callback,
- type());
+ // Compile the interceptor call, followed by inline code to load the
+ // property from further up the prototype chain if the call fails.
+ // Check that the maps haven't changed.
+ DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+
+ // Preserve the receiver register explicitly whenever it is different
from the
+ // holder and it is needed should the interceptor return without any
result.
+ // The ACCESSOR case needs the receiver to be passed into C++ code, the
FIELD
+ // case might cause a miss during the prototype check.
+ bool must_perform_prototype_check =
+ !holder().is_identical_to(it->GetHolder<JSObject>());
+ bool must_preserve_receiver_reg =
+ !receiver().is(holder_reg) &&
+ (it->property_kind() == LookupIterator::ACCESSOR ||
+ must_perform_prototype_check);
+
+ // Save necessary data before invoking an interceptor.
+ // Requires a frame to make GC aware of pushed pointers.
+ {
+ FrameScope frame_scope(masm(), StackFrame::INTERNAL);
+ if (must_preserve_receiver_reg) {
+ __ Push(receiver(), holder_reg, this->name());
+ } else {
+ __ Push(holder_reg, this->name());
}
- }
+ // Invoke an interceptor. Note: map checks from receiver to
+ // interceptor's holder has been compiled before (see a caller
+ // of this method).
+ CompileCallLoadPropertyWithInterceptor(
+ masm(), receiver(), holder_reg, this->name(), holder(),
+ IC::kLoadPropertyWithInterceptorOnly);
- if (compile_followup_inline) {
- // Compile the interceptor call, followed by inline code to load the
- // property from further up the prototype chain if the call fails.
- // Check that the maps haven't changed.
- DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+ // Check if interceptor provided a value for property. If it's
+ // the case, return immediately.
+ Label interceptor_failed;
+ __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
+ __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
+ frame_scope.GenerateLeaveFrame();
+ __ Ret();
- // Preserve the receiver register explicitly whenever it is different
from
- // the holder and it is needed should the interceptor return without
any
- // result. The CALLBACKS case needs the receiver to be passed into C++
code,
- // the FIELD case might cause a miss during the prototype check.
- bool must_perfrom_prototype_check = *holder() != lookup->holder();
- bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
- (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+ __ bind(&interceptor_failed);
+ if (must_preserve_receiver_reg) {
+ __ Pop(receiver(), holder_reg, this->name());
+ } else {
+ __ Pop(holder_reg, this->name());
+ }
+ // Leave the internal frame.
+ }
- // Save necessary data before invoking an interceptor.
- // Requires a frame to make GC aware of pushed pointers.
- {
- FrameScope frame_scope(masm(), StackFrame::INTERNAL);
- if (must_preserve_receiver_reg) {
- __ Push(receiver(), holder_reg, this->name());
- } else {
- __ Push(holder_reg, this->name());
- }
- // Invoke an interceptor. Note: map checks from receiver to
- // interceptor's holder has been compiled before (see a caller
- // of this method).
- CompileCallLoadPropertyWithInterceptor(
- masm(), receiver(), holder_reg, this->name(), holder(),
- IC::kLoadPropertyWithInterceptorOnly);
+ GenerateLoadPostInterceptor(it, holder_reg);
+}
- // Check if interceptor provided a value for property. If it's
- // the case, return immediately.
- Label interceptor_failed;
- __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
- __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
- frame_scope.GenerateLeaveFrame();
- __ Ret();
- __ bind(&interceptor_failed);
- __ pop(this->name());
- __ pop(holder_reg);
- if (must_preserve_receiver_reg) {
- __ pop(receiver());
- }
- // Leave the internal frame.
- }
- GenerateLoadPostInterceptor(holder_reg, name, lookup);
- } else { // !compile_followup_inline
- // Call the runtime system to load the interceptor.
- // Check that the maps haven't changed.
- PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
- holder());
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register
holder_reg) {
+ // Call the runtime system to load the interceptor.
+ DCHECK(holder()->HasNamedInterceptor());
+ DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+ PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+ holder());
- ExternalReference ref = ExternalReference(
- IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
- __ TailCallExternalReference(
- ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
- }
+ ExternalReference ref = ExternalReference(
+ IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+ __ TailCallExternalReference(
+ ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.