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

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

Issue 473243003: MIPS: Use LookupIterator for CompileLoadInterceptor and delete Object::Lookup. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 | « src/mips/stub-cache-mips.cc ('k') | no next file » | no next file with comments »
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_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
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 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 ApiFunction fun(getter_address); 791 ApiFunction fun(getter_address);
792 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 792 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
793 ExternalReference ref = ExternalReference(&fun, type, isolate()); 793 ExternalReference ref = ExternalReference(&fun, type, isolate());
794 __ li(getter_address_reg, Operand(ref)); 794 __ li(getter_address_reg, Operand(ref));
795 795
796 CallApiGetterStub stub(isolate()); 796 CallApiGetterStub stub(isolate());
797 __ TailCallStub(&stub); 797 __ TailCallStub(&stub);
798 } 798 }
799 799
800 800
801 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg, 801 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
802 LookupResult* lookup, 802 LookupIterator* it, Register holder_reg) {
803 Handle<Name> name) {
804 DCHECK(holder()->HasNamedInterceptor()); 803 DCHECK(holder()->HasNamedInterceptor());
805 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 804 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
806 805
807 // So far the most popular follow ups for interceptor loads are FIELD 806 // Compile the interceptor call, followed by inline code to load the
808 // and CALLBACKS, so inline only them, other cases may be added 807 // property from further up the prototype chain if the call fails.
809 // later. 808 // Check that the maps haven't changed.
810 bool compile_followup_inline = false; 809 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
811 if (lookup->IsFound() && lookup->IsCacheable()) { 810
812 if (lookup->IsField()) { 811 // Preserve the receiver register explicitly whenever it is different from the
813 compile_followup_inline = true; 812 // holder and it is needed should the interceptor return without any result.
814 } else if (lookup->type() == CALLBACKS && 813 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
815 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 814 // case might cause a miss during the prototype check.
816 Handle<ExecutableAccessorInfo> callback( 815 bool must_perform_prototype_check =
817 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 816 !holder().is_identical_to(it->GetHolder<JSObject>());
818 compile_followup_inline = 817 bool must_preserve_receiver_reg =
819 callback->getter() != NULL && 818 !receiver().is(holder_reg) &&
820 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 819 (it->property_kind() == LookupIterator::ACCESSOR ||
821 type()); 820 must_perform_prototype_check);
821
822 // Save necessary data before invoking an interceptor.
823 // Requires a frame to make GC aware of pushed pointers.
824 {
825 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
826 if (must_preserve_receiver_reg) {
827 __ Push(receiver(), holder_reg, this->name());
828 } else {
829 __ Push(holder_reg, this->name());
822 } 830 }
831 // Invoke an interceptor. Note: map checks from receiver to
832 // interceptor's holder has been compiled before (see a caller
833 // of this method).
834 CompileCallLoadPropertyWithInterceptor(
835 masm(), receiver(), holder_reg, this->name(), holder(),
836 IC::kLoadPropertyWithInterceptorOnly);
837
838 // Check if interceptor provided a value for property. If it's
839 // the case, return immediately.
840 Label interceptor_failed;
841 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
842 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
843 frame_scope.GenerateLeaveFrame();
844 __ Ret();
845
846 __ bind(&interceptor_failed);
847 if (must_preserve_receiver_reg) {
848 __ Pop(receiver(), holder_reg, this->name());
849 } else {
850 __ Pop(holder_reg, this->name());
851 }
852 // Leave the internal frame.
823 } 853 }
824 854
825 if (compile_followup_inline) { 855 GenerateLoadPostInterceptor(it, holder_reg);
826 // Compile the interceptor call, followed by inline code to load the
827 // property from further up the prototype chain if the call fails.
828 // Check that the maps haven't changed.
829 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
830
831 // Preserve the receiver register explicitly whenever it is different from
832 // the holder and it is needed should the interceptor return without any
833 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
834 // the FIELD case might cause a miss during the prototype check.
835 bool must_perfrom_prototype_check = *holder() != lookup->holder();
836 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
837 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
838
839 // Save necessary data before invoking an interceptor.
840 // Requires a frame to make GC aware of pushed pointers.
841 {
842 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
843 if (must_preserve_receiver_reg) {
844 __ Push(receiver(), holder_reg, this->name());
845 } else {
846 __ Push(holder_reg, this->name());
847 }
848 // Invoke an interceptor. Note: map checks from receiver to
849 // interceptor's holder has been compiled before (see a caller
850 // of this method).
851 CompileCallLoadPropertyWithInterceptor(
852 masm(), receiver(), holder_reg, this->name(), holder(),
853 IC::kLoadPropertyWithInterceptorOnly);
854
855 // Check if interceptor provided a value for property. If it's
856 // the case, return immediately.
857 Label interceptor_failed;
858 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
859 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
860 frame_scope.GenerateLeaveFrame();
861 __ Ret();
862
863 __ bind(&interceptor_failed);
864 __ pop(this->name());
865 __ pop(holder_reg);
866 if (must_preserve_receiver_reg) {
867 __ pop(receiver());
868 }
869 // Leave the internal frame.
870 }
871 GenerateLoadPostInterceptor(holder_reg, name, lookup);
872 } else { // !compile_followup_inline
873 // Call the runtime system to load the interceptor.
874 // Check that the maps haven't changed.
875 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
876 holder());
877
878 ExternalReference ref = ExternalReference(
879 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
880 __ TailCallExternalReference(
881 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
882 }
883 } 856 }
884 857
885 858
859 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
860 // Call the runtime system to load the interceptor.
861 DCHECK(holder()->HasNamedInterceptor());
862 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
863 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
864 holder());
865
866 ExternalReference ref = ExternalReference(
867 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
868 __ TailCallExternalReference(
869 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
870 }
871
872
886 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 873 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
887 Handle<JSObject> object, Handle<Name> name, 874 Handle<JSObject> object, Handle<Name> name,
888 Handle<ExecutableAccessorInfo> callback) { 875 Handle<ExecutableAccessorInfo> callback) {
889 Register holder_reg = Frontend(receiver(), name); 876 Register holder_reg = Frontend(receiver(), name);
890 877
891 __ Push(receiver(), holder_reg); // Receiver. 878 __ Push(receiver(), holder_reg); // Receiver.
892 __ li(at, Operand(callback)); // Callback info. 879 __ li(at, Operand(callback)); // Callback info.
893 __ push(at); 880 __ push(at);
894 __ li(at, Operand(name)); 881 __ li(at, Operand(name));
895 __ Push(at, value()); 882 __ Push(at, value());
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 1169
1183 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1170 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1184 } 1171 }
1185 1172
1186 1173
1187 #undef __ 1174 #undef __
1188 1175
1189 } } // namespace v8::internal 1176 } } // namespace v8::internal
1190 1177
1191 #endif // V8_TARGET_ARCH_MIPS64 1178 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/stub-cache-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698