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

Side by Side Diff: src/mips/stub-cache-mips.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 | « no previous file | src/mips64/stub-cache-mips64.cc » ('j') | 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_MIPS 7 #if V8_TARGET_ARCH_MIPS
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 __ li(getter_address_reg, Operand(ref)); 790 __ li(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_perform_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_perform_prototype_check);
817
818 // Save necessary data before invoking an interceptor.
819 // Requires a frame to make GC aware of pushed pointers.
820 {
821 FrameScope 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 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
839 frame_scope.GenerateLeaveFrame();
840 __ Ret();
841
842 __ bind(&interceptor_failed);
843 if (must_preserve_receiver_reg) {
844 __ Pop(receiver(), holder_reg, this->name());
845 } else {
846 __ Pop(holder_reg, this->name());
847 }
848 // Leave the internal frame.
819 } 849 }
820 850
821 if (compile_followup_inline) { 851 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 FrameScope 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 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
856 frame_scope.GenerateLeaveFrame();
857 __ Ret();
858
859 __ bind(&interceptor_failed);
860 __ pop(this->name());
861 __ pop(holder_reg);
862 if (must_preserve_receiver_reg) {
863 __ pop(receiver());
864 }
865 // Leave the internal frame.
866 }
867 GenerateLoadPostInterceptor(holder_reg, name, lookup);
868 } else { // !compile_followup_inline
869 // Call the runtime system to load the interceptor.
870 // Check that the maps haven't changed.
871 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
872 holder());
873
874 ExternalReference ref = ExternalReference(
875 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
876 __ TailCallExternalReference(
877 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
878 }
879 } 852 }
880 853
881 854
855 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
856 // Call the runtime system to load the interceptor.
857 DCHECK(holder()->HasNamedInterceptor());
858 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
859 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
860 holder());
861
862 ExternalReference ref = ExternalReference(
863 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
864 __ TailCallExternalReference(
865 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
866 }
867
868
882 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 869 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
883 Handle<JSObject> object, Handle<Name> name, 870 Handle<JSObject> object, Handle<Name> name,
884 Handle<ExecutableAccessorInfo> callback) { 871 Handle<ExecutableAccessorInfo> callback) {
885 Register holder_reg = Frontend(receiver(), name); 872 Register holder_reg = Frontend(receiver(), name);
886 873
887 __ Push(receiver(), holder_reg); // Receiver. 874 __ Push(receiver(), holder_reg); // Receiver.
888 __ li(at, Operand(callback)); // Callback info. 875 __ li(at, Operand(callback)); // Callback info.
889 __ push(at); 876 __ push(at);
890 __ li(at, Operand(name)); 877 __ li(at, Operand(name));
891 __ Push(at, value()); 878 __ Push(at, value());
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 1164
1178 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1165 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1179 } 1166 }
1180 1167
1181 1168
1182 #undef __ 1169 #undef __
1183 1170
1184 } } // namespace v8::internal 1171 } } // namespace v8::internal
1185 1172
1186 #endif // V8_TARGET_ARCH_MIPS 1173 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips64/stub-cache-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698