Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: src/arm64/stub-cache-arm64.cc

Issue 466283003: Use LookupIterator for CompileLoadInterceptor and delete Object::Lookup (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add ports Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 ApiFunction fun(getter_address); 749 ApiFunction fun(getter_address);
750 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 750 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
751 ExternalReference ref = ExternalReference(&fun, type, isolate()); 751 ExternalReference ref = ExternalReference(&fun, type, isolate());
752 __ Mov(getter_address_reg, ref); 752 __ Mov(getter_address_reg, ref);
753 753
754 CallApiGetterStub stub(isolate()); 754 CallApiGetterStub stub(isolate());
755 __ TailCallStub(&stub); 755 __ TailCallStub(&stub);
756 } 756 }
757 757
758 758
759 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg, 759 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
760 LookupResult* lookup, 760 LookupIterator* it, Register holder_reg) {
761 Handle<Name> name) {
762 DCHECK(!AreAliased(receiver(), this->name(), 761 DCHECK(!AreAliased(receiver(), this->name(),
763 scratch1(), scratch2(), scratch3())); 762 scratch1(), scratch2(), scratch3()));
764 DCHECK(holder()->HasNamedInterceptor()); 763 DCHECK(holder()->HasNamedInterceptor());
765 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 764 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
766 765
767 // So far the most popular follow ups for interceptor loads are FIELD 766 // Compile the interceptor call, followed by inline code to load the
768 // and CALLBACKS, so inline only them, other cases may be added later. 767 // property from further up the prototype chain if the call fails.
769 bool compile_followup_inline = false; 768 // Check that the maps haven't changed.
770 if (lookup->IsFound() && lookup->IsCacheable()) { 769 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
771 if (lookup->IsField()) { 770
772 compile_followup_inline = true; 771 // Preserve the receiver register explicitly whenever it is different from the
773 } else if (lookup->type() == CALLBACKS && 772 // holder and it is needed should the interceptor return without any result.
774 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 773 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
775 Handle<ExecutableAccessorInfo> callback( 774 // case might cause a miss during the prototype check.
776 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 775 bool must_perfrom_prototype_check =
777 compile_followup_inline = 776 !holder().is_identical_to(it->GetHolder<JSObject>());
778 callback->getter() != NULL && 777 bool must_preserve_receiver_reg =
779 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 778 !receiver().is(holder_reg) &&
780 type()); 779 (it->property_kind() == LookupIterator::ACCESSOR ||
780 must_perfrom_prototype_check);
781
782 // Save necessary data before invoking an interceptor.
783 // Requires a frame to make GC aware of pushed pointers.
784 {
785 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
786 if (must_preserve_receiver_reg) {
787 __ Push(receiver(), holder_reg, this->name());
788 } else {
789 __ Push(holder_reg, this->name());
781 } 790 }
791 // Invoke an interceptor. Note: map checks from receiver to
792 // interceptor's holder has been compiled before (see a caller
793 // of this method.)
794 CompileCallLoadPropertyWithInterceptor(
795 masm(), receiver(), holder_reg, this->name(), holder(),
796 IC::kLoadPropertyWithInterceptorOnly);
797
798 // Check if interceptor provided a value for property. If it's
799 // the case, return immediately.
800 Label interceptor_failed;
801 __ JumpIfRoot(x0, Heap::kNoInterceptorResultSentinelRootIndex,
802 &interceptor_failed);
803 frame_scope.GenerateLeaveFrame();
804 __ Ret();
805
806 __ Bind(&interceptor_failed);
807 if (must_preserve_receiver_reg) {
808 __ Pop(this->name(), holder_reg, receiver());
809 } else {
810 __ Pop(this->name(), holder_reg);
811 }
812 // Leave the internal frame.
782 } 813 }
783 814
784 if (compile_followup_inline) { 815 GenerateLoadPostInterceptor(it, holder_reg);
785 // Compile the interceptor call, followed by inline code to load the
786 // property from further up the prototype chain if the call fails.
787 // Check that the maps haven't changed.
788 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
789
790 // Preserve the receiver register explicitly whenever it is different from
791 // the holder and it is needed should the interceptor return without any
792 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
793 // the FIELD case might cause a miss during the prototype check.
794 bool must_perfrom_prototype_check = *holder() != lookup->holder();
795 bool must_preserve_receiver_reg = !receiver().Is(holder_reg) &&
796 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
797
798 // Save necessary data before invoking an interceptor.
799 // Requires a frame to make GC aware of pushed pointers.
800 {
801 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
802 if (must_preserve_receiver_reg) {
803 __ Push(receiver(), holder_reg, this->name());
804 } else {
805 __ Push(holder_reg, this->name());
806 }
807 // Invoke an interceptor. Note: map checks from receiver to
808 // interceptor's holder has been compiled before (see a caller
809 // of this method.)
810 CompileCallLoadPropertyWithInterceptor(
811 masm(), receiver(), holder_reg, this->name(), holder(),
812 IC::kLoadPropertyWithInterceptorOnly);
813
814 // Check if interceptor provided a value for property. If it's
815 // the case, return immediately.
816 Label interceptor_failed;
817 __ JumpIfRoot(x0,
818 Heap::kNoInterceptorResultSentinelRootIndex,
819 &interceptor_failed);
820 frame_scope.GenerateLeaveFrame();
821 __ Ret();
822
823 __ Bind(&interceptor_failed);
824 if (must_preserve_receiver_reg) {
825 __ Pop(this->name(), holder_reg, receiver());
826 } else {
827 __ Pop(this->name(), holder_reg);
828 }
829 // Leave the internal frame.
830 }
831 GenerateLoadPostInterceptor(holder_reg, name, lookup);
832 } else { // !compile_followup_inline
833 // Call the runtime system to load the interceptor.
834 // Check that the maps haven't changed.
835 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
836 holder());
837
838 ExternalReference ref =
839 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
840 isolate());
841 __ TailCallExternalReference(
842 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
843 }
844 } 816 }
845 817
846 818
819 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
820 // Call the runtime system to load the interceptor.
821 DCHECK(holder()->HasNamedInterceptor());
822 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
823 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
824 holder());
825
826 ExternalReference ref = ExternalReference(
827 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
828 __ TailCallExternalReference(
829 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
830 }
831
832
847 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 833 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
848 Handle<JSObject> object, Handle<Name> name, 834 Handle<JSObject> object, Handle<Name> name,
849 Handle<ExecutableAccessorInfo> callback) { 835 Handle<ExecutableAccessorInfo> callback) {
850 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback"); 836 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
851 Register holder_reg = Frontend(receiver(), name); 837 Register holder_reg = Frontend(receiver(), name);
852 838
853 // Stub never generated for non-global objects that require access checks. 839 // Stub never generated for non-global objects that require access checks.
854 DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded()); 840 DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded());
855 841
856 // receiver() and holder_reg can alias. 842 // receiver() and holder_reg can alias.
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 1132
1147 // Miss case, call the runtime. 1133 // Miss case, call the runtime.
1148 __ Bind(&miss); 1134 __ Bind(&miss);
1149 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1135 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1150 } 1136 }
1151 1137
1152 1138
1153 } } // namespace v8::internal 1139 } } // namespace v8::internal
1154 1140
1155 #endif // V8_TARGET_ARCH_ARM64 1141 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698