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

Side by Side Diff: src/arm/stub-cache-arm.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
« no previous file with comments | « no previous file | src/arm64/stub-cache-arm64.cc » ('j') | src/ia32/stub-cache-ia32.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_ARM 7 #if V8_TARGET_ARCH_ARM
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 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 ApiFunction fun(getter_address); 787 ApiFunction fun(getter_address);
788 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 788 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
789 ExternalReference ref = ExternalReference(&fun, type, isolate()); 789 ExternalReference ref = ExternalReference(&fun, type, isolate());
790 __ mov(getter_address_reg, Operand(ref)); 790 __ mov(getter_address_reg, Operand(ref));
791 791
792 CallApiGetterStub stub(isolate()); 792 CallApiGetterStub stub(isolate());
793 __ TailCallStub(&stub); 793 __ TailCallStub(&stub);
794 } 794 }
795 795
796 796
797 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg, 797 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
798 LookupResult* lookup, 798 LookupIterator* it, Register holder_reg) {
799 Handle<Name> name) {
800 DCHECK(holder()->HasNamedInterceptor()); 799 DCHECK(holder()->HasNamedInterceptor());
801 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 800 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
802 801
803 // So far the most popular follow ups for interceptor loads are FIELD 802 // Compile the interceptor call, followed by inline code to load the
804 // and CALLBACKS, so inline only them, other cases may be added 803 // property from further up the prototype chain if the call fails.
805 // later. 804 // Check that the maps haven't changed.
806 bool compile_followup_inline = false; 805 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
807 if (lookup->IsFound() && lookup->IsCacheable()) { 806
808 if (lookup->IsField()) { 807 // Preserve the receiver register explicitly whenever it is different from the
809 compile_followup_inline = true; 808 // holder and it is needed should the interceptor return without any result.
810 } else if (lookup->type() == CALLBACKS && 809 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
811 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 810 // case might cause a miss during the prototype check.
812 Handle<ExecutableAccessorInfo> callback( 811 bool must_perfrom_prototype_check =
813 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 812 !holder().is_identical_to(it->GetHolder<JSObject>());
814 compile_followup_inline = 813 bool must_preserve_receiver_reg =
815 callback->getter() != NULL && 814 !receiver().is(holder_reg) &&
816 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 815 (it->property_kind() == LookupIterator::ACCESSOR ||
817 type()); 816 must_perfrom_prototype_check);
817
818 // Save necessary data before invoking an interceptor.
819 // Requires a frame to make GC aware of pushed pointers.
820 {
821 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
822 if (must_preserve_receiver_reg) {
823 __ Push(receiver(), holder_reg, this->name());
824 } else {
825 __ Push(holder_reg, this->name());
818 } 826 }
827 // Invoke an interceptor. Note: map checks from receiver to
828 // interceptor's holder has been compiled before (see a caller
829 // of this method.)
830 CompileCallLoadPropertyWithInterceptor(
831 masm(), receiver(), holder_reg, this->name(), holder(),
832 IC::kLoadPropertyWithInterceptorOnly);
833
834 // Check if interceptor provided a value for property. If it's
835 // the case, return immediately.
836 Label interceptor_failed;
837 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
838 __ cmp(r0, scratch1());
839 __ b(eq, &interceptor_failed);
840 frame_scope.GenerateLeaveFrame();
841 __ Ret();
842
843 __ bind(&interceptor_failed);
844 __ pop(this->name());
845 __ pop(holder_reg);
846 if (must_preserve_receiver_reg) {
847 __ pop(receiver());
848 }
849 // Leave the internal frame.
819 } 850 }
820 851
821 if (compile_followup_inline) { 852 GenerateLoadPostInterceptor(it, holder_reg);
822 // Compile the interceptor call, followed by inline code to load the
823 // property from further up the prototype chain if the call fails.
824 // Check that the maps haven't changed.
825 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
826
827 // Preserve the receiver register explicitly whenever it is different from
828 // the holder and it is needed should the interceptor return without any
829 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
830 // the FIELD case might cause a miss during the prototype check.
831 bool must_perfrom_prototype_check = *holder() != lookup->holder();
832 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
833 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
834
835 // Save necessary data before invoking an interceptor.
836 // Requires a frame to make GC aware of pushed pointers.
837 {
838 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
839 if (must_preserve_receiver_reg) {
840 __ Push(receiver(), holder_reg, this->name());
841 } else {
842 __ Push(holder_reg, this->name());
843 }
844 // Invoke an interceptor. Note: map checks from receiver to
845 // interceptor's holder has been compiled before (see a caller
846 // of this method.)
847 CompileCallLoadPropertyWithInterceptor(
848 masm(), receiver(), holder_reg, this->name(), holder(),
849 IC::kLoadPropertyWithInterceptorOnly);
850
851 // Check if interceptor provided a value for property. If it's
852 // the case, return immediately.
853 Label interceptor_failed;
854 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
855 __ cmp(r0, scratch1());
856 __ b(eq, &interceptor_failed);
857 frame_scope.GenerateLeaveFrame();
858 __ Ret();
859
860 __ bind(&interceptor_failed);
861 __ pop(this->name());
862 __ pop(holder_reg);
863 if (must_preserve_receiver_reg) {
864 __ pop(receiver());
865 }
866 // Leave the internal frame.
867 }
868
869 GenerateLoadPostInterceptor(holder_reg, name, lookup);
870 } else { // !compile_followup_inline
871 // Call the runtime system to load the interceptor.
872 // Check that the maps haven't changed.
873 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
874 holder());
875
876 ExternalReference ref =
877 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
878 isolate());
879 __ TailCallExternalReference(
880 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
881 }
882 } 853 }
883 854
884 855
856 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
857 // Call the runtime system to load the interceptor.
858 DCHECK(holder()->HasNamedInterceptor());
859 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
860 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
861 holder());
862
863 ExternalReference ref = ExternalReference(
864 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
865 __ TailCallExternalReference(
866 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
867 }
868
869
885 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 870 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
886 Handle<JSObject> object, Handle<Name> name, 871 Handle<JSObject> object, Handle<Name> name,
887 Handle<ExecutableAccessorInfo> callback) { 872 Handle<ExecutableAccessorInfo> callback) {
888 Register holder_reg = Frontend(receiver(), name); 873 Register holder_reg = Frontend(receiver(), name);
889 874
890 __ push(receiver()); // receiver 875 __ push(receiver()); // receiver
891 __ push(holder_reg); 876 __ push(holder_reg);
892 __ mov(ip, Operand(callback)); // callback info 877 __ mov(ip, Operand(callback)); // callback info
893 __ push(ip); 878 __ push(ip);
894 __ mov(ip, Operand(name)); 879 __ mov(ip, Operand(name));
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 1163
1179 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1164 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1180 } 1165 }
1181 1166
1182 1167
1183 #undef __ 1168 #undef __
1184 1169
1185 } } // namespace v8::internal 1170 } } // namespace v8::internal
1186 1171
1187 #endif // V8_TARGET_ARCH_ARM 1172 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/stub-cache-arm64.cc » ('j') | src/ia32/stub-cache-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698