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

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 static const int kFastApiCallArguments = 3;
574 575
575 // Reserves space for the extra arguments to FastHandleApiCall in the 576 // Reserves space for the extra arguments to FastHandleApiCall in the
576 // caller's frame. 577 // caller's frame.
577 // 578 //
578 // These arguments are set by CheckPrototypes and GenerateFastApiCall. 579 // These arguments are set by CheckPrototypes and GenerateFastApiCall.
579 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, 580 static void ReserveSpaceForFastApiCall(MacroAssembler* masm,
580 Register scratch) { 581 Register scratch) {
581 __ mov(scratch, Operand(Smi::FromInt(0))); 582 __ mov(scratch, Operand(Smi::FromInt(0)));
582 __ push(scratch); 583 for (int i = 0; i < kFastApiCallArguments; i++) {
583 __ push(scratch); 584 __ push(scratch);
584 __ push(scratch); 585 }
585 __ push(scratch);
586 } 586 }
587 587
588 588
589 // Undoes the effects of ReserveSpaceForFastApiCall. 589 // Undoes the effects of ReserveSpaceForFastApiCall.
590 static void FreeSpaceForFastApiCall(MacroAssembler* masm) { 590 static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
591 __ Drop(4); 591 __ Drop(kFastApiCallArguments);
592 } 592 }
593 593
594 594
595 // Generates call to FastHandleApiCall builtin. 595 static bool GenerateFastApiDirectCall(MacroAssembler* masm,
Erik Corry 2011/01/24 21:45:16 Instead of returning a bool and using a Failure**
Zaheer 2011/01/25 07:39:52 Actually i followed the IA32 return structure. Mod
596 static void GenerateFastApiCall(MacroAssembler* masm, 596 const CallOptimization& optimization,
597 const CallOptimization& optimization, 597 int argc,
598 int argc) { 598 Failure** failure) {
599 // ----------- S t a t e -------------
600 // -- sp[0] : holder (set by CheckPrototypes)
601 // -- sp[4] : callee js function
602 // -- sp[8] : call data
603 // -- sp[12] : last js argument
604 // -- ...
605 // -- sp[(argc + 3) * 4] : first js argument
606 // -- sp[(argc + 4) * 4] : receiver
607 // -----------------------------------
599 // Get the function and setup the context. 608 // Get the function and setup the context.
600 JSFunction* function = optimization.constant_function(); 609 JSFunction* function = optimization.constant_function();
601 __ mov(r5, Operand(Handle<JSFunction>(function))); 610 __ mov(r5, Operand(Handle<JSFunction>(function)));
602 __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); 611 __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
603 612
604 // Pass the additional arguments FastHandleApiCall expects. 613 // Pass the additional arguments FastHandleApiCall expects.
605 bool info_loaded = false;
606 Object* callback = optimization.api_call_info()->callback();
607 if (Heap::InNewSpace(callback)) {
608 info_loaded = true;
609 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info()));
610 __ ldr(r7, FieldMemOperand(r0, CallHandlerInfo::kCallbackOffset));
611 } else {
612 __ Move(r7, Handle<Object>(callback));
613 }
614 Object* call_data = optimization.api_call_info()->data(); 614 Object* call_data = optimization.api_call_info()->data();
615 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
615 if (Heap::InNewSpace(call_data)) { 616 if (Heap::InNewSpace(call_data)) {
616 if (!info_loaded) { 617 __ Move(r0, api_call_info_handle);
617 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info()));
618 }
619 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); 618 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset));
620 } else { 619 } else {
621 __ Move(r6, Handle<Object>(call_data)); 620 __ Move(r6, Handle<Object>(call_data));
622 } 621 }
622 // Store js function and call data.
623 __ stm(ib, sp, r5.bit() | r6.bit());
623 624
624 __ add(sp, sp, Operand(1 * kPointerSize)); 625 // r2 points to call data as expected by Arguments class (refer layout above).
625 __ stm(ia, sp, r5.bit() | r6.bit() | r7.bit()); 626 __ add(r2, sp, Operand(2 * kPointerSize));
626 __ sub(sp, sp, Operand(1 * kPointerSize));
627 627
628 // Set the number of arguments. 628 Object* callback = optimization.api_call_info()->callback();
629 __ mov(r0, Operand(argc + 4)); 629 Address api_function_address = v8::ToCData<Address>(callback);
630 ApiFunction fun(api_function_address);
630 631
631 // Jump to the fast api call builtin (tail call). 632 const int kApiStackSpace = 4;
632 Handle<Code> code = Handle<Code>( 633 __ PrepareCallApiFunction(kApiStackSpace,
633 Builtins::builtin(Builtins::FastHandleApiCall)); 634 argc + kFastApiCallArguments + 1);
634 ParameterCount expected(0); 635 // v8::Arguments::implicit_args = data
635 __ InvokeCode(code, expected, expected, 636 __ str(r2, MemOperand(sp));
636 RelocInfo::CODE_TARGET, JUMP_FUNCTION); 637 // v8::Arguments::values = last argument
638 __ add(ip, r2, Operand(argc * kPointerSize));
639 __ str(ip, MemOperand(sp, 1 * kPointerSize));
640 // v8::Arguments::length_ = argc
641 __ mov(ip, Operand(argc));
642 __ str(ip, MemOperand(sp, 2 * kPointerSize));
643 // v8::Arguments::is_construct_call = 0
644 __ mov(ip, Operand(0));
645 __ str(ip, MemOperand(sp, 3 * kPointerSize));
646 // r0 = v8::Arguments&
647 __ mov(r0, sp);
648
649 // Emitting a stub call may try to allocate (if the code is not
650 // already generated). Do not allow the assembler to perform a
651 // garbage collection but instead return the allocation failure
652 // object.
653 MaybeObject* result =
654 masm->TryCallApiFunctionAndReturn(&fun);
655 if (result->IsFailure()) {
656 *failure = Failure::cast(result);
657 return false;
658 }
659 return true;
637 } 660 }
638 661
639
640 class CallInterceptorCompiler BASE_EMBEDDED { 662 class CallInterceptorCompiler BASE_EMBEDDED {
641 public: 663 public:
642 CallInterceptorCompiler(StubCompiler* stub_compiler, 664 CallInterceptorCompiler(StubCompiler* stub_compiler,
643 const ParameterCount& arguments, 665 const ParameterCount& arguments,
644 Register name) 666 Register name)
645 : stub_compiler_(stub_compiler), 667 : stub_compiler_(stub_compiler),
646 arguments_(arguments), 668 arguments_(arguments),
647 name_(name) {} 669 name_(name) {}
648 670
649 void Compile(MacroAssembler* masm, 671 bool Compile(MacroAssembler* masm,
650 JSObject* object, 672 JSObject* object,
651 JSObject* holder, 673 JSObject* holder,
652 String* name, 674 String* name,
653 LookupResult* lookup, 675 LookupResult* lookup,
654 Register receiver, 676 Register receiver,
655 Register scratch1, 677 Register scratch1,
656 Register scratch2, 678 Register scratch2,
657 Register scratch3, 679 Register scratch3,
658 Label* miss) { 680 Label* miss,
681 Failure **failure) {
659 ASSERT(holder->HasNamedInterceptor()); 682 ASSERT(holder->HasNamedInterceptor());
660 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 683 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
661 684
662 // Check that the receiver isn't a smi. 685 // Check that the receiver isn't a smi.
663 __ BranchOnSmi(receiver, miss); 686 __ BranchOnSmi(receiver, miss);
664 687
665 CallOptimization optimization(lookup); 688 CallOptimization optimization(lookup);
666 689
667 if (optimization.is_constant_call()) { 690 if (optimization.is_constant_call()) {
668 CompileCacheable(masm, 691 return CompileCacheable(masm,
669 object, 692 object,
670 receiver, 693 receiver,
671 scratch1, 694 scratch1,
672 scratch2, 695 scratch2,
673 scratch3, 696 scratch3,
674 holder, 697 holder,
675 lookup, 698 lookup,
676 name, 699 name,
677 optimization, 700 optimization,
678 miss); 701 miss,
702 failure);
679 } else { 703 } else {
680 CompileRegular(masm, 704 CompileRegular(masm,
681 object, 705 object,
682 receiver, 706 receiver,
683 scratch1, 707 scratch1,
684 scratch2, 708 scratch2,
685 scratch3, 709 scratch3,
686 name, 710 name,
687 holder, 711 holder,
688 miss); 712 miss);
713 return true;
689 } 714 }
690 } 715 }
691 716
692 private: 717 private:
693 void CompileCacheable(MacroAssembler* masm, 718 bool CompileCacheable(MacroAssembler* masm,
694 JSObject* object, 719 JSObject* object,
695 Register receiver, 720 Register receiver,
696 Register scratch1, 721 Register scratch1,
697 Register scratch2, 722 Register scratch2,
698 Register scratch3, 723 Register scratch3,
699 JSObject* interceptor_holder, 724 JSObject* interceptor_holder,
700 LookupResult* lookup, 725 LookupResult* lookup,
701 String* name, 726 String* name,
702 const CallOptimization& optimization, 727 const CallOptimization& optimization,
703 Label* miss_label) { 728 Label* miss_label,
729 Failure **failure) {
704 ASSERT(optimization.is_constant_call()); 730 ASSERT(optimization.is_constant_call());
705 ASSERT(!lookup->holder()->IsGlobalObject()); 731 ASSERT(!lookup->holder()->IsGlobalObject());
706 732
707 int depth1 = kInvalidProtoDepth; 733 int depth1 = kInvalidProtoDepth;
708 int depth2 = kInvalidProtoDepth; 734 int depth2 = kInvalidProtoDepth;
709 bool can_do_fast_api_call = false; 735 bool can_do_fast_api_call = false;
710 if (optimization.is_simple_api_call() && 736 if (optimization.is_simple_api_call() &&
711 !lookup->holder()->IsGlobalObject()) { 737 !lookup->holder()->IsGlobalObject()) {
712 depth1 = 738 depth1 =
713 optimization.GetPrototypeDepthOfExpectedType(object, 739 optimization.GetPrototypeDepthOfExpectedType(object,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } else { 783 } else {
758 // CheckPrototypes has a side effect of fetching a 'holder' 784 // CheckPrototypes has a side effect of fetching a 'holder'
759 // for API (object which is instanceof for the signature). It's 785 // for API (object which is instanceof for the signature). It's
760 // safe to omit it here, as if present, it should be fetched 786 // safe to omit it here, as if present, it should be fetched
761 // by the previous CheckPrototypes. 787 // by the previous CheckPrototypes.
762 ASSERT(depth2 == kInvalidProtoDepth); 788 ASSERT(depth2 == kInvalidProtoDepth);
763 } 789 }
764 790
765 // Invoke function. 791 // Invoke function.
766 if (can_do_fast_api_call) { 792 if (can_do_fast_api_call) {
767 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 793 bool success = GenerateFastApiDirectCall(masm,
794 optimization,
795 arguments_.immediate(),
796 failure);
797 if (!success) {
798 return false;
799 }
768 } else { 800 } else {
769 __ InvokeFunction(optimization.constant_function(), arguments_, 801 __ InvokeFunction(optimization.constant_function(), arguments_,
770 JUMP_FUNCTION); 802 JUMP_FUNCTION);
771 } 803 }
772 804
773 // Deferred code for fast API call case---clean preallocated space. 805 // Deferred code for fast API call case---clean preallocated space.
774 if (can_do_fast_api_call) { 806 if (can_do_fast_api_call) {
775 __ bind(&miss_cleanup); 807 __ bind(&miss_cleanup);
776 FreeSpaceForFastApiCall(masm); 808 FreeSpaceForFastApiCall(masm);
777 __ b(miss_label); 809 __ b(miss_label);
778 } 810 }
779 811
780 // Invoke a regular function. 812 // Invoke a regular function.
781 __ bind(&regular_invoke); 813 __ bind(&regular_invoke);
782 if (can_do_fast_api_call) { 814 if (can_do_fast_api_call) {
783 FreeSpaceForFastApiCall(masm); 815 FreeSpaceForFastApiCall(masm);
784 } 816 }
817
818 return true;
785 } 819 }
786 820
787 void CompileRegular(MacroAssembler* masm, 821 void CompileRegular(MacroAssembler* masm,
788 JSObject* object, 822 JSObject* object,
789 Register receiver, 823 Register receiver,
790 Register scratch1, 824 Register scratch1,
791 Register scratch2, 825 Register scratch2,
792 Register scratch3, 826 Register scratch3,
793 String* name, 827 String* name,
794 JSObject* interceptor_holder, 828 JSObject* interceptor_holder,
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 r1, r4, name, &miss); 2265 r1, r4, name, &miss);
2232 } 2266 }
2233 break; 2267 break;
2234 } 2268 }
2235 2269
2236 default: 2270 default:
2237 UNREACHABLE(); 2271 UNREACHABLE();
2238 } 2272 }
2239 2273
2240 if (depth != kInvalidProtoDepth) { 2274 if (depth != kInvalidProtoDepth) {
2241 GenerateFastApiCall(masm(), optimization, argc); 2275 Failure* failure;
2276 bool success = GenerateFastApiDirectCall(masm(),
2277 optimization,
2278 argc,
2279 &failure);
2280 if (!success) {
2281 return failure;
2282 }
2242 } else { 2283 } else {
2243 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 2284 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
2244 } 2285 }
2245 2286
2246 // Handle call cache miss. 2287 // Handle call cache miss.
2247 __ bind(&miss); 2288 __ bind(&miss);
2248 if (depth != kInvalidProtoDepth) { 2289 if (depth != kInvalidProtoDepth) {
2249 FreeSpaceForFastApiCall(masm()); 2290 FreeSpaceForFastApiCall(masm());
2250 } 2291 }
2251 2292
(...skipping 23 matching lines...) Expand all
2275 // Get the number of arguments. 2316 // Get the number of arguments.
2276 const int argc = arguments().immediate(); 2317 const int argc = arguments().immediate();
2277 2318
2278 LookupResult lookup; 2319 LookupResult lookup;
2279 LookupPostInterceptor(holder, name, &lookup); 2320 LookupPostInterceptor(holder, name, &lookup);
2280 2321
2281 // Get the receiver from the stack. 2322 // Get the receiver from the stack.
2282 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2323 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2283 2324
2284 CallInterceptorCompiler compiler(this, arguments(), r2); 2325 CallInterceptorCompiler compiler(this, arguments(), r2);
2285 compiler.Compile(masm(), 2326 Failure *failure;
2327 bool success = compiler.Compile(masm(),
2286 object, 2328 object,
2287 holder, 2329 holder,
2288 name, 2330 name,
2289 &lookup, 2331 &lookup,
2290 r1, 2332 r1,
2291 r3, 2333 r3,
2292 r4, 2334 r4,
2293 r0, 2335 r0,
2294 &miss); 2336 &miss,
2337 &failure);
2338 if (!success) {
2339 return false;
2340 }
2295 2341
2296 // Move returned value, the function to call, to r1. 2342 // Move returned value, the function to call, to r1.
2297 __ mov(r1, r0); 2343 __ mov(r1, r0);
2298 // Restore receiver. 2344 // Restore receiver.
2299 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2345 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2300 2346
2301 GenerateCallFunction(masm(), object, arguments(), &miss); 2347 GenerateCallFunction(masm(), object, arguments(), &miss);
2302 2348
2303 // Handle call cache miss. 2349 // Handle call cache miss.
2304 __ bind(&miss); 2350 __ bind(&miss);
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 // Return the generated code. 3246 // Return the generated code.
3201 return GetCode(); 3247 return GetCode();
3202 } 3248 }
3203 3249
3204 3250
3205 #undef __ 3251 #undef __
3206 3252
3207 } } // namespace v8::internal 3253 } } // namespace v8::internal
3208 3254
3209 #endif // V8_TARGET_ARCH_ARM 3255 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« src/arm/simulator-arm.cc ('K') | « src/arm/simulator-arm.cc ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698