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

Side by Side Diff: src/ia32/full-codegen-ia32.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/ia32/debug-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.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_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "code-stubs.h" 9 #include "code-stubs.h"
10 #include "codegen.h" 10 #include "codegen.h"
(...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 } 2550 }
2551 2551
2552 2552
2553 void FullCodeGenerator::CallIC(Handle<Code> code, 2553 void FullCodeGenerator::CallIC(Handle<Code> code,
2554 TypeFeedbackId ast_id) { 2554 TypeFeedbackId ast_id) {
2555 ic_total_count_++; 2555 ic_total_count_++;
2556 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2556 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2557 } 2557 }
2558 2558
2559 2559
2560 // Code common for calls using the IC.
2561 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2562 Expression* callee = expr->expression();
2560 2563
2561 2564 CallIC::CallType call_type = callee->IsVariableProxy()
2562 // Code common for calls using the IC. 2565 ? CallIC::FUNCTION
2563 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2566 : CallIC::METHOD;
2564 Expression* callee = expr->expression();
2565 ZoneList<Expression*>* args = expr->arguments();
2566 int arg_count = args->length();
2567
2568 CallFunctionFlags flags;
2569 // Get the target function. 2567 // Get the target function.
2570 if (callee->IsVariableProxy()) { 2568 if (call_type == CallIC::FUNCTION) {
2571 { StackValueContext context(this); 2569 { StackValueContext context(this);
2572 EmitVariableLoad(callee->AsVariableProxy()); 2570 EmitVariableLoad(callee->AsVariableProxy());
2573 PrepareForBailout(callee, NO_REGISTERS); 2571 PrepareForBailout(callee, NO_REGISTERS);
2574 } 2572 }
2575 // Push undefined as receiver. This is patched in the method prologue if it 2573 // Push undefined as receiver. This is patched in the method prologue if it
2576 // is a sloppy mode method. 2574 // is a sloppy mode method.
2577 __ push(Immediate(isolate()->factory()->undefined_value())); 2575 __ push(Immediate(isolate()->factory()->undefined_value()));
2578 flags = NO_CALL_FUNCTION_FLAGS;
2579 } else { 2576 } else {
2580 // Load the function from the receiver. 2577 // Load the function from the receiver.
2581 ASSERT(callee->IsProperty()); 2578 ASSERT(callee->IsProperty());
2582 __ mov(edx, Operand(esp, 0)); 2579 __ mov(edx, Operand(esp, 0));
2583 EmitNamedPropertyLoad(callee->AsProperty()); 2580 EmitNamedPropertyLoad(callee->AsProperty());
2584 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2581 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2585 // Push the target function under the receiver. 2582 // Push the target function under the receiver.
2586 __ push(Operand(esp, 0)); 2583 __ push(Operand(esp, 0));
2587 __ mov(Operand(esp, kPointerSize), eax); 2584 __ mov(Operand(esp, kPointerSize), eax);
2588 flags = CALL_AS_METHOD;
2589 } 2585 }
2590 2586
2591 // Load the arguments. 2587 EmitCall(expr, call_type);
2592 { PreservePositionScope scope(masm()->positions_recorder());
2593 for (int i = 0; i < arg_count; i++) {
2594 VisitForStackValue(args->at(i));
2595 }
2596 }
2597
2598 // Record source position of the IC call.
2599 SetSourcePosition(expr->position());
2600 CallFunctionStub stub(isolate(), arg_count, flags);
2601 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2602 __ CallStub(&stub);
2603 RecordJSReturnSite(expr);
2604
2605 // Restore context register.
2606 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2607
2608 context()->DropAndPlug(1, eax);
2609 } 2588 }
2610 2589
2611 2590
2612 // Code common for calls using the IC. 2591 // Code common for calls using the IC.
2613 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2592 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2614 Expression* key) { 2593 Expression* key) {
2615 // Load the key. 2594 // Load the key.
2616 VisitForAccumulatorValue(key); 2595 VisitForAccumulatorValue(key);
2617 2596
2618 Expression* callee = expr->expression(); 2597 Expression* callee = expr->expression();
2619 ZoneList<Expression*>* args = expr->arguments();
2620 int arg_count = args->length();
2621 2598
2622 // Load the function from the receiver. 2599 // Load the function from the receiver.
2623 ASSERT(callee->IsProperty()); 2600 ASSERT(callee->IsProperty());
2624 __ mov(edx, Operand(esp, 0)); 2601 __ mov(edx, Operand(esp, 0));
2625 // Move the key into the right register for the keyed load IC. 2602 // Move the key into the right register for the keyed load IC.
2626 __ mov(ecx, eax); 2603 __ mov(ecx, eax);
2627 EmitKeyedPropertyLoad(callee->AsProperty()); 2604 EmitKeyedPropertyLoad(callee->AsProperty());
2628 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2605 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2629 2606
2630 // Push the target function under the receiver. 2607 // Push the target function under the receiver.
2631 __ push(Operand(esp, 0)); 2608 __ push(Operand(esp, 0));
2632 __ mov(Operand(esp, kPointerSize), eax); 2609 __ mov(Operand(esp, kPointerSize), eax);
2633 2610
2634 // Load the arguments. 2611 EmitCall(expr, CallIC::METHOD);
2635 { PreservePositionScope scope(masm()->positions_recorder());
2636 for (int i = 0; i < arg_count; i++) {
2637 VisitForStackValue(args->at(i));
2638 }
2639 }
2640
2641 // Record source position of the IC call.
2642 SetSourcePosition(expr->position());
2643 CallFunctionStub stub(isolate(), arg_count, CALL_AS_METHOD);
2644 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2645 __ CallStub(&stub);
2646 RecordJSReturnSite(expr);
2647
2648 // Restore context register.
2649 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2650
2651 context()->DropAndPlug(1, eax);
2652 } 2612 }
2653 2613
2654 2614
2655 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2615 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
2656 // Code common for calls using the call stub. 2616 // Load the arguments.
2657 ZoneList<Expression*>* args = expr->arguments(); 2617 ZoneList<Expression*>* args = expr->arguments();
2658 int arg_count = args->length(); 2618 int arg_count = args->length();
2659 { PreservePositionScope scope(masm()->positions_recorder()); 2619 { PreservePositionScope scope(masm()->positions_recorder());
2660 for (int i = 0; i < arg_count; i++) { 2620 for (int i = 0; i < arg_count; i++) {
2661 VisitForStackValue(args->at(i)); 2621 VisitForStackValue(args->at(i));
2662 } 2622 }
2663 } 2623 }
2664 // Record source position for debugger. 2624
2625 // Record source position of the IC call.
2665 SetSourcePosition(expr->position()); 2626 SetSourcePosition(expr->position());
2666 2627 Handle<Code> ic = CallIC::initialize_stub(
2667 __ LoadHeapObject(ebx, FeedbackVector()); 2628 isolate(), arg_count, call_type);
2668 __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot()))); 2629 __ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
2669
2670 // Record call targets in unoptimized code.
2671 CallFunctionStub stub(isolate(), arg_count, RECORD_CALL_TARGET);
2672 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2630 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2673 __ CallStub(&stub); 2631 // Don't assign a type feedback id to the IC, since type feedback is provided
2632 // by the vector above.
2633 CallIC(ic);
2674 2634
2675 RecordJSReturnSite(expr); 2635 RecordJSReturnSite(expr);
2636
2676 // Restore context register. 2637 // Restore context register.
2677 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2638 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2639
2678 context()->DropAndPlug(1, eax); 2640 context()->DropAndPlug(1, eax);
2679 } 2641 }
2680 2642
2681 2643
2682 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2644 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2683 // Push copy of the first argument or undefined if it doesn't exist. 2645 // Push copy of the first argument or undefined if it doesn't exist.
2684 if (arg_count > 0) { 2646 if (arg_count > 0) {
2685 __ push(Operand(esp, arg_count * kPointerSize)); 2647 __ push(Operand(esp, arg_count * kPointerSize));
2686 } else { 2648 } else {
2687 __ push(Immediate(isolate()->factory()->undefined_value())); 2649 __ push(Immediate(isolate()->factory()->undefined_value()));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2740 SetSourcePosition(expr->position()); 2702 SetSourcePosition(expr->position());
2741 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 2703 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
2742 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2704 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2743 __ CallStub(&stub); 2705 __ CallStub(&stub);
2744 RecordJSReturnSite(expr); 2706 RecordJSReturnSite(expr);
2745 // Restore context register. 2707 // Restore context register.
2746 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2708 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2747 context()->DropAndPlug(1, eax); 2709 context()->DropAndPlug(1, eax);
2748 2710
2749 } else if (call_type == Call::GLOBAL_CALL) { 2711 } else if (call_type == Call::GLOBAL_CALL) {
2750 EmitCallWithIC(expr); 2712 EmitCallWithLoadIC(expr);
2751 2713
2752 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2714 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2753 // Call to a lookup slot (dynamically introduced variable). 2715 // Call to a lookup slot (dynamically introduced variable).
2754 VariableProxy* proxy = callee->AsVariableProxy(); 2716 VariableProxy* proxy = callee->AsVariableProxy();
2755 Label slow, done; 2717 Label slow, done;
2756 { PreservePositionScope scope(masm()->positions_recorder()); 2718 { PreservePositionScope scope(masm()->positions_recorder());
2757 // Generate code for loading from variables potentially shadowed by 2719 // Generate code for loading from variables potentially shadowed by
2758 // eval-introduced variables. 2720 // eval-introduced variables.
2759 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2721 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2760 } 2722 }
(...skipping 15 matching lines...) Expand all
2776 // Push function. 2738 // Push function.
2777 __ push(eax); 2739 __ push(eax);
2778 // The receiver is implicitly the global receiver. Indicate this by 2740 // The receiver is implicitly the global receiver. Indicate this by
2779 // passing the hole to the call function stub. 2741 // passing the hole to the call function stub.
2780 __ push(Immediate(isolate()->factory()->undefined_value())); 2742 __ push(Immediate(isolate()->factory()->undefined_value()));
2781 __ bind(&call); 2743 __ bind(&call);
2782 } 2744 }
2783 2745
2784 // The receiver is either the global receiver or an object found by 2746 // The receiver is either the global receiver or an object found by
2785 // LoadContextSlot. 2747 // LoadContextSlot.
2786 EmitCallWithStub(expr); 2748 EmitCall(expr);
2787 2749
2788 } else if (call_type == Call::PROPERTY_CALL) { 2750 } else if (call_type == Call::PROPERTY_CALL) {
2789 Property* property = callee->AsProperty(); 2751 Property* property = callee->AsProperty();
2790 { PreservePositionScope scope(masm()->positions_recorder()); 2752 { PreservePositionScope scope(masm()->positions_recorder());
2791 VisitForStackValue(property->obj()); 2753 VisitForStackValue(property->obj());
2792 } 2754 }
2793 if (property->key()->IsPropertyName()) { 2755 if (property->key()->IsPropertyName()) {
2794 EmitCallWithIC(expr); 2756 EmitCallWithLoadIC(expr);
2795 } else { 2757 } else {
2796 EmitKeyedCallWithIC(expr, property->key()); 2758 EmitKeyedCallWithLoadIC(expr, property->key());
2797 } 2759 }
2798 2760
2799 } else { 2761 } else {
2800 ASSERT(call_type == Call::OTHER_CALL); 2762 ASSERT(call_type == Call::OTHER_CALL);
2801 // Call to an arbitrary expression not handled specially above. 2763 // Call to an arbitrary expression not handled specially above.
2802 { PreservePositionScope scope(masm()->positions_recorder()); 2764 { PreservePositionScope scope(masm()->positions_recorder());
2803 VisitForStackValue(callee); 2765 VisitForStackValue(callee);
2804 } 2766 }
2805 __ push(Immediate(isolate()->factory()->undefined_value())); 2767 __ push(Immediate(isolate()->factory()->undefined_value()));
2806 // Emit function call. 2768 // Emit function call.
2807 EmitCallWithStub(expr); 2769 EmitCall(expr);
2808 } 2770 }
2809 2771
2810 #ifdef DEBUG 2772 #ifdef DEBUG
2811 // RecordJSReturnSite should have been called. 2773 // RecordJSReturnSite should have been called.
2812 ASSERT(expr->return_is_recorded_); 2774 ASSERT(expr->return_is_recorded_);
2813 #endif 2775 #endif
2814 } 2776 }
2815 2777
2816 2778
2817 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2779 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 25 matching lines...) Expand all
2843 // Record call targets in unoptimized code. 2805 // Record call targets in unoptimized code.
2844 if (FLAG_pretenuring_call_new) { 2806 if (FLAG_pretenuring_call_new) {
2845 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 2807 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
2846 ASSERT(expr->AllocationSiteFeedbackSlot() == 2808 ASSERT(expr->AllocationSiteFeedbackSlot() ==
2847 expr->CallNewFeedbackSlot() + 1); 2809 expr->CallNewFeedbackSlot() + 1);
2848 } 2810 }
2849 2811
2850 __ LoadHeapObject(ebx, FeedbackVector()); 2812 __ LoadHeapObject(ebx, FeedbackVector());
2851 __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2813 __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
2852 2814
2853 CallConstructStub stub(isolate(), RECORD_CALL_TARGET); 2815 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
2854 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 2816 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
2855 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2817 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2856 context()->Plug(eax); 2818 context()->Plug(eax);
2857 } 2819 }
2858 2820
2859 2821
2860 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2822 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2861 ZoneList<Expression*>* args = expr->arguments(); 2823 ZoneList<Expression*>* args = expr->arguments();
2862 ASSERT(args->length() == 1); 2824 ASSERT(args->length() == 1);
2863 2825
(...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after
4887 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4849 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4888 Assembler::target_address_at(call_target_address, 4850 Assembler::target_address_at(call_target_address,
4889 unoptimized_code)); 4851 unoptimized_code));
4890 return OSR_AFTER_STACK_CHECK; 4852 return OSR_AFTER_STACK_CHECK;
4891 } 4853 }
4892 4854
4893 4855
4894 } } // namespace v8::internal 4856 } } // namespace v8::internal
4895 4857
4896 #endif // V8_TARGET_ARCH_IA32 4858 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/debug-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698