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

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: REBASE + code size multiplier. Created 6 years, 7 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
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/arm/lithium-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "code-stubs.h" 9 #include "code-stubs.h"
10 #include "codegen.h" 10 #include "codegen.h"
(...skipping 2591 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 TypeFeedbackId ast_id) { 2602 TypeFeedbackId ast_id) {
2603 ic_total_count_++; 2603 ic_total_count_++;
2604 // All calls must have a predictable size in full-codegen code to ensure that 2604 // All calls must have a predictable size in full-codegen code to ensure that
2605 // the debugger can patch them correctly. 2605 // the debugger can patch them correctly.
2606 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2606 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2607 NEVER_INLINE_TARGET_ADDRESS); 2607 NEVER_INLINE_TARGET_ADDRESS);
2608 } 2608 }
2609 2609
2610 2610
2611 // Code common for calls using the IC. 2611 // Code common for calls using the IC.
2612 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2612 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2613 Expression* callee = expr->expression(); 2613 Expression* callee = expr->expression();
2614 ZoneList<Expression*>* args = expr->arguments();
2615 int arg_count = args->length();
2616 2614
2617 CallFunctionFlags flags; 2615 CallIC::CallType call_type = callee->IsVariableProxy()
2616 ? CallIC::FUNCTION
2617 : CallIC::METHOD;
2618
2618 // Get the target function. 2619 // Get the target function.
2619 if (callee->IsVariableProxy()) { 2620 if (call_type == CallIC::FUNCTION) {
2620 { StackValueContext context(this); 2621 { StackValueContext context(this);
2621 EmitVariableLoad(callee->AsVariableProxy()); 2622 EmitVariableLoad(callee->AsVariableProxy());
2622 PrepareForBailout(callee, NO_REGISTERS); 2623 PrepareForBailout(callee, NO_REGISTERS);
2623 } 2624 }
2624 // Push undefined as receiver. This is patched in the method prologue if it 2625 // Push undefined as receiver. This is patched in the method prologue if it
2625 // is a sloppy mode method. 2626 // is a sloppy mode method.
2626 __ Push(isolate()->factory()->undefined_value()); 2627 __ Push(isolate()->factory()->undefined_value());
2627 flags = NO_CALL_FUNCTION_FLAGS;
2628 } else { 2628 } else {
2629 // Load the function from the receiver. 2629 // Load the function from the receiver.
2630 ASSERT(callee->IsProperty()); 2630 ASSERT(callee->IsProperty());
2631 __ ldr(r0, MemOperand(sp, 0)); 2631 __ ldr(r0, MemOperand(sp, 0));
2632 EmitNamedPropertyLoad(callee->AsProperty()); 2632 EmitNamedPropertyLoad(callee->AsProperty());
2633 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2633 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2634 // Push the target function under the receiver. 2634 // Push the target function under the receiver.
2635 __ ldr(ip, MemOperand(sp, 0)); 2635 __ ldr(ip, MemOperand(sp, 0));
2636 __ push(ip); 2636 __ push(ip);
2637 __ str(r0, MemOperand(sp, kPointerSize)); 2637 __ str(r0, MemOperand(sp, kPointerSize));
2638 flags = CALL_AS_METHOD;
2639 } 2638 }
2640 2639
2641 // Load the arguments. 2640 EmitCall(expr, call_type);
2642 { PreservePositionScope scope(masm()->positions_recorder());
2643 for (int i = 0; i < arg_count; i++) {
2644 VisitForStackValue(args->at(i));
2645 }
2646 }
2647
2648 // Record source position for debugger.
2649 SetSourcePosition(expr->position());
2650 CallFunctionStub stub(isolate(), arg_count, flags);
2651 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2652 __ CallStub(&stub);
2653
2654 RecordJSReturnSite(expr);
2655
2656 // Restore context register.
2657 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2658
2659 context()->DropAndPlug(1, r0);
2660 } 2641 }
2661 2642
2662 2643
2663 // Code common for calls using the IC. 2644 // Code common for calls using the IC.
2664 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2645 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2665 Expression* key) { 2646 Expression* key) {
2666 // Load the key. 2647 // Load the key.
2667 VisitForAccumulatorValue(key); 2648 VisitForAccumulatorValue(key);
2668 2649
2669 Expression* callee = expr->expression(); 2650 Expression* callee = expr->expression();
2670 ZoneList<Expression*>* args = expr->arguments();
2671 int arg_count = args->length();
2672 2651
2673 // Load the function from the receiver. 2652 // Load the function from the receiver.
2674 ASSERT(callee->IsProperty()); 2653 ASSERT(callee->IsProperty());
2675 __ ldr(r1, MemOperand(sp, 0)); 2654 __ ldr(r1, MemOperand(sp, 0));
2676 EmitKeyedPropertyLoad(callee->AsProperty()); 2655 EmitKeyedPropertyLoad(callee->AsProperty());
2677 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2656 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2678 2657
2679 // Push the target function under the receiver. 2658 // Push the target function under the receiver.
2680 __ ldr(ip, MemOperand(sp, 0)); 2659 __ ldr(ip, MemOperand(sp, 0));
2681 __ push(ip); 2660 __ push(ip);
2682 __ str(r0, MemOperand(sp, kPointerSize)); 2661 __ str(r0, MemOperand(sp, kPointerSize));
2683 2662
2684 { PreservePositionScope scope(masm()->positions_recorder()); 2663 EmitCall(expr, CallIC::METHOD);
2685 for (int i = 0; i < arg_count; i++) {
2686 VisitForStackValue(args->at(i));
2687 }
2688 }
2689
2690 // Record source position for debugger.
2691 SetSourcePosition(expr->position());
2692 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD);
2693 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2694 __ CallStub(&stub);
2695
2696 RecordJSReturnSite(expr);
2697 // Restore context register.
2698 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2699
2700 context()->DropAndPlug(1, r0);
2701 } 2664 }
2702 2665
2703 2666
2704 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2667 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
2705 // Code common for calls using the call stub. 2668 // Load the arguments.
2706 ZoneList<Expression*>* args = expr->arguments(); 2669 ZoneList<Expression*>* args = expr->arguments();
2707 int arg_count = args->length(); 2670 int arg_count = args->length();
2708 { PreservePositionScope scope(masm()->positions_recorder()); 2671 { PreservePositionScope scope(masm()->positions_recorder());
2709 for (int i = 0; i < arg_count; i++) { 2672 for (int i = 0; i < arg_count; i++) {
2710 VisitForStackValue(args->at(i)); 2673 VisitForStackValue(args->at(i));
2711 } 2674 }
2712 } 2675 }
2713 // Record source position for debugger. 2676
2677 // Record source position of the IC call.
2714 SetSourcePosition(expr->position()); 2678 SetSourcePosition(expr->position());
2679 Handle<Code> ic = CallIC::initialize_stub(
2680 isolate(), arg_count, call_type);
2681 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2682 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2683 // Don't assign a type feedback id to the IC, since type feedback is provided
2684 // by the vector above.
2685 CallIC(ic);
2715 2686
2716 __ Move(r2, FeedbackVector());
2717 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2718
2719 // Record call targets in unoptimized code.
2720 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET);
2721 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2722 __ CallStub(&stub);
2723 RecordJSReturnSite(expr); 2687 RecordJSReturnSite(expr);
2724 // Restore context register. 2688 // Restore context register.
2725 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2689 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2726 context()->DropAndPlug(1, r0); 2690 context()->DropAndPlug(1, r0);
2727 } 2691 }
2728 2692
2729 2693
2730 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2694 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2731 // r4: copy of the first argument or undefined if it doesn't exist. 2695 // r4: copy of the first argument or undefined if it doesn't exist.
2732 if (arg_count > 0) { 2696 if (arg_count > 0) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 // Record source position for debugger. 2759 // Record source position for debugger.
2796 SetSourcePosition(expr->position()); 2760 SetSourcePosition(expr->position());
2797 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 2761 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
2798 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2762 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2799 __ CallStub(&stub); 2763 __ CallStub(&stub);
2800 RecordJSReturnSite(expr); 2764 RecordJSReturnSite(expr);
2801 // Restore context register. 2765 // Restore context register.
2802 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2766 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2803 context()->DropAndPlug(1, r0); 2767 context()->DropAndPlug(1, r0);
2804 } else if (call_type == Call::GLOBAL_CALL) { 2768 } else if (call_type == Call::GLOBAL_CALL) {
2805 EmitCallWithIC(expr); 2769 EmitCallWithLoadIC(expr);
2806 2770
2807 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2771 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2808 // Call to a lookup slot (dynamically introduced variable). 2772 // Call to a lookup slot (dynamically introduced variable).
2809 VariableProxy* proxy = callee->AsVariableProxy(); 2773 VariableProxy* proxy = callee->AsVariableProxy();
2810 Label slow, done; 2774 Label slow, done;
2811 2775
2812 { PreservePositionScope scope(masm()->positions_recorder()); 2776 { PreservePositionScope scope(masm()->positions_recorder());
2813 // Generate code for loading from variables potentially shadowed 2777 // Generate code for loading from variables potentially shadowed
2814 // by eval-introduced variables. 2778 // by eval-introduced variables.
2815 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2779 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 19 matching lines...) Expand all
2835 __ push(r0); 2799 __ push(r0);
2836 // The receiver is implicitly the global receiver. Indicate this 2800 // The receiver is implicitly the global receiver. Indicate this
2837 // by passing the hole to the call function stub. 2801 // by passing the hole to the call function stub.
2838 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2802 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2839 __ push(r1); 2803 __ push(r1);
2840 __ bind(&call); 2804 __ bind(&call);
2841 } 2805 }
2842 2806
2843 // The receiver is either the global receiver or an object found 2807 // The receiver is either the global receiver or an object found
2844 // by LoadContextSlot. 2808 // by LoadContextSlot.
2845 EmitCallWithStub(expr); 2809 EmitCall(expr);
2846 } else if (call_type == Call::PROPERTY_CALL) { 2810 } else if (call_type == Call::PROPERTY_CALL) {
2847 Property* property = callee->AsProperty(); 2811 Property* property = callee->AsProperty();
2848 { PreservePositionScope scope(masm()->positions_recorder()); 2812 { PreservePositionScope scope(masm()->positions_recorder());
2849 VisitForStackValue(property->obj()); 2813 VisitForStackValue(property->obj());
2850 } 2814 }
2851 if (property->key()->IsPropertyName()) { 2815 if (property->key()->IsPropertyName()) {
2852 EmitCallWithIC(expr); 2816 EmitCallWithLoadIC(expr);
2853 } else { 2817 } else {
2854 EmitKeyedCallWithIC(expr, property->key()); 2818 EmitKeyedCallWithLoadIC(expr, property->key());
2855 } 2819 }
2856 } else { 2820 } else {
2857 ASSERT(call_type == Call::OTHER_CALL); 2821 ASSERT(call_type == Call::OTHER_CALL);
2858 // Call to an arbitrary expression not handled specially above. 2822 // Call to an arbitrary expression not handled specially above.
2859 { PreservePositionScope scope(masm()->positions_recorder()); 2823 { PreservePositionScope scope(masm()->positions_recorder());
2860 VisitForStackValue(callee); 2824 VisitForStackValue(callee);
2861 } 2825 }
2862 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2826 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2863 __ push(r1); 2827 __ push(r1);
2864 // Emit function call. 2828 // Emit function call.
2865 EmitCallWithStub(expr); 2829 EmitCall(expr);
2866 } 2830 }
2867 2831
2868 #ifdef DEBUG 2832 #ifdef DEBUG
2869 // RecordJSReturnSite should have been called. 2833 // RecordJSReturnSite should have been called.
2870 ASSERT(expr->return_is_recorded_); 2834 ASSERT(expr->return_is_recorded_);
2871 #endif 2835 #endif
2872 } 2836 }
2873 2837
2874 2838
2875 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2839 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 25 matching lines...) Expand all
2901 // Record call targets in unoptimized code. 2865 // Record call targets in unoptimized code.
2902 if (FLAG_pretenuring_call_new) { 2866 if (FLAG_pretenuring_call_new) {
2903 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 2867 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
2904 ASSERT(expr->AllocationSiteFeedbackSlot() == 2868 ASSERT(expr->AllocationSiteFeedbackSlot() ==
2905 expr->CallNewFeedbackSlot() + 1); 2869 expr->CallNewFeedbackSlot() + 1);
2906 } 2870 }
2907 2871
2908 __ Move(r2, FeedbackVector()); 2872 __ Move(r2, FeedbackVector());
2909 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2873 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2910 2874
2911 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); 2875 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
2912 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 2876 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
2913 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2877 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2914 context()->Plug(r0); 2878 context()->Plug(r0);
2915 } 2879 }
2916 2880
2917 2881
2918 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2882 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2919 ZoneList<Expression*>* args = expr->arguments(); 2883 ZoneList<Expression*>* args = expr->arguments();
2920 ASSERT(args->length() == 1); 2884 ASSERT(args->length() == 1);
2921 2885
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
4900 4864
4901 ASSERT(interrupt_address == 4865 ASSERT(interrupt_address ==
4902 isolate->builtins()->OsrAfterStackCheck()->entry()); 4866 isolate->builtins()->OsrAfterStackCheck()->entry());
4903 return OSR_AFTER_STACK_CHECK; 4867 return OSR_AFTER_STACK_CHECK;
4904 } 4868 }
4905 4869
4906 4870
4907 } } // namespace v8::internal 4871 } } // namespace v8::internal
4908 4872
4909 #endif // V8_TARGET_ARCH_ARM 4873 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/arm/lithium-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698