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

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

Issue 172523002: Create a function call IC (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE. 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
« 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 // 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 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2625 TypeFeedbackId ast_id) { 2625 TypeFeedbackId ast_id) {
2626 ic_total_count_++; 2626 ic_total_count_++;
2627 // All calls must have a predictable size in full-codegen code to ensure that 2627 // All calls must have a predictable size in full-codegen code to ensure that
2628 // the debugger can patch them correctly. 2628 // the debugger can patch them correctly.
2629 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2629 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2630 NEVER_INLINE_TARGET_ADDRESS); 2630 NEVER_INLINE_TARGET_ADDRESS);
2631 } 2631 }
2632 2632
2633 2633
2634 // Code common for calls using the IC. 2634 // Code common for calls using the IC.
2635 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2635 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2636 Expression* callee = expr->expression(); 2636 Expression* callee = expr->expression();
2637 ZoneList<Expression*>* args = expr->arguments();
2638 int arg_count = args->length();
2639 2637
2640 CallFunctionFlags flags; 2638 CallIC::CallType call_type = callee->IsVariableProxy()
2639 ? CallIC::FUNCTION
2640 : CallIC::METHOD;
2641
2641 // Get the target function. 2642 // Get the target function.
2642 if (callee->IsVariableProxy()) { 2643 if (call_type == CallIC::FUNCTION) {
2643 { StackValueContext context(this); 2644 { StackValueContext context(this);
2644 EmitVariableLoad(callee->AsVariableProxy()); 2645 EmitVariableLoad(callee->AsVariableProxy());
2645 PrepareForBailout(callee, NO_REGISTERS); 2646 PrepareForBailout(callee, NO_REGISTERS);
2646 } 2647 }
2647 // Push undefined as receiver. This is patched in the method prologue if it 2648 // Push undefined as receiver. This is patched in the method prologue if it
2648 // is a sloppy mode method. 2649 // is a sloppy mode method.
2649 __ Push(isolate()->factory()->undefined_value()); 2650 __ Push(isolate()->factory()->undefined_value());
2650 flags = NO_CALL_FUNCTION_FLAGS;
2651 } else { 2651 } else {
2652 // Load the function from the receiver. 2652 // Load the function from the receiver.
2653 ASSERT(callee->IsProperty()); 2653 ASSERT(callee->IsProperty());
2654 __ ldr(r0, MemOperand(sp, 0)); 2654 __ ldr(r0, MemOperand(sp, 0));
2655 EmitNamedPropertyLoad(callee->AsProperty()); 2655 EmitNamedPropertyLoad(callee->AsProperty());
2656 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2656 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2657 // Push the target function under the receiver. 2657 // Push the target function under the receiver.
2658 __ ldr(ip, MemOperand(sp, 0)); 2658 __ ldr(ip, MemOperand(sp, 0));
2659 __ push(ip); 2659 __ push(ip);
2660 __ str(r0, MemOperand(sp, kPointerSize)); 2660 __ str(r0, MemOperand(sp, kPointerSize));
2661 flags = CALL_AS_METHOD;
2662 } 2661 }
2663 2662
2664 // Load the arguments. 2663 EmitCall(expr, call_type);
2665 { PreservePositionScope scope(masm()->positions_recorder());
2666 for (int i = 0; i < arg_count; i++) {
2667 VisitForStackValue(args->at(i));
2668 }
2669 }
2670
2671 // Record source position for debugger.
2672 SetSourcePosition(expr->position());
2673 CallFunctionStub stub(arg_count, flags);
2674 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2675 __ CallStub(&stub);
2676
2677 RecordJSReturnSite(expr);
2678
2679 // Restore context register.
2680 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2681
2682 context()->DropAndPlug(1, r0);
2683 } 2664 }
2684 2665
2685 2666
2686 // Code common for calls using the IC. 2667 // Code common for calls using the IC.
2687 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2668 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2688 Expression* key) { 2669 Expression* key) {
2689 // Load the key. 2670 // Load the key.
2690 VisitForAccumulatorValue(key); 2671 VisitForAccumulatorValue(key);
2691 2672
2692 Expression* callee = expr->expression(); 2673 Expression* callee = expr->expression();
2693 ZoneList<Expression*>* args = expr->arguments();
2694 int arg_count = args->length();
2695 2674
2696 // Load the function from the receiver. 2675 // Load the function from the receiver.
2697 ASSERT(callee->IsProperty()); 2676 ASSERT(callee->IsProperty());
2698 __ ldr(r1, MemOperand(sp, 0)); 2677 __ ldr(r1, MemOperand(sp, 0));
2699 EmitKeyedPropertyLoad(callee->AsProperty()); 2678 EmitKeyedPropertyLoad(callee->AsProperty());
2700 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2679 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2701 2680
2702 // Push the target function under the receiver. 2681 // Push the target function under the receiver.
2703 __ ldr(ip, MemOperand(sp, 0)); 2682 __ ldr(ip, MemOperand(sp, 0));
2704 __ push(ip); 2683 __ push(ip);
2705 __ str(r0, MemOperand(sp, kPointerSize)); 2684 __ str(r0, MemOperand(sp, kPointerSize));
2706 2685
2707 { PreservePositionScope scope(masm()->positions_recorder()); 2686 EmitCall(expr, CallIC::METHOD);
2708 for (int i = 0; i < arg_count; i++) {
2709 VisitForStackValue(args->at(i));
2710 }
2711 }
2712
2713 // Record source position for debugger.
2714 SetSourcePosition(expr->position());
2715 CallFunctionStub stub(arg_count, CALL_AS_METHOD);
2716 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2717 __ CallStub(&stub);
2718
2719 RecordJSReturnSite(expr);
2720 // Restore context register.
2721 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2722
2723 context()->DropAndPlug(1, r0);
2724 } 2687 }
2725 2688
2726 2689
2727 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2690 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
2728 // Code common for calls using the call stub. 2691 // Load the arguments.
2729 ZoneList<Expression*>* args = expr->arguments(); 2692 ZoneList<Expression*>* args = expr->arguments();
2730 int arg_count = args->length(); 2693 int arg_count = args->length();
2731 { PreservePositionScope scope(masm()->positions_recorder()); 2694 { PreservePositionScope scope(masm()->positions_recorder());
2732 for (int i = 0; i < arg_count; i++) { 2695 for (int i = 0; i < arg_count; i++) {
2733 VisitForStackValue(args->at(i)); 2696 VisitForStackValue(args->at(i));
2734 } 2697 }
2735 } 2698 }
2736 // Record source position for debugger. 2699
2700 // Record source position of the IC call.
2737 SetSourcePosition(expr->position()); 2701 SetSourcePosition(expr->position());
2738 2702 Handle<Code> ic = CallIC::initialize_stub(
2703 isolate(), arg_count, call_type);
2739 Handle<Object> uninitialized = 2704 Handle<Object> uninitialized =
2740 TypeFeedbackInfo::UninitializedSentinel(isolate()); 2705 TypeFeedbackInfo::UninitializedSentinel(isolate());
2741 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); 2706 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2742 __ Move(r2, FeedbackVector()); 2707 __ Move(r2, FeedbackVector());
2743 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); 2708 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2709 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2710 // Don't assign a type feedback id to the IC, since type feedback is provided
2711 // by the vector above.
2712 CallIC(ic);
2744 2713
2745 // Record call targets in unoptimized code.
2746 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2747 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2748 __ CallStub(&stub);
2749 RecordJSReturnSite(expr); 2714 RecordJSReturnSite(expr);
2750 // Restore context register. 2715 // Restore context register.
2751 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2716 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2752 context()->DropAndPlug(1, r0); 2717 context()->DropAndPlug(1, r0);
2753 } 2718 }
2754 2719
2755 2720
2756 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2721 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2757 // r4: copy of the first argument or undefined if it doesn't exist. 2722 // r4: copy of the first argument or undefined if it doesn't exist.
2758 if (arg_count > 0) { 2723 if (arg_count > 0) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2821 // Record source position for debugger. 2786 // Record source position for debugger.
2822 SetSourcePosition(expr->position()); 2787 SetSourcePosition(expr->position());
2823 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); 2788 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
2824 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2789 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2825 __ CallStub(&stub); 2790 __ CallStub(&stub);
2826 RecordJSReturnSite(expr); 2791 RecordJSReturnSite(expr);
2827 // Restore context register. 2792 // Restore context register.
2828 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2793 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2829 context()->DropAndPlug(1, r0); 2794 context()->DropAndPlug(1, r0);
2830 } else if (call_type == Call::GLOBAL_CALL) { 2795 } else if (call_type == Call::GLOBAL_CALL) {
2831 EmitCallWithIC(expr); 2796 EmitCallWithLoadIC(expr);
2832 2797
2833 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2798 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2834 // Call to a lookup slot (dynamically introduced variable). 2799 // Call to a lookup slot (dynamically introduced variable).
2835 VariableProxy* proxy = callee->AsVariableProxy(); 2800 VariableProxy* proxy = callee->AsVariableProxy();
2836 Label slow, done; 2801 Label slow, done;
2837 2802
2838 { PreservePositionScope scope(masm()->positions_recorder()); 2803 { PreservePositionScope scope(masm()->positions_recorder());
2839 // Generate code for loading from variables potentially shadowed 2804 // Generate code for loading from variables potentially shadowed
2840 // by eval-introduced variables. 2805 // by eval-introduced variables.
2841 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2806 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 19 matching lines...) Expand all
2861 __ push(r0); 2826 __ push(r0);
2862 // The receiver is implicitly the global receiver. Indicate this 2827 // The receiver is implicitly the global receiver. Indicate this
2863 // by passing the hole to the call function stub. 2828 // by passing the hole to the call function stub.
2864 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2829 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2865 __ push(r1); 2830 __ push(r1);
2866 __ bind(&call); 2831 __ bind(&call);
2867 } 2832 }
2868 2833
2869 // The receiver is either the global receiver or an object found 2834 // The receiver is either the global receiver or an object found
2870 // by LoadContextSlot. 2835 // by LoadContextSlot.
2871 EmitCallWithStub(expr); 2836 EmitCall(expr);
2872 } else if (call_type == Call::PROPERTY_CALL) { 2837 } else if (call_type == Call::PROPERTY_CALL) {
2873 Property* property = callee->AsProperty(); 2838 Property* property = callee->AsProperty();
2874 { PreservePositionScope scope(masm()->positions_recorder()); 2839 { PreservePositionScope scope(masm()->positions_recorder());
2875 VisitForStackValue(property->obj()); 2840 VisitForStackValue(property->obj());
2876 } 2841 }
2877 if (property->key()->IsPropertyName()) { 2842 if (property->key()->IsPropertyName()) {
2878 EmitCallWithIC(expr); 2843 EmitCallWithLoadIC(expr);
2879 } else { 2844 } else {
2880 EmitKeyedCallWithIC(expr, property->key()); 2845 EmitKeyedCallWithLoadIC(expr, property->key());
2881 } 2846 }
2882 } else { 2847 } else {
2883 ASSERT(call_type == Call::OTHER_CALL); 2848 ASSERT(call_type == Call::OTHER_CALL);
2884 // Call to an arbitrary expression not handled specially above. 2849 // Call to an arbitrary expression not handled specially above.
2885 { PreservePositionScope scope(masm()->positions_recorder()); 2850 { PreservePositionScope scope(masm()->positions_recorder());
2886 VisitForStackValue(callee); 2851 VisitForStackValue(callee);
2887 } 2852 }
2888 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2853 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2889 __ push(r1); 2854 __ push(r1);
2890 // Emit function call. 2855 // Emit function call.
2891 EmitCallWithStub(expr); 2856 EmitCall(expr);
2892 } 2857 }
2893 2858
2894 #ifdef DEBUG 2859 #ifdef DEBUG
2895 // RecordJSReturnSite should have been called. 2860 // RecordJSReturnSite should have been called.
2896 ASSERT(expr->return_is_recorded_); 2861 ASSERT(expr->return_is_recorded_);
2897 #endif 2862 #endif
2898 } 2863 }
2899 2864
2900 2865
2901 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2866 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 29 matching lines...) Expand all
2931 if (FLAG_pretenuring_call_new) { 2896 if (FLAG_pretenuring_call_new) {
2932 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), 2897 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
2933 isolate()->factory()->NewAllocationSite()); 2898 isolate()->factory()->NewAllocationSite());
2934 ASSERT(expr->AllocationSiteFeedbackSlot() == 2899 ASSERT(expr->AllocationSiteFeedbackSlot() ==
2935 expr->CallNewFeedbackSlot() + 1); 2900 expr->CallNewFeedbackSlot() + 1);
2936 } 2901 }
2937 2902
2938 __ Move(r2, FeedbackVector()); 2903 __ Move(r2, FeedbackVector());
2939 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2904 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2940 2905
2941 CallConstructStub stub(RECORD_CALL_TARGET); 2906 CallConstructStub stub(RECORD_CONSTRUCTOR_TARGET);
2942 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2907 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2943 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2908 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2944 context()->Plug(r0); 2909 context()->Plug(r0);
2945 } 2910 }
2946 2911
2947 2912
2948 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2913 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2949 ZoneList<Expression*>* args = expr->arguments(); 2914 ZoneList<Expression*>* args = expr->arguments();
2950 ASSERT(args->length() == 1); 2915 ASSERT(args->length() == 1);
2951 2916
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 4892
4928 ASSERT(interrupt_address == 4893 ASSERT(interrupt_address ==
4929 isolate->builtins()->OsrAfterStackCheck()->entry()); 4894 isolate->builtins()->OsrAfterStackCheck()->entry());
4930 return OSR_AFTER_STACK_CHECK; 4895 return OSR_AFTER_STACK_CHECK;
4931 } 4896 }
4932 4897
4933 4898
4934 } } // namespace v8::internal 4899 } } // namespace v8::internal
4935 4900
4936 #endif // V8_TARGET_ARCH_ARM 4901 #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