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

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

Issue 6170001: Direct call api functions (arm implementation) (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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
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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 564
565 ExternalReference ref = 565 ExternalReference ref =
566 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); 566 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
567 __ mov(r0, Operand(5)); 567 __ mov(r0, Operand(5));
568 __ mov(r1, Operand(ref)); 568 __ mov(r1, Operand(ref));
569 569
570 CEntryStub stub(1); 570 CEntryStub stub(1);
571 __ CallStub(&stub); 571 __ CallStub(&stub);
572 } 572 }
573 573
574 #ifdef USE_SIMULATOR
575 static const int kFastApiCallArguments = 4;
576 #else
577 static const int kFastApiCallArguments = 3;
578 #endif
574 579
575 // Reserves space for the extra arguments to FastHandleApiCall in the 580 // Reserves space for the extra arguments to FastHandleApiCall in the
576 // caller's frame. 581 // caller's frame.
577 // 582 //
578 // These arguments are set by CheckPrototypes and GenerateFastApiCall. 583 // These arguments are set by CheckPrototypes and GenerateFastApiCall.
579 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, 584 static void ReserveSpaceForFastApiCall(MacroAssembler* masm,
580 Register scratch) { 585 Register scratch) {
581 __ mov(scratch, Operand(Smi::FromInt(0))); 586 __ mov(scratch, Operand(Smi::FromInt(0)));
582 __ push(scratch); 587 for (int i = 0; i < kFastApiCallArguments; i++) {
583 __ push(scratch); 588 __ push(scratch);
584 __ push(scratch); 589 }
585 __ push(scratch);
586 } 590 }
587 591
588 592
589 // Undoes the effects of ReserveSpaceForFastApiCall. 593 // Undoes the effects of ReserveSpaceForFastApiCall.
590 static void FreeSpaceForFastApiCall(MacroAssembler* masm) { 594 static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
591 __ Drop(4); 595 __ Drop(kFastApiCallArguments);
592 } 596 }
593 597
594 598
595 // Generates call to FastHandleApiCall builtin. 599 // Generates call to FastHandleApiCall builtin.
596 static void GenerateFastApiCall(MacroAssembler* masm, 600 static void GenerateFastApiCall(MacroAssembler* masm,
597 const CallOptimization& optimization, 601 const CallOptimization& optimization,
598 int argc) { 602 int argc) {
599 // Get the function and setup the context. 603 // Get the function and setup the context.
600 JSFunction* function = optimization.constant_function(); 604 JSFunction* function = optimization.constant_function();
601 __ mov(r5, Operand(Handle<JSFunction>(function))); 605 __ mov(r5, Operand(Handle<JSFunction>(function)));
(...skipping 27 matching lines...) Expand all
629 __ mov(r0, Operand(argc + 4)); 633 __ mov(r0, Operand(argc + 4));
630 634
631 // Jump to the fast api call builtin (tail call). 635 // Jump to the fast api call builtin (tail call).
632 Handle<Code> code = Handle<Code>( 636 Handle<Code> code = Handle<Code>(
633 Builtins::builtin(Builtins::FastHandleApiCall)); 637 Builtins::builtin(Builtins::FastHandleApiCall));
634 ParameterCount expected(0); 638 ParameterCount expected(0);
635 __ InvokeCode(code, expected, expected, 639 __ InvokeCode(code, expected, expected,
636 RelocInfo::CODE_TARGET, JUMP_FUNCTION); 640 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
637 } 641 }
638 642
643 #ifndef USE_SIMULATOR
644 static bool GenerateFastApiDirectCall(MacroAssembler* masm,
645 const CallOptimization& optimization,
antonm 2011/01/11 14:11:33 nit: indentation is slightly off
Zaheer 2011/01/11 15:44:35 Done
646 int argc,
647 Failure** failure) {
antonm 2011/01/11 14:11:33 may you add a stack map like in ia32 version?
Zaheer 2011/01/11 15:44:35 Done
648 // Get the function and setup the context.
649 JSFunction* function = optimization.constant_function();
650 __ mov(r5, Operand(Handle<JSFunction>(function)));
651 __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
652
653 // Pass the additional arguments FastHandleApiCall expects.
654 Object* call_data = optimization.api_call_info()->data();
655 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
656 if (Heap::InNewSpace(call_data)) {
657 __ Move(r0, api_call_info_handle);
658 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset));
659 } else {
660 __ Move(r6, Handle<Object>(call_data));
661 }
662 __ stm(ib, sp, r5.bit() | r6.bit());
antonm 2011/01/11 14:11:33 please, add a comment what are you doing here.
663 __ add(r2, sp, Operand(2 * kPointerSize)); // r2 = data
664
665 Object* callback = optimization.api_call_info()->callback();
666 Address api_function_address = v8::ToCData<Address>(callback);
667 ApiFunction fun(api_function_address);
668
669 const int kApiStackSpace = 4;
670 __ PrepareCallApiFunction(kApiStackSpace,
671 argc + kFastApiCallArguments + 1,
672 r4);
673 // v8::Arguments::implicit_args = data
674 __ str(r2, MemOperand(sp));
antonm 2011/01/11 14:11:33 I don't know if it'd be faster, but maybe you can
Zaheer 2011/01/11 15:44:35 will check
675 __ add(ip, r2, Operand(argc * kPointerSize));
676 // v8::Arguments::values = last argument
677 __ str(ip, MemOperand(sp, 1 * kPointerSize));
678 __ mov(ip, Operand(argc));
679 // v8::Arguments::length_ = argc
antonm 2011/01/11 14:11:33 for me comments are one line below they should be:
Zaheer 2011/01/11 15:44:35 Mistake! fixed
680 __ str(ip, MemOperand(sp, 2 * kPointerSize));
681 __ mov(ip, Operand(0));
682 // v8::Arguments::is_construct_call = 0
683 __ str(ip, MemOperand(sp, 3 * kPointerSize));
684 // r0 = v8::Arguments&
685 __ mov(r0, sp);
686
687 // Emitting a stub call may try to allocate (if the code is not
688 // already generated). Do not allow the assembler to perform a
689 // garbage collection but instead return the allocation failure
690 // object.
691 MaybeObject* result =
692 masm->TryCallApiFunctionAndReturn(&fun);
693 if (result->IsFailure()) {
694 *failure = Failure::cast(result);
695 return false;
696 }
697 return true;
698 }
699 #endif
700
639 701
640 class CallInterceptorCompiler BASE_EMBEDDED { 702 class CallInterceptorCompiler BASE_EMBEDDED {
641 public: 703 public:
642 CallInterceptorCompiler(StubCompiler* stub_compiler, 704 CallInterceptorCompiler(StubCompiler* stub_compiler,
643 const ParameterCount& arguments, 705 const ParameterCount& arguments,
644 Register name) 706 Register name)
645 : stub_compiler_(stub_compiler), 707 : stub_compiler_(stub_compiler),
646 arguments_(arguments), 708 arguments_(arguments),
647 name_(name) {} 709 name_(name) {}
648 710
649 void Compile(MacroAssembler* masm, 711 bool Compile(MacroAssembler* masm,
650 JSObject* object, 712 JSObject* object,
651 JSObject* holder, 713 JSObject* holder,
652 String* name, 714 String* name,
653 LookupResult* lookup, 715 LookupResult* lookup,
654 Register receiver, 716 Register receiver,
655 Register scratch1, 717 Register scratch1,
656 Register scratch2, 718 Register scratch2,
657 Register scratch3, 719 Register scratch3,
658 Label* miss) { 720 Label* miss,
721 Failure **failure) {
659 ASSERT(holder->HasNamedInterceptor()); 722 ASSERT(holder->HasNamedInterceptor());
660 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 723 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
661 724
662 // Check that the receiver isn't a smi. 725 // Check that the receiver isn't a smi.
663 __ BranchOnSmi(receiver, miss); 726 __ BranchOnSmi(receiver, miss);
664 727
665 CallOptimization optimization(lookup); 728 CallOptimization optimization(lookup);
666 729
667 if (optimization.is_constant_call()) { 730 if (optimization.is_constant_call()) {
668 CompileCacheable(masm, 731 return CompileCacheable(masm,
669 object, 732 object,
670 receiver, 733 receiver,
671 scratch1, 734 scratch1,
672 scratch2, 735 scratch2,
673 scratch3, 736 scratch3,
674 holder, 737 holder,
675 lookup, 738 lookup,
676 name, 739 name,
677 optimization, 740 optimization,
678 miss); 741 miss,
742 failure);
679 } else { 743 } else {
680 CompileRegular(masm, 744 CompileRegular(masm,
681 object, 745 object,
682 receiver, 746 receiver,
683 scratch1, 747 scratch1,
684 scratch2, 748 scratch2,
685 scratch3, 749 scratch3,
686 name, 750 name,
687 holder, 751 holder,
688 miss); 752 miss);
753 return true;
689 } 754 }
690 } 755 }
691 756
692 private: 757 private:
693 void CompileCacheable(MacroAssembler* masm, 758 bool CompileCacheable(MacroAssembler* masm,
694 JSObject* object, 759 JSObject* object,
695 Register receiver, 760 Register receiver,
696 Register scratch1, 761 Register scratch1,
697 Register scratch2, 762 Register scratch2,
698 Register scratch3, 763 Register scratch3,
699 JSObject* interceptor_holder, 764 JSObject* interceptor_holder,
700 LookupResult* lookup, 765 LookupResult* lookup,
701 String* name, 766 String* name,
702 const CallOptimization& optimization, 767 const CallOptimization& optimization,
703 Label* miss_label) { 768 Label* miss_label,
769 Failure **failure) {
704 ASSERT(optimization.is_constant_call()); 770 ASSERT(optimization.is_constant_call());
705 ASSERT(!lookup->holder()->IsGlobalObject()); 771 ASSERT(!lookup->holder()->IsGlobalObject());
706 772
707 int depth1 = kInvalidProtoDepth; 773 int depth1 = kInvalidProtoDepth;
708 int depth2 = kInvalidProtoDepth; 774 int depth2 = kInvalidProtoDepth;
709 bool can_do_fast_api_call = false; 775 bool can_do_fast_api_call = false;
710 if (optimization.is_simple_api_call() && 776 if (optimization.is_simple_api_call() &&
711 !lookup->holder()->IsGlobalObject()) { 777 !lookup->holder()->IsGlobalObject()) {
712 depth1 = 778 depth1 =
713 optimization.GetPrototypeDepthOfExpectedType(object, 779 optimization.GetPrototypeDepthOfExpectedType(object,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } else { 823 } else {
758 // CheckPrototypes has a side effect of fetching a 'holder' 824 // CheckPrototypes has a side effect of fetching a 'holder'
759 // for API (object which is instanceof for the signature). It's 825 // for API (object which is instanceof for the signature). It's
760 // safe to omit it here, as if present, it should be fetched 826 // safe to omit it here, as if present, it should be fetched
761 // by the previous CheckPrototypes. 827 // by the previous CheckPrototypes.
762 ASSERT(depth2 == kInvalidProtoDepth); 828 ASSERT(depth2 == kInvalidProtoDepth);
763 } 829 }
764 830
765 // Invoke function. 831 // Invoke function.
766 if (can_do_fast_api_call) { 832 if (can_do_fast_api_call) {
833 #ifdef USE_SIMULATOR
767 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 834 GenerateFastApiCall(masm, optimization, arguments_.immediate());
835 #else
836 bool success = GenerateFastApiDirectCall(masm,
837 optimization,
838 arguments_.immediate(),
839 failure);
840 if (!success) {
841 return false;
842 }
843 #endif
768 } else { 844 } else {
769 __ InvokeFunction(optimization.constant_function(), arguments_, 845 __ InvokeFunction(optimization.constant_function(), arguments_,
770 JUMP_FUNCTION); 846 JUMP_FUNCTION);
771 } 847 }
772 848
773 // Deferred code for fast API call case---clean preallocated space. 849 // Deferred code for fast API call case---clean preallocated space.
774 if (can_do_fast_api_call) { 850 if (can_do_fast_api_call) {
775 __ bind(&miss_cleanup); 851 __ bind(&miss_cleanup);
776 FreeSpaceForFastApiCall(masm); 852 FreeSpaceForFastApiCall(masm);
777 __ b(miss_label); 853 __ b(miss_label);
778 } 854 }
779 855
780 // Invoke a regular function. 856 // Invoke a regular function.
781 __ bind(&regular_invoke); 857 __ bind(&regular_invoke);
782 if (can_do_fast_api_call) { 858 if (can_do_fast_api_call) {
783 FreeSpaceForFastApiCall(masm); 859 FreeSpaceForFastApiCall(masm);
784 } 860 }
861
862 return true;
785 } 863 }
786 864
787 void CompileRegular(MacroAssembler* masm, 865 void CompileRegular(MacroAssembler* masm,
788 JSObject* object, 866 JSObject* object,
789 Register receiver, 867 Register receiver,
790 Register scratch1, 868 Register scratch1,
791 Register scratch2, 869 Register scratch2,
792 Register scratch3, 870 Register scratch3,
793 String* name, 871 String* name,
794 JSObject* interceptor_holder, 872 JSObject* interceptor_holder,
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 r1, r4, name, &miss); 2309 r1, r4, name, &miss);
2232 } 2310 }
2233 break; 2311 break;
2234 } 2312 }
2235 2313
2236 default: 2314 default:
2237 UNREACHABLE(); 2315 UNREACHABLE();
2238 } 2316 }
2239 2317
2240 if (depth != kInvalidProtoDepth) { 2318 if (depth != kInvalidProtoDepth) {
2319 #ifdef USE_SIMULATOR
antonm 2011/01/11 14:11:33 do we need a special case for simulator?
Zaheer 2011/01/11 15:44:35 currently the simulator interface to the native ap
antonm 2011/01/11 19:27:40 I see, let's ask Erik, maybe he can suggest someth
2241 GenerateFastApiCall(masm(), optimization, argc); 2320 GenerateFastApiCall(masm(), optimization, argc);
2321 #else
2322 Failure* failure;
2323 bool success = GenerateFastApiDirectCall(masm(),
2324 optimization,
2325 argc,
2326 &failure);
2327 if (!success) {
2328 return failure;
2329 }
2330 #endif
2242 } else { 2331 } else {
2243 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 2332 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2244 } 2333 }
2245 2334
2246 // Handle call cache miss. 2335 // Handle call cache miss.
2247 __ bind(&miss); 2336 __ bind(&miss);
2248 if (depth != kInvalidProtoDepth) { 2337 if (depth != kInvalidProtoDepth) {
2249 FreeSpaceForFastApiCall(masm()); 2338 FreeSpaceForFastApiCall(masm());
2250 } 2339 }
2251 2340
(...skipping 23 matching lines...) Expand all
2275 // Get the number of arguments. 2364 // Get the number of arguments.
2276 const int argc = arguments().immediate(); 2365 const int argc = arguments().immediate();
2277 2366
2278 LookupResult lookup; 2367 LookupResult lookup;
2279 LookupPostInterceptor(holder, name, &lookup); 2368 LookupPostInterceptor(holder, name, &lookup);
2280 2369
2281 // Get the receiver from the stack. 2370 // Get the receiver from the stack.
2282 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2371 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2283 2372
2284 CallInterceptorCompiler compiler(this, arguments(), r2); 2373 CallInterceptorCompiler compiler(this, arguments(), r2);
2285 compiler.Compile(masm(), 2374 Failure *failure;
2375 bool success = compiler.Compile(masm(),
2286 object, 2376 object,
2287 holder, 2377 holder,
2288 name, 2378 name,
2289 &lookup, 2379 &lookup,
2290 r1, 2380 r1,
2291 r3, 2381 r3,
2292 r4, 2382 r4,
2293 r0, 2383 r0,
2294 &miss); 2384 &miss,
2385 &failure);
2386 if (!success) {
2387 return false;
2388 }
2295 2389
2296 // Move returned value, the function to call, to r1. 2390 // Move returned value, the function to call, to r1.
2297 __ mov(r1, r0); 2391 __ mov(r1, r0);
2298 // Restore receiver. 2392 // Restore receiver.
2299 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2393 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2300 2394
2301 GenerateCallFunction(masm(), object, arguments(), &miss); 2395 GenerateCallFunction(masm(), object, arguments(), &miss);
2302 2396
2303 // Handle call cache miss. 2397 // Handle call cache miss.
2304 __ bind(&miss); 2398 __ bind(&miss);
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 // Return the generated code. 3294 // Return the generated code.
3201 return GetCode(); 3295 return GetCode();
3202 } 3296 }
3203 3297
3204 3298
3205 #undef __ 3299 #undef __
3206 3300
3207 } } // namespace v8::internal 3301 } } // namespace v8::internal
3208 3302
3209 #endif // V8_TARGET_ARCH_ARM 3303 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698