Revision: 23176
Author: [email protected]
Date: Tue Aug 19 04:56:54 2014 UTC
Log: X87: Use LookupIterator for CompileLoadInterceptor and delete
Object::Lookup
port r23168.
original commit message:
Use LookupIterator for CompileLoadInterceptor and delete Object::Lookup
BUG=
[email protected]
Review URL: https://codereview.chromium.org/481323002
Patch from Chunyang Dai <[email protected]>.
http://code.google.com/p/v8/source/detail?r=23176
Modified:
/branches/bleeding_edge/src/x87/stub-cache-x87.cc
=======================================
--- /branches/bleeding_edge/src/x87/stub-cache-x87.cc Fri Aug 8 12:38:20
2014 UTC
+++ /branches/bleeding_edge/src/x87/stub-cache-x87.cc Tue Aug 19 04:56:54
2014 UTC
@@ -778,102 +778,87 @@
}
-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()));
- 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()));
+ // 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);
- // 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);
+ // Save necessary data before invoking an interceptor.
+ // Requires a frame to make GC aware of pushed pointers.
+ {
+ FrameScope frame_scope(masm(), StackFrame::INTERNAL);
- // 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());
+ }
+ __ push(holder_reg);
+ __ push(this->name());
- if (must_preserve_receiver_reg) {
- __ push(receiver());
- }
- __ push(holder_reg);
- __ push(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);
+
+ // Check if interceptor provided a value for property. If it's
+ // the case, return immediately.
+ Label interceptor_failed;
+ __ cmp(eax, factory()->no_interceptor_result_sentinel());
+ __ j(equal, &interceptor_failed);
+ frame_scope.GenerateLeaveFrame();
+ __ ret(0);
- // 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);
+ // Clobber registers when generating debug-code to provoke errors.
+ __ bind(&interceptor_failed);
+ if (FLAG_debug_code) {
+ __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
+ __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
+ __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
+ }
- // Check if interceptor provided a value for property. If it's
- // the case, return immediately.
- Label interceptor_failed;
- __ cmp(eax, factory()->no_interceptor_result_sentinel());
- __ j(equal, &interceptor_failed);
- frame_scope.GenerateLeaveFrame();
- __ ret(0);
+ __ pop(this->name());
+ __ pop(holder_reg);
+ if (must_preserve_receiver_reg) {
+ __ pop(receiver());
+ }
- // Clobber registers when generating debug-code to provoke errors.
- __ bind(&interceptor_failed);
- if (FLAG_debug_code) {
- __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
- __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
- __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
- }
+ // Leave the internal frame.
+ }
- __ pop(this->name());
- __ pop(holder_reg);
- if (must_preserve_receiver_reg) {
- __ pop(receiver());
- }
+ GenerateLoadPostInterceptor(it, holder_reg);
+}
- // 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.
- __ pop(scratch2()); // save old return address
- PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
- holder());
- __ push(scratch2()); // restore old return address
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register
holder_reg) {
+ DCHECK(holder()->HasNamedInterceptor());
+ DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+ // Call the runtime system to load the interceptor.
+ __ pop(scratch2()); // save old return address
+ PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+ holder());
+ __ push(scratch2()); // restore old return address
- 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.