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

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

Powered by Google App Engine
This is Rietveld 408576698