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

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

Issue 481323002: X87: Use LookupIterator for CompileLoadInterceptor and delete Object::Lookup (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@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
« no previous file with comments | « no previous file | 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_X87 7 #if V8_TARGET_ARCH_X87
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 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 } 771 }
772 772
773 773
774 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 774 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
775 // Return the constant value. 775 // Return the constant value.
776 __ LoadObject(eax, value); 776 __ LoadObject(eax, value);
777 __ ret(0); 777 __ ret(0);
778 } 778 }
779 779
780 780
781 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg, 781 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
782 LookupResult* lookup, 782 LookupIterator* it, Register holder_reg) {
783 Handle<Name> name) {
784 DCHECK(holder()->HasNamedInterceptor()); 783 DCHECK(holder()->HasNamedInterceptor());
785 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 784 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
786 785
787 // So far the most popular follow ups for interceptor loads are FIELD 786 // Compile the interceptor call, followed by inline code to load the
788 // and CALLBACKS, so inline only them, other cases may be added 787 // property from further up the prototype chain if the call fails.
789 // later. 788 // Check that the maps haven't changed.
790 bool compile_followup_inline = false; 789 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
791 if (lookup->IsFound() && lookup->IsCacheable()) { 790
792 if (lookup->IsField()) { 791 // Preserve the receiver register explicitly whenever it is different from the
793 compile_followup_inline = true; 792 // holder and it is needed should the interceptor return without any result.
794 } else if (lookup->type() == CALLBACKS && 793 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
795 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 794 // case might cause a miss during the prototype check.
796 Handle<ExecutableAccessorInfo> callback( 795 bool must_perform_prototype_check =
797 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 796 !holder().is_identical_to(it->GetHolder<JSObject>());
798 compile_followup_inline = 797 bool must_preserve_receiver_reg =
799 callback->getter() != NULL && 798 !receiver().is(holder_reg) &&
800 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 799 (it->property_kind() == LookupIterator::ACCESSOR ||
801 type()); 800 must_perform_prototype_check);
801
802 // Save necessary data before invoking an interceptor.
803 // Requires a frame to make GC aware of pushed pointers.
804 {
805 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
806
807 if (must_preserve_receiver_reg) {
808 __ push(receiver());
802 } 809 }
810 __ push(holder_reg);
811 __ push(this->name());
812
813 // Invoke an interceptor. Note: map checks from receiver to
814 // interceptor's holder has been compiled before (see a caller
815 // of this method.)
816 CompileCallLoadPropertyWithInterceptor(
817 masm(), receiver(), holder_reg, this->name(), holder(),
818 IC::kLoadPropertyWithInterceptorOnly);
819
820 // Check if interceptor provided a value for property. If it's
821 // the case, return immediately.
822 Label interceptor_failed;
823 __ cmp(eax, factory()->no_interceptor_result_sentinel());
824 __ j(equal, &interceptor_failed);
825 frame_scope.GenerateLeaveFrame();
826 __ ret(0);
827
828 // Clobber registers when generating debug-code to provoke errors.
829 __ bind(&interceptor_failed);
830 if (FLAG_debug_code) {
831 __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
832 __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
833 __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
834 }
835
836 __ pop(this->name());
837 __ pop(holder_reg);
838 if (must_preserve_receiver_reg) {
839 __ pop(receiver());
840 }
841
842 // Leave the internal frame.
803 } 843 }
804 844
805 if (compile_followup_inline) { 845 GenerateLoadPostInterceptor(it, holder_reg);
806 // Compile the interceptor call, followed by inline code to load the
807 // property from further up the prototype chain if the call fails.
808 // Check that the maps haven't changed.
809 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
810
811 // Preserve the receiver register explicitly whenever it is different from
812 // the holder and it is needed should the interceptor return without any
813 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
814 // the FIELD case might cause a miss during the prototype check.
815 bool must_perfrom_prototype_check = *holder() != lookup->holder();
816 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
817 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
818
819 // Save necessary data before invoking an interceptor.
820 // Requires a frame to make GC aware of pushed pointers.
821 {
822 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
823
824 if (must_preserve_receiver_reg) {
825 __ push(receiver());
826 }
827 __ push(holder_reg);
828 __ push(this->name());
829
830 // Invoke an interceptor. Note: map checks from receiver to
831 // interceptor's holder has been compiled before (see a caller
832 // of this method.)
833 CompileCallLoadPropertyWithInterceptor(
834 masm(), receiver(), holder_reg, this->name(), holder(),
835 IC::kLoadPropertyWithInterceptorOnly);
836
837 // Check if interceptor provided a value for property. If it's
838 // the case, return immediately.
839 Label interceptor_failed;
840 __ cmp(eax, factory()->no_interceptor_result_sentinel());
841 __ j(equal, &interceptor_failed);
842 frame_scope.GenerateLeaveFrame();
843 __ ret(0);
844
845 // Clobber registers when generating debug-code to provoke errors.
846 __ bind(&interceptor_failed);
847 if (FLAG_debug_code) {
848 __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
849 __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
850 __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
851 }
852
853 __ pop(this->name());
854 __ pop(holder_reg);
855 if (must_preserve_receiver_reg) {
856 __ pop(receiver());
857 }
858
859 // Leave the internal frame.
860 }
861
862 GenerateLoadPostInterceptor(holder_reg, name, lookup);
863 } else { // !compile_followup_inline
864 // Call the runtime system to load the interceptor.
865 // Check that the maps haven't changed.
866 __ pop(scratch2()); // save old return address
867 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
868 holder());
869 __ push(scratch2()); // restore old return address
870
871 ExternalReference ref =
872 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
873 isolate());
874 __ TailCallExternalReference(
875 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
876 }
877 } 846 }
878 847
879 848
849 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
850 DCHECK(holder()->HasNamedInterceptor());
851 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
852 // Call the runtime system to load the interceptor.
853 __ pop(scratch2()); // save old return address
854 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
855 holder());
856 __ push(scratch2()); // restore old return address
857
858 ExternalReference ref = ExternalReference(
859 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
860 __ TailCallExternalReference(
861 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
862 }
863
864
880 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 865 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
881 Handle<JSObject> object, Handle<Name> name, 866 Handle<JSObject> object, Handle<Name> name,
882 Handle<ExecutableAccessorInfo> callback) { 867 Handle<ExecutableAccessorInfo> callback) {
883 Register holder_reg = Frontend(receiver(), name); 868 Register holder_reg = Frontend(receiver(), name);
884 869
885 __ pop(scratch1()); // remove the return address 870 __ pop(scratch1()); // remove the return address
886 __ push(receiver()); 871 __ push(receiver());
887 __ push(holder_reg); 872 __ push(holder_reg);
888 __ Push(callback); 873 __ Push(callback);
889 __ Push(name); 874 __ Push(name);
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 // ----------------------------------- 1177 // -----------------------------------
1193 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1178 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1194 } 1179 }
1195 1180
1196 1181
1197 #undef __ 1182 #undef __
1198 1183
1199 } } // namespace v8::internal 1184 } } // namespace v8::internal
1200 1185
1201 #endif // V8_TARGET_ARCH_X87 1186 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698