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/ia32/stub-cache-ia32.cc

Issue 596096: Refactoring various pieces of post interceptor caching. (Closed)
Patch Set: Fix incorrect indentation Created 10 years, 10 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
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 145
146 // Probe the secondary table. 146 // Probe the secondary table.
147 ProbeTable(masm, flags, kSecondary, name, scratch, extra); 147 ProbeTable(masm, flags, kSecondary, name, scratch, extra);
148 148
149 // Cache miss: Fall-through and let caller handle the miss by 149 // Cache miss: Fall-through and let caller handle the miss by
150 // entering the runtime system. 150 // entering the runtime system.
151 __ bind(&miss); 151 __ bind(&miss);
152 } 152 }
153 153
154 154
155 static void PushInterceptorArguments(MacroAssembler* masm,
156 Register receiver,
157 Register holder,
158 Register name,
159 JSObject* holder_obj) {
160 __ push(receiver);
161 __ push(holder);
162 __ push(name);
163 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
164 ASSERT(!Heap::InNewSpace(interceptor));
165 __ mov(receiver, Immediate(Handle<Object>(interceptor)));
166 __ push(receiver);
167 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
168 }
169
170
171 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 155 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
172 int index, 156 int index,
173 Register prototype) { 157 Register prototype) {
174 // Load the global or builtins object from the current context. 158 // Load the global or builtins object from the current context.
175 __ mov(prototype, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 159 __ mov(prototype, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
176 // Load the global context from the global or builtins object. 160 // Load the global context from the global or builtins object.
177 __ mov(prototype, 161 __ mov(prototype,
178 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); 162 FieldOperand(prototype, GlobalObject::kGlobalContextOffset));
179 // Load the function from the global context. 163 // Load the function from the global context.
180 __ mov(prototype, Operand(prototype, Context::SlotOffset(index))); 164 __ mov(prototype, Operand(prototype, Context::SlotOffset(index)));
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 __ mov(dst, FieldOperand(src, offset)); 264 __ mov(dst, FieldOperand(src, offset));
281 } else { 265 } else {
282 // Calculate the offset into the properties array. 266 // Calculate the offset into the properties array.
283 int offset = index * kPointerSize + FixedArray::kHeaderSize; 267 int offset = index * kPointerSize + FixedArray::kHeaderSize;
284 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 268 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
285 __ mov(dst, FieldOperand(dst, offset)); 269 __ mov(dst, FieldOperand(dst, offset));
286 } 270 }
287 } 271 }
288 272
289 273
274 static void PushInterceptorArguments(MacroAssembler* masm,
275 Register receiver,
276 Register holder,
277 Register name,
278 JSObject* holder_obj) {
279 __ push(receiver);
280 __ push(holder);
281 __ push(name);
282 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
283 ASSERT(!Heap::InNewSpace(interceptor));
284 __ mov(receiver, Immediate(Handle<Object>(interceptor)));
285 __ push(receiver);
286 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
287 }
288
289
290 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 290 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
291 Register receiver, 291 Register receiver,
292 Register holder, 292 Register holder,
293 Register name, 293 Register name,
294 JSObject* holder_obj) { 294 JSObject* holder_obj) {
295 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 295 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
296 296 __ CallExternalReference(
297 ExternalReference ref = 297 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)),
298 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); 298 5);
299 __ mov(eax, Immediate(5));
300 __ mov(ebx, Immediate(ref));
301
302 CEntryStub stub(1);
303 __ CallStub(&stub);
304 } 299 }
305 300
306 301
307 template <class Compiler> 302 template <class Compiler>
308 static void CompileLoadInterceptor(Compiler* compiler, 303 static void CompileLoadInterceptor(Compiler* compiler,
309 StubCompiler* stub_compiler, 304 StubCompiler* stub_compiler,
310 MacroAssembler* masm, 305 MacroAssembler* masm,
311 JSObject* object, 306 JSObject* object,
312 JSObject* holder, 307 JSObject* holder,
313 String* name, 308 String* name,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 void CompileCacheable(MacroAssembler* masm, 352 void CompileCacheable(MacroAssembler* masm,
358 StubCompiler* stub_compiler, 353 StubCompiler* stub_compiler,
359 Register receiver, 354 Register receiver,
360 Register holder, 355 Register holder,
361 Register scratch1, 356 Register scratch1,
362 Register scratch2, 357 Register scratch2,
363 JSObject* holder_obj, 358 JSObject* holder_obj,
364 LookupResult* lookup, 359 LookupResult* lookup,
365 String* name, 360 String* name,
366 Label* miss_label) { 361 Label* miss_label) {
367 AccessorInfo* callback = 0; 362 AccessorInfo* callback = NULL;
368 bool optimize = false; 363 bool optimize = false;
369 // So far the most popular follow ups for interceptor loads are FIELD 364 // So far the most popular follow ups for interceptor loads are FIELD
370 // and CALLBACKS, so inline only them, other cases may be added 365 // and CALLBACKS, so inline only them, other cases may be added
371 // later. 366 // later.
372 if (lookup->type() == FIELD) { 367 if (lookup->type() == FIELD) {
373 optimize = true; 368 optimize = true;
374 } else if (lookup->type() == CALLBACKS) { 369 } else if (lookup->type() == CALLBACKS) {
375 Object* callback_object = lookup->GetCallbackObject(); 370 Object* callback_object = lookup->GetCallbackObject();
376 if (callback_object->IsAccessorInfo()) { 371 if (callback_object->IsAccessorInfo()) {
377 callback = AccessorInfo::cast(callback_object); 372 callback = AccessorInfo::cast(callback_object);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 } 671 }
677 672
678 673
679 class CallInterceptorCompiler BASE_EMBEDDED { 674 class CallInterceptorCompiler BASE_EMBEDDED {
680 public: 675 public:
681 CallInterceptorCompiler(StubCompiler* stub_compiler, 676 CallInterceptorCompiler(StubCompiler* stub_compiler,
682 const ParameterCount& arguments, 677 const ParameterCount& arguments,
683 Register name) 678 Register name)
684 : stub_compiler_(stub_compiler), 679 : stub_compiler_(stub_compiler),
685 arguments_(arguments), 680 arguments_(arguments),
686 argc_(arguments.immediate()),
687 name_(name) {} 681 name_(name) {}
688 682
689 void Compile(MacroAssembler* masm, 683 void Compile(MacroAssembler* masm,
690 JSObject* object, 684 JSObject* object,
691 JSObject* holder, 685 JSObject* holder,
692 String* name, 686 String* name,
693 LookupResult* lookup, 687 LookupResult* lookup,
694 Register receiver, 688 Register receiver,
695 Register scratch1, 689 Register scratch1,
696 Register scratch2, 690 Register scratch2,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 JSObject* object, 727 JSObject* object,
734 Register receiver, 728 Register receiver,
735 Register scratch1, 729 Register scratch1,
736 Register scratch2, 730 Register scratch2,
737 JSObject* holder_obj, 731 JSObject* holder_obj,
738 LookupResult* lookup, 732 LookupResult* lookup,
739 String* name, 733 String* name,
740 const CallOptimization& optimization, 734 const CallOptimization& optimization,
741 Label* miss_label) { 735 Label* miss_label) {
742 ASSERT(optimization.is_constant_call()); 736 ASSERT(optimization.is_constant_call());
737 ASSERT(!lookup->holder()->IsGlobalObject());
743 738
744 int depth1 = kInvalidProtoDepth; 739 int depth1 = kInvalidProtoDepth;
745 int depth2 = kInvalidProtoDepth; 740 int depth2 = kInvalidProtoDepth;
746 bool can_do_fast_api_call = false; 741 bool can_do_fast_api_call = false;
747 if (optimization.is_simple_api_call() && 742 if (optimization.is_simple_api_call() &&
748 !lookup->holder()->IsGlobalObject()) { 743 !lookup->holder()->IsGlobalObject()) {
749 depth1 = optimization.GetPrototypeDepthOfExpectedType(object, holder_obj); 744 depth1 = optimization.GetPrototypeDepthOfExpectedType(object, holder_obj);
750 if (depth1 == kInvalidProtoDepth) { 745 if (depth1 == kInvalidProtoDepth) {
751 depth2 = optimization.GetPrototypeDepthOfExpectedType(holder_obj, 746 depth2 = optimization.GetPrototypeDepthOfExpectedType(holder_obj,
752 lookup->holder()); 747 lookup->holder());
(...skipping 20 matching lines...) Expand all
773 LoadWithInterceptor(masm, receiver, holder, holder_obj, &regular_invoke); 768 LoadWithInterceptor(masm, receiver, holder, holder_obj, &regular_invoke);
774 769
775 // Generate code for the failed interceptor case. 770 // Generate code for the failed interceptor case.
776 771
777 // Check the lookup is still valid. 772 // Check the lookup is still valid.
778 stub_compiler_->CheckPrototypes(holder_obj, receiver, 773 stub_compiler_->CheckPrototypes(holder_obj, receiver,
779 lookup->holder(), 774 lookup->holder(),
780 scratch1, scratch2, name, 775 scratch1, scratch2, name,
781 depth2, miss); 776 depth2, miss);
782 777
783 if (lookup->holder()->IsGlobalObject()) { 778 if (can_do_fast_api_call) {
784 ASSERT(!can_do_fast_api_call); 779 GenerateFastApiCall(masm, optimization, arguments_.immediate());
785 __ mov(edx, Operand(esp, (argc_ + 1) * kPointerSize)); 780 } else {
786 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 781 // Jump to the cached code (tail call).
787 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edx); 782 __ InvokeFunction(optimization.constant_function(), arguments_);
788 } 783 }
789 784
790 if (can_do_fast_api_call) { 785 if (can_do_fast_api_call) {
791 GenerateFastApiCall(masm, optimization, argc_);
792 } else {
793 // Get the function and setup the context.
794 JSFunction* function = optimization.constant_function();
795 __ mov(edi, Immediate(Handle<JSFunction>(function)));
796 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
797
798 // Jump to the cached code (tail call).
799 ASSERT(function->is_compiled());
800 Handle<Code> code(function->code());
801 ParameterCount expected(function->shared()->formal_parameter_count());
802 __ InvokeCode(code, expected, arguments_,
803 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
804 }
805
806 if (can_do_fast_api_call) {
807 __ bind(&miss_cleanup); 786 __ bind(&miss_cleanup);
808 FreeSpaceForFastApiCall(masm, scratch1); 787 FreeSpaceForFastApiCall(masm, scratch1);
809 __ jmp(miss_label); 788 __ jmp(miss_label);
810 } 789 }
811 790
812 __ bind(&regular_invoke); 791 __ bind(&regular_invoke);
813 if (can_do_fast_api_call) { 792 if (can_do_fast_api_call) {
814 FreeSpaceForFastApiCall(masm, scratch1); 793 FreeSpaceForFastApiCall(masm, scratch1);
815 } 794 }
816 } 795 }
(...skipping 14 matching lines...) Expand all
831 __ EnterInternalFrame(); 810 __ EnterInternalFrame();
832 // Save the name_ register across the call. 811 // Save the name_ register across the call.
833 __ push(name_); 812 __ push(name_);
834 813
835 PushInterceptorArguments(masm, 814 PushInterceptorArguments(masm,
836 receiver, 815 receiver,
837 holder, 816 holder,
838 name_, 817 name_,
839 holder_obj); 818 holder_obj);
840 819
841 ExternalReference ref = ExternalReference( 820 __ CallExternalReference(
842 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)); 821 ExternalReference(
843 __ mov(eax, Immediate(5)); 822 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
844 __ mov(ebx, Immediate(ref)); 823 5);
845
846 CEntryStub stub(1);
847 __ CallStub(&stub);
848 824
849 // Restore the name_ register. 825 // Restore the name_ register.
850 __ pop(name_); 826 __ pop(name_);
851 __ LeaveInternalFrame(); 827 __ LeaveInternalFrame();
852 } 828 }
853 829
854 void LoadWithInterceptor(MacroAssembler* masm, 830 void LoadWithInterceptor(MacroAssembler* masm,
855 Register receiver, 831 Register receiver,
856 Register holder, 832 Register holder,
857 JSObject* holder_obj, 833 JSObject* holder_obj,
(...skipping 11 matching lines...) Expand all
869 __ pop(name_); // Restore the name. 845 __ pop(name_); // Restore the name.
870 __ pop(receiver); // Restore the holder. 846 __ pop(receiver); // Restore the holder.
871 __ LeaveInternalFrame(); 847 __ LeaveInternalFrame();
872 848
873 __ cmp(eax, Factory::no_interceptor_result_sentinel()); 849 __ cmp(eax, Factory::no_interceptor_result_sentinel());
874 __ j(not_equal, interceptor_succeeded); 850 __ j(not_equal, interceptor_succeeded);
875 } 851 }
876 852
877 StubCompiler* stub_compiler_; 853 StubCompiler* stub_compiler_;
878 const ParameterCount& arguments_; 854 const ParameterCount& arguments_;
879 const int argc_;
880 Register name_; 855 Register name_;
881 }; 856 };
882 857
883 858
884 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 859 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
885 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 860 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
886 Code* code = NULL; 861 Code* code = NULL;
887 if (kind == Code::LOAD_IC) { 862 if (kind == Code::LOAD_IC) {
888 code = Builtins::builtin(Builtins::LoadIC_Miss); 863 code = Builtins::builtin(Builtins::LoadIC_Miss);
889 } else { 864 } else {
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 __ j(not_equal, &miss, not_taken); 1346 __ j(not_equal, &miss, not_taken);
1372 break; 1347 break;
1373 1348
1374 default: 1349 default:
1375 UNREACHABLE(); 1350 UNREACHABLE();
1376 } 1351 }
1377 1352
1378 if (depth != kInvalidProtoDepth) { 1353 if (depth != kInvalidProtoDepth) {
1379 GenerateFastApiCall(masm(), optimization, argc); 1354 GenerateFastApiCall(masm(), optimization, argc);
1380 } else { 1355 } else {
1381 // Get the function and setup the context. 1356 __ InvokeFunction(function, arguments());
1382 __ mov(edi, Immediate(Handle<JSFunction>(function)));
1383 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1384
1385 // Jump to the cached code (tail call).
1386 ASSERT(function->is_compiled());
1387 Handle<Code> code(function->code());
1388 ParameterCount expected(function->shared()->formal_parameter_count());
1389 __ InvokeCode(code, expected, arguments(),
1390 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
1391 } 1357 }
1392 1358
1393 // Handle call cache miss. 1359 // Handle call cache miss.
1394 __ bind(&miss); 1360 __ bind(&miss);
1395 if (depth != kInvalidProtoDepth) { 1361 if (depth != kInvalidProtoDepth) {
1396 FreeSpaceForFastApiCall(masm(), eax); 1362 FreeSpaceForFastApiCall(masm(), eax);
1397 } 1363 }
1398 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); 1364 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
1399 __ jmp(ic, RelocInfo::CODE_TARGET); 1365 __ jmp(ic, RelocInfo::CODE_TARGET);
1400 1366
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 2218 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
2253 2219
2254 // Return the generated code. 2220 // Return the generated code.
2255 return GetCode(); 2221 return GetCode();
2256 } 2222 }
2257 2223
2258 2224
2259 #undef __ 2225 #undef __
2260 2226
2261 } } // namespace v8::internal 2227 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698