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

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,
646 int argc,
647 Failure** failure) {
648 // ----------- S t a t e -------------
649 // -- sp[0] : holder (set by CheckPrototypes)
650 // -- sp[4] : callee js function
651 // -- sp[8] : call data
652 // -- sp[12] : last js argument
653 // -- ...
654 // -- sp[(argc + 3) * 4] : first js argument
655 // -- sp[(argc + 4) * 4] : receiver
656 // -----------------------------------
657 // Get the function and setup the context.
658 JSFunction* function = optimization.constant_function();
659 __ mov(r5, Operand(Handle<JSFunction>(function)));
660 __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
661
662 // Pass the additional arguments FastHandleApiCall expects.
663 Object* call_data = optimization.api_call_info()->data();
664 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
665 if (Heap::InNewSpace(call_data)) {
666 __ Move(r0, api_call_info_handle);
667 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset));
668 } else {
669 __ Move(r6, Handle<Object>(call_data));
670 }
671 __ stm(ib, sp, r5.bit() | r6.bit());
672
673 // r2 points to calldata as expected by Arguments class (refer layout above)
674 __ add(r2, sp, Operand(2 * kPointerSize));
675
676 Object* callback = optimization.api_call_info()->callback();
677 Address api_function_address = v8::ToCData<Address>(callback);
678 ApiFunction fun(api_function_address);
679
680 const int kApiStackSpace = 4;
681 __ PrepareCallApiFunction(kApiStackSpace,
682 argc + kFastApiCallArguments + 1);
683 // v8::Arguments::implicit_args = data
684 __ str(r2, MemOperand(sp));
685 // v8::Arguments::values = last argument
686 __ add(ip, r2, Operand(argc * kPointerSize));
687 __ str(ip, MemOperand(sp, 1 * kPointerSize));
688 // v8::Arguments::length_ = argc
689 __ mov(ip, Operand(argc));
690 __ str(ip, MemOperand(sp, 2 * kPointerSize));
691 // v8::Arguments::is_construct_call = 0
692 __ mov(ip, Operand(0));
693 __ str(ip, MemOperand(sp, 3 * kPointerSize));
694 // r0 = v8::Arguments&
695 __ mov(r0, sp);
696
697 // Emitting a stub call may try to allocate (if the code is not
698 // already generated). Do not allow the assembler to perform a
699 // garbage collection but instead return the allocation failure
700 // object.
701 MaybeObject* result =
702 masm->TryCallApiFunctionAndReturn(&fun);
703 if (result->IsFailure()) {
704 *failure = Failure::cast(result);
705 return false;
706 }
707 return true;
708 }
709 #endif
710
639 711
640 class CallInterceptorCompiler BASE_EMBEDDED { 712 class CallInterceptorCompiler BASE_EMBEDDED {
641 public: 713 public:
642 CallInterceptorCompiler(StubCompiler* stub_compiler, 714 CallInterceptorCompiler(StubCompiler* stub_compiler,
643 const ParameterCount& arguments, 715 const ParameterCount& arguments,
644 Register name) 716 Register name)
645 : stub_compiler_(stub_compiler), 717 : stub_compiler_(stub_compiler),
646 arguments_(arguments), 718 arguments_(arguments),
647 name_(name) {} 719 name_(name) {}
648 720
649 void Compile(MacroAssembler* masm, 721 bool Compile(MacroAssembler* masm,
650 JSObject* object, 722 JSObject* object,
651 JSObject* holder, 723 JSObject* holder,
652 String* name, 724 String* name,
653 LookupResult* lookup, 725 LookupResult* lookup,
654 Register receiver, 726 Register receiver,
655 Register scratch1, 727 Register scratch1,
656 Register scratch2, 728 Register scratch2,
657 Register scratch3, 729 Register scratch3,
658 Label* miss) { 730 Label* miss,
731 Failure **failure) {
659 ASSERT(holder->HasNamedInterceptor()); 732 ASSERT(holder->HasNamedInterceptor());
660 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 733 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
661 734
662 // Check that the receiver isn't a smi. 735 // Check that the receiver isn't a smi.
663 __ BranchOnSmi(receiver, miss); 736 __ BranchOnSmi(receiver, miss);
664 737
665 CallOptimization optimization(lookup); 738 CallOptimization optimization(lookup);
666 739
667 if (optimization.is_constant_call()) { 740 if (optimization.is_constant_call()) {
668 CompileCacheable(masm, 741 return CompileCacheable(masm,
669 object, 742 object,
670 receiver, 743 receiver,
671 scratch1, 744 scratch1,
672 scratch2, 745 scratch2,
673 scratch3, 746 scratch3,
674 holder, 747 holder,
675 lookup, 748 lookup,
676 name, 749 name,
677 optimization, 750 optimization,
678 miss); 751 miss,
752 failure);
679 } else { 753 } else {
680 CompileRegular(masm, 754 CompileRegular(masm,
681 object, 755 object,
682 receiver, 756 receiver,
683 scratch1, 757 scratch1,
684 scratch2, 758 scratch2,
685 scratch3, 759 scratch3,
686 name, 760 name,
687 holder, 761 holder,
688 miss); 762 miss);
763 return true;
689 } 764 }
690 } 765 }
691 766
692 private: 767 private:
693 void CompileCacheable(MacroAssembler* masm, 768 bool CompileCacheable(MacroAssembler* masm,
694 JSObject* object, 769 JSObject* object,
695 Register receiver, 770 Register receiver,
696 Register scratch1, 771 Register scratch1,
697 Register scratch2, 772 Register scratch2,
698 Register scratch3, 773 Register scratch3,
699 JSObject* interceptor_holder, 774 JSObject* interceptor_holder,
700 LookupResult* lookup, 775 LookupResult* lookup,
701 String* name, 776 String* name,
702 const CallOptimization& optimization, 777 const CallOptimization& optimization,
703 Label* miss_label) { 778 Label* miss_label,
779 Failure **failure) {
704 ASSERT(optimization.is_constant_call()); 780 ASSERT(optimization.is_constant_call());
705 ASSERT(!lookup->holder()->IsGlobalObject()); 781 ASSERT(!lookup->holder()->IsGlobalObject());
706 782
707 int depth1 = kInvalidProtoDepth; 783 int depth1 = kInvalidProtoDepth;
708 int depth2 = kInvalidProtoDepth; 784 int depth2 = kInvalidProtoDepth;
709 bool can_do_fast_api_call = false; 785 bool can_do_fast_api_call = false;
710 if (optimization.is_simple_api_call() && 786 if (optimization.is_simple_api_call() &&
711 !lookup->holder()->IsGlobalObject()) { 787 !lookup->holder()->IsGlobalObject()) {
712 depth1 = 788 depth1 =
713 optimization.GetPrototypeDepthOfExpectedType(object, 789 optimization.GetPrototypeDepthOfExpectedType(object,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } else { 833 } else {
758 // CheckPrototypes has a side effect of fetching a 'holder' 834 // CheckPrototypes has a side effect of fetching a 'holder'
759 // for API (object which is instanceof for the signature). It's 835 // for API (object which is instanceof for the signature). It's
760 // safe to omit it here, as if present, it should be fetched 836 // safe to omit it here, as if present, it should be fetched
761 // by the previous CheckPrototypes. 837 // by the previous CheckPrototypes.
762 ASSERT(depth2 == kInvalidProtoDepth); 838 ASSERT(depth2 == kInvalidProtoDepth);
763 } 839 }
764 840
765 // Invoke function. 841 // Invoke function.
766 if (can_do_fast_api_call) { 842 if (can_do_fast_api_call) {
843 #ifdef USE_SIMULATOR
767 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 844 GenerateFastApiCall(masm, optimization, arguments_.immediate());
845 #else
846 bool success = GenerateFastApiDirectCall(masm,
847 optimization,
848 arguments_.immediate(),
849 failure);
850 if (!success) {
851 return false;
852 }
853 #endif
768 } else { 854 } else {
769 __ InvokeFunction(optimization.constant_function(), arguments_, 855 __ InvokeFunction(optimization.constant_function(), arguments_,
770 JUMP_FUNCTION); 856 JUMP_FUNCTION);
771 } 857 }
772 858
773 // Deferred code for fast API call case---clean preallocated space. 859 // Deferred code for fast API call case---clean preallocated space.
774 if (can_do_fast_api_call) { 860 if (can_do_fast_api_call) {
775 __ bind(&miss_cleanup); 861 __ bind(&miss_cleanup);
776 FreeSpaceForFastApiCall(masm); 862 FreeSpaceForFastApiCall(masm);
777 __ b(miss_label); 863 __ b(miss_label);
778 } 864 }
779 865
780 // Invoke a regular function. 866 // Invoke a regular function.
781 __ bind(&regular_invoke); 867 __ bind(&regular_invoke);
782 if (can_do_fast_api_call) { 868 if (can_do_fast_api_call) {
783 FreeSpaceForFastApiCall(masm); 869 FreeSpaceForFastApiCall(masm);
784 } 870 }
871
872 return true;
785 } 873 }
786 874
787 void CompileRegular(MacroAssembler* masm, 875 void CompileRegular(MacroAssembler* masm,
788 JSObject* object, 876 JSObject* object,
789 Register receiver, 877 Register receiver,
790 Register scratch1, 878 Register scratch1,
791 Register scratch2, 879 Register scratch2,
792 Register scratch3, 880 Register scratch3,
793 String* name, 881 String* name,
794 JSObject* interceptor_holder, 882 JSObject* interceptor_holder,
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 r1, r4, name, &miss); 2319 r1, r4, name, &miss);
2232 } 2320 }
2233 break; 2321 break;
2234 } 2322 }
2235 2323
2236 default: 2324 default:
2237 UNREACHABLE(); 2325 UNREACHABLE();
2238 } 2326 }
2239 2327
2240 if (depth != kInvalidProtoDepth) { 2328 if (depth != kInvalidProtoDepth) {
2329 #ifdef USE_SIMULATOR
2241 GenerateFastApiCall(masm(), optimization, argc); 2330 GenerateFastApiCall(masm(), optimization, argc);
2331 #else
2332 Failure* failure;
2333 bool success = GenerateFastApiDirectCall(masm(),
2334 optimization,
2335 argc,
2336 &failure);
2337 if (!success) {
2338 return failure;
2339 }
2340 #endif
2242 } else { 2341 } else {
2243 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 2342 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2244 } 2343 }
2245 2344
2246 // Handle call cache miss. 2345 // Handle call cache miss.
2247 __ bind(&miss); 2346 __ bind(&miss);
2248 if (depth != kInvalidProtoDepth) { 2347 if (depth != kInvalidProtoDepth) {
2249 FreeSpaceForFastApiCall(masm()); 2348 FreeSpaceForFastApiCall(masm());
2250 } 2349 }
2251 2350
(...skipping 23 matching lines...) Expand all
2275 // Get the number of arguments. 2374 // Get the number of arguments.
2276 const int argc = arguments().immediate(); 2375 const int argc = arguments().immediate();
2277 2376
2278 LookupResult lookup; 2377 LookupResult lookup;
2279 LookupPostInterceptor(holder, name, &lookup); 2378 LookupPostInterceptor(holder, name, &lookup);
2280 2379
2281 // Get the receiver from the stack. 2380 // Get the receiver from the stack.
2282 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2381 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2283 2382
2284 CallInterceptorCompiler compiler(this, arguments(), r2); 2383 CallInterceptorCompiler compiler(this, arguments(), r2);
2285 compiler.Compile(masm(), 2384 Failure *failure;
2385 bool success = compiler.Compile(masm(),
2286 object, 2386 object,
2287 holder, 2387 holder,
2288 name, 2388 name,
2289 &lookup, 2389 &lookup,
2290 r1, 2390 r1,
2291 r3, 2391 r3,
2292 r4, 2392 r4,
2293 r0, 2393 r0,
2294 &miss); 2394 &miss,
2395 &failure);
2396 if (!success) {
2397 return false;
2398 }
2295 2399
2296 // Move returned value, the function to call, to r1. 2400 // Move returned value, the function to call, to r1.
2297 __ mov(r1, r0); 2401 __ mov(r1, r0);
2298 // Restore receiver. 2402 // Restore receiver.
2299 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2403 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2300 2404
2301 GenerateCallFunction(masm(), object, arguments(), &miss); 2405 GenerateCallFunction(masm(), object, arguments(), &miss);
2302 2406
2303 // Handle call cache miss. 2407 // Handle call cache miss.
2304 __ bind(&miss); 2408 __ bind(&miss);
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 // Return the generated code. 3304 // Return the generated code.
3201 return GetCode(); 3305 return GetCode();
3202 } 3306 }
3203 3307
3204 3308
3205 #undef __ 3309 #undef __
3206 3310
3207 } } // namespace v8::internal 3311 } } // namespace v8::internal
3208 3312
3209 #endif // V8_TARGET_ARCH_ARM 3313 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« src/arm/macro-assembler-arm.cc ('K') | « src/arm/macro-assembler-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698