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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 247373002: CallICStub with a "never patch" approach until customization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ports. Created 6 years, 8 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2610 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 TypeFeedbackId ast_id) { 2621 TypeFeedbackId ast_id) {
2622 ic_total_count_++; 2622 ic_total_count_++;
2623 // All calls must have a predictable size in full-codegen code to ensure that 2623 // All calls must have a predictable size in full-codegen code to ensure that
2624 // the debugger can patch them correctly. 2624 // the debugger can patch them correctly.
2625 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2625 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2626 NEVER_INLINE_TARGET_ADDRESS); 2626 NEVER_INLINE_TARGET_ADDRESS);
2627 } 2627 }
2628 2628
2629 2629
2630 // Code common for calls using the IC. 2630 // Code common for calls using the IC.
2631 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2631 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2632 Expression* callee = expr->expression(); 2632 Expression* callee = expr->expression();
2633 ZoneList<Expression*>* args = expr->arguments();
2634 int arg_count = args->length();
2635 2633
2636 CallFunctionFlags flags; 2634 CallIC::CallType call_type = callee->IsVariableProxy()
2635 ? CallIC::FUNCTION
2636 : CallIC::METHOD;
2637
2637 // Get the target function. 2638 // Get the target function.
2638 if (callee->IsVariableProxy()) { 2639 if (call_type == CallIC::FUNCTION) {
2639 { StackValueContext context(this); 2640 { StackValueContext context(this);
2640 EmitVariableLoad(callee->AsVariableProxy()); 2641 EmitVariableLoad(callee->AsVariableProxy());
2641 PrepareForBailout(callee, NO_REGISTERS); 2642 PrepareForBailout(callee, NO_REGISTERS);
2642 } 2643 }
2643 // Push undefined as receiver. This is patched in the method prologue if it 2644 // Push undefined as receiver. This is patched in the method prologue if it
2644 // is a sloppy mode method. 2645 // is a sloppy mode method.
2645 __ Push(isolate()->factory()->undefined_value()); 2646 __ Push(isolate()->factory()->undefined_value());
2646 flags = NO_CALL_FUNCTION_FLAGS;
2647 } else { 2647 } else {
2648 // Load the function from the receiver. 2648 // Load the function from the receiver.
2649 ASSERT(callee->IsProperty()); 2649 ASSERT(callee->IsProperty());
2650 __ ldr(r0, MemOperand(sp, 0)); 2650 __ ldr(r0, MemOperand(sp, 0));
2651 EmitNamedPropertyLoad(callee->AsProperty()); 2651 EmitNamedPropertyLoad(callee->AsProperty());
2652 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2652 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2653 // Push the target function under the receiver. 2653 // Push the target function under the receiver.
2654 __ ldr(ip, MemOperand(sp, 0)); 2654 __ ldr(ip, MemOperand(sp, 0));
2655 __ push(ip); 2655 __ push(ip);
2656 __ str(r0, MemOperand(sp, kPointerSize)); 2656 __ str(r0, MemOperand(sp, kPointerSize));
2657 flags = CALL_AS_METHOD;
2658 } 2657 }
2659 2658
2660 // Load the arguments. 2659 EmitCall(expr, call_type);
2661 { PreservePositionScope scope(masm()->positions_recorder());
2662 for (int i = 0; i < arg_count; i++) {
2663 VisitForStackValue(args->at(i));
2664 }
2665 }
2666
2667 // Record source position for debugger.
2668 SetSourcePosition(expr->position());
2669 CallFunctionStub stub(arg_count, flags);
2670 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2671 __ CallStub(&stub);
2672
2673 RecordJSReturnSite(expr);
2674
2675 // Restore context register.
2676 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2677
2678 context()->DropAndPlug(1, r0);
2679 } 2660 }
2680 2661
2681 2662
2682 // Code common for calls using the IC. 2663 // Code common for calls using the IC.
2683 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2664 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2684 Expression* key) { 2665 Expression* key) {
2685 // Load the key. 2666 // Load the key.
2686 VisitForAccumulatorValue(key); 2667 VisitForAccumulatorValue(key);
2687 2668
2688 Expression* callee = expr->expression(); 2669 Expression* callee = expr->expression();
2689 ZoneList<Expression*>* args = expr->arguments();
2690 int arg_count = args->length();
2691 2670
2692 // Load the function from the receiver. 2671 // Load the function from the receiver.
2693 ASSERT(callee->IsProperty()); 2672 ASSERT(callee->IsProperty());
2694 __ ldr(r1, MemOperand(sp, 0)); 2673 __ ldr(r1, MemOperand(sp, 0));
2695 EmitKeyedPropertyLoad(callee->AsProperty()); 2674 EmitKeyedPropertyLoad(callee->AsProperty());
2696 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2675 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2697 2676
2698 // Push the target function under the receiver. 2677 // Push the target function under the receiver.
2699 __ ldr(ip, MemOperand(sp, 0)); 2678 __ ldr(ip, MemOperand(sp, 0));
2700 __ push(ip); 2679 __ push(ip);
2701 __ str(r0, MemOperand(sp, kPointerSize)); 2680 __ str(r0, MemOperand(sp, kPointerSize));
2702 2681
2703 { PreservePositionScope scope(masm()->positions_recorder()); 2682 EmitCall(expr, CallIC::METHOD);
2704 for (int i = 0; i < arg_count; i++) {
2705 VisitForStackValue(args->at(i));
2706 }
2707 }
2708
2709 // Record source position for debugger.
2710 SetSourcePosition(expr->position());
2711 CallFunctionStub stub(arg_count, CALL_AS_METHOD);
2712 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2713 __ CallStub(&stub);
2714
2715 RecordJSReturnSite(expr);
2716 // Restore context register.
2717 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2718
2719 context()->DropAndPlug(1, r0);
2720 } 2683 }
2721 2684
2722 2685
2723 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2686 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
2724 // Code common for calls using the call stub. 2687 // Load the arguments.
2725 ZoneList<Expression*>* args = expr->arguments(); 2688 ZoneList<Expression*>* args = expr->arguments();
2726 int arg_count = args->length(); 2689 int arg_count = args->length();
2727 { PreservePositionScope scope(masm()->positions_recorder()); 2690 { PreservePositionScope scope(masm()->positions_recorder());
2728 for (int i = 0; i < arg_count; i++) { 2691 for (int i = 0; i < arg_count; i++) {
2729 VisitForStackValue(args->at(i)); 2692 VisitForStackValue(args->at(i));
2730 } 2693 }
2731 } 2694 }
2732 // Record source position for debugger. 2695
2696 // Record source position of the IC call.
2733 SetSourcePosition(expr->position()); 2697 SetSourcePosition(expr->position());
2698 Handle<Code> ic = CallIC::initialize_stub(
2699 isolate(), arg_count, call_type);
2700 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2701 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2702 // Don't assign a type feedback id to the IC, since type feedback is provided
2703 // by the vector above.
2704 CallIC(ic);
2734 2705
2735 __ Move(r2, FeedbackVector());
2736 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2737
2738 // Record call targets in unoptimized code.
2739 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2740 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2741 __ CallStub(&stub);
2742 RecordJSReturnSite(expr); 2706 RecordJSReturnSite(expr);
2743 // Restore context register. 2707 // Restore context register.
2744 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2708 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2745 context()->DropAndPlug(1, r0); 2709 context()->DropAndPlug(1, r0);
2746 } 2710 }
2747 2711
2748 2712
2749 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2713 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2750 // r4: copy of the first argument or undefined if it doesn't exist. 2714 // r4: copy of the first argument or undefined if it doesn't exist.
2751 if (arg_count > 0) { 2715 if (arg_count > 0) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2814 // Record source position for debugger. 2778 // Record source position for debugger.
2815 SetSourcePosition(expr->position()); 2779 SetSourcePosition(expr->position());
2816 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); 2780 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
2817 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2781 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2818 __ CallStub(&stub); 2782 __ CallStub(&stub);
2819 RecordJSReturnSite(expr); 2783 RecordJSReturnSite(expr);
2820 // Restore context register. 2784 // Restore context register.
2821 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2785 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2822 context()->DropAndPlug(1, r0); 2786 context()->DropAndPlug(1, r0);
2823 } else if (call_type == Call::GLOBAL_CALL) { 2787 } else if (call_type == Call::GLOBAL_CALL) {
2824 EmitCallWithIC(expr); 2788 EmitCallWithLoadIC(expr);
2825 2789
2826 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2790 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2827 // Call to a lookup slot (dynamically introduced variable). 2791 // Call to a lookup slot (dynamically introduced variable).
2828 VariableProxy* proxy = callee->AsVariableProxy(); 2792 VariableProxy* proxy = callee->AsVariableProxy();
2829 Label slow, done; 2793 Label slow, done;
2830 2794
2831 { PreservePositionScope scope(masm()->positions_recorder()); 2795 { PreservePositionScope scope(masm()->positions_recorder());
2832 // Generate code for loading from variables potentially shadowed 2796 // Generate code for loading from variables potentially shadowed
2833 // by eval-introduced variables. 2797 // by eval-introduced variables.
2834 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2798 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 19 matching lines...) Expand all
2854 __ push(r0); 2818 __ push(r0);
2855 // The receiver is implicitly the global receiver. Indicate this 2819 // The receiver is implicitly the global receiver. Indicate this
2856 // by passing the hole to the call function stub. 2820 // by passing the hole to the call function stub.
2857 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2821 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2858 __ push(r1); 2822 __ push(r1);
2859 __ bind(&call); 2823 __ bind(&call);
2860 } 2824 }
2861 2825
2862 // The receiver is either the global receiver or an object found 2826 // The receiver is either the global receiver or an object found
2863 // by LoadContextSlot. 2827 // by LoadContextSlot.
2864 EmitCallWithStub(expr); 2828 EmitCall(expr);
2865 } else if (call_type == Call::PROPERTY_CALL) { 2829 } else if (call_type == Call::PROPERTY_CALL) {
2866 Property* property = callee->AsProperty(); 2830 Property* property = callee->AsProperty();
2867 { PreservePositionScope scope(masm()->positions_recorder()); 2831 { PreservePositionScope scope(masm()->positions_recorder());
2868 VisitForStackValue(property->obj()); 2832 VisitForStackValue(property->obj());
2869 } 2833 }
2870 if (property->key()->IsPropertyName()) { 2834 if (property->key()->IsPropertyName()) {
2871 EmitCallWithIC(expr); 2835 EmitCallWithLoadIC(expr);
2872 } else { 2836 } else {
2873 EmitKeyedCallWithIC(expr, property->key()); 2837 EmitKeyedCallWithLoadIC(expr, property->key());
2874 } 2838 }
2875 } else { 2839 } else {
2876 ASSERT(call_type == Call::OTHER_CALL); 2840 ASSERT(call_type == Call::OTHER_CALL);
2877 // Call to an arbitrary expression not handled specially above. 2841 // Call to an arbitrary expression not handled specially above.
2878 { PreservePositionScope scope(masm()->positions_recorder()); 2842 { PreservePositionScope scope(masm()->positions_recorder());
2879 VisitForStackValue(callee); 2843 VisitForStackValue(callee);
2880 } 2844 }
2881 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2845 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2882 __ push(r1); 2846 __ push(r1);
2883 // Emit function call. 2847 // Emit function call.
2884 EmitCallWithStub(expr); 2848 EmitCall(expr);
2885 } 2849 }
2886 2850
2887 #ifdef DEBUG 2851 #ifdef DEBUG
2888 // RecordJSReturnSite should have been called. 2852 // RecordJSReturnSite should have been called.
2889 ASSERT(expr->return_is_recorded_); 2853 ASSERT(expr->return_is_recorded_);
2890 #endif 2854 #endif
2891 } 2855 }
2892 2856
2893 2857
2894 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2858 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 25 matching lines...) Expand all
2920 // Record call targets in unoptimized code. 2884 // Record call targets in unoptimized code.
2921 if (FLAG_pretenuring_call_new) { 2885 if (FLAG_pretenuring_call_new) {
2922 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 2886 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
2923 ASSERT(expr->AllocationSiteFeedbackSlot() == 2887 ASSERT(expr->AllocationSiteFeedbackSlot() ==
2924 expr->CallNewFeedbackSlot() + 1); 2888 expr->CallNewFeedbackSlot() + 1);
2925 } 2889 }
2926 2890
2927 __ Move(r2, FeedbackVector()); 2891 __ Move(r2, FeedbackVector());
2928 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2892 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2929 2893
2930 CallConstructStub stub(RECORD_CALL_TARGET); 2894 CallConstructStub stub(RECORD_CONSTRUCTOR_TARGET);
2931 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2895 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2932 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2896 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2933 context()->Plug(r0); 2897 context()->Plug(r0);
2934 } 2898 }
2935 2899
2936 2900
2937 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2901 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2938 ZoneList<Expression*>* args = expr->arguments(); 2902 ZoneList<Expression*>* args = expr->arguments();
2939 ASSERT(args->length() == 1); 2903 ASSERT(args->length() == 1);
2940 2904
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
4919 4883
4920 ASSERT(interrupt_address == 4884 ASSERT(interrupt_address ==
4921 isolate->builtins()->OsrAfterStackCheck()->entry()); 4885 isolate->builtins()->OsrAfterStackCheck()->entry());
4922 return OSR_AFTER_STACK_CHECK; 4886 return OSR_AFTER_STACK_CHECK;
4923 } 4887 }
4924 4888
4925 4889
4926 } } // namespace v8::internal 4890 } } // namespace v8::internal
4927 4891
4928 #endif // V8_TARGET_ARCH_ARM 4892 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698