OLD | NEW |
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 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 2059 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
2060 Label l_next, l_call, l_loop; | 2060 Label l_next, l_call, l_loop; |
2061 // Initial send value is undefined. | 2061 // Initial send value is undefined. |
2062 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 2062 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
2063 __ Branch(&l_next); | 2063 __ Branch(&l_next); |
2064 | 2064 |
2065 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2065 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
2066 __ bind(&l_catch); | 2066 __ bind(&l_catch); |
2067 __ mov(a0, v0); | 2067 __ mov(a0, v0); |
2068 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2068 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
2069 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" | 2069 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" |
2070 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2070 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2071 __ Push(a3, a0); // iter, exception | 2071 __ Push(a2, a3, a0); // "throw", iter, except |
2072 __ jmp(&l_call); | 2072 __ jmp(&l_call); |
2073 | 2073 |
2074 // try { received = %yield result } | 2074 // try { received = %yield result } |
2075 // Shuffle the received result above a try handler and yield it without | 2075 // Shuffle the received result above a try handler and yield it without |
2076 // re-boxing. | 2076 // re-boxing. |
2077 __ bind(&l_try); | 2077 __ bind(&l_try); |
2078 __ pop(a0); // result | 2078 __ pop(a0); // result |
2079 __ PushTryHandler(StackHandler::CATCH, expr->index()); | 2079 __ PushTryHandler(StackHandler::CATCH, expr->index()); |
2080 const int handler_size = StackHandlerConstants::kSize; | 2080 const int handler_size = StackHandlerConstants::kSize; |
2081 __ push(a0); // result | 2081 __ push(a0); // result |
2082 __ jmp(&l_suspend); | 2082 __ jmp(&l_suspend); |
2083 __ bind(&l_continuation); | 2083 __ bind(&l_continuation); |
2084 __ mov(a0, v0); | 2084 __ mov(a0, v0); |
2085 __ jmp(&l_resume); | 2085 __ jmp(&l_resume); |
2086 __ bind(&l_suspend); | 2086 __ bind(&l_suspend); |
2087 const int generator_object_depth = kPointerSize + handler_size; | 2087 const int generator_object_depth = kPointerSize + handler_size; |
2088 __ lw(a0, MemOperand(sp, generator_object_depth)); | 2088 __ lw(a0, MemOperand(sp, generator_object_depth)); |
2089 __ push(a0); // g | 2089 __ push(a0); // g |
2090 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2090 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
2091 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); | 2091 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); |
2092 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); | 2092 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); |
2093 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); | 2093 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); |
2094 __ mov(a1, cp); | 2094 __ mov(a1, cp); |
2095 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, | 2095 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, |
2096 kRAHasBeenSaved, kDontSaveFPRegs); | 2096 kRAHasBeenSaved, kDontSaveFPRegs); |
2097 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2097 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
2098 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2098 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2099 __ pop(v0); // result | 2099 __ pop(v0); // result |
2100 EmitReturnSequence(); | 2100 EmitReturnSequence(); |
2101 __ mov(a0, v0); | 2101 __ mov(a0, v0); |
2102 __ bind(&l_resume); // received in a0 | 2102 __ bind(&l_resume); // received in a0 |
2103 __ PopTryHandler(); | 2103 __ PopTryHandler(); |
2104 | 2104 |
2105 // receiver = iter; f = 'next'; arg = received; | 2105 // receiver = iter; f = 'next'; arg = received; |
2106 __ bind(&l_next); | 2106 __ bind(&l_next); |
2107 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" | 2107 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" |
2108 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2108 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2109 __ Push(a3, a0); // iter, received | 2109 __ Push(a2, a3, a0); // "next", iter, received |
2110 | 2110 |
2111 // result = receiver[f](arg); | 2111 // result = receiver[f](arg); |
2112 __ bind(&l_call); | 2112 __ bind(&l_call); |
2113 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2113 __ lw(a1, MemOperand(sp, kPointerSize)); |
2114 CallIC(ic); | 2114 __ lw(a0, MemOperand(sp, 2 * kPointerSize)); |
| 2115 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2116 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); |
| 2117 __ mov(a0, v0); |
| 2118 __ mov(a1, a0); |
| 2119 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); |
| 2120 CallFunctionStub stub(1, CALL_AS_METHOD); |
| 2121 __ CallStub(&stub); |
| 2122 |
2115 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2123 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2124 __ Drop(1); // The function is still on the stack; drop it. |
2116 | 2125 |
2117 // if (!result.done) goto l_try; | 2126 // if (!result.done) goto l_try; |
2118 __ bind(&l_loop); | 2127 __ bind(&l_loop); |
2119 __ mov(a0, v0); | 2128 __ mov(a0, v0); |
2120 __ push(a0); // save result | 2129 __ push(a0); // save result |
2121 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" | 2130 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" |
2122 CallLoadIC(NOT_CONTEXTUAL); // result.done in v0 | 2131 CallLoadIC(NOT_CONTEXTUAL); // result.done in v0 |
2123 __ mov(a0, v0); | 2132 __ mov(a0, v0); |
2124 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2133 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2125 CallIC(bool_ic); | 2134 CallIC(bool_ic); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2628 | 2637 |
2629 void FullCodeGenerator::CallIC(Handle<Code> code, | 2638 void FullCodeGenerator::CallIC(Handle<Code> code, |
2630 ContextualMode mode, | 2639 ContextualMode mode, |
2631 TypeFeedbackId id) { | 2640 TypeFeedbackId id) { |
2632 ic_total_count_++; | 2641 ic_total_count_++; |
2633 ASSERT(mode != CONTEXTUAL || id.IsNone()); | 2642 ASSERT(mode != CONTEXTUAL || id.IsNone()); |
2634 __ Call(code, RelocInfo::CODE_TARGET, id); | 2643 __ Call(code, RelocInfo::CODE_TARGET, id); |
2635 } | 2644 } |
2636 | 2645 |
2637 | 2646 |
2638 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2647 // Code common for calls using the IC. |
2639 Handle<Object> name, | 2648 void FullCodeGenerator::EmitCallWithIC(Call* expr) { |
2640 ContextualMode mode) { | 2649 Expression* callee = expr->expression(); |
2641 // Code common for calls using the IC. | |
2642 ZoneList<Expression*>* args = expr->arguments(); | 2650 ZoneList<Expression*>* args = expr->arguments(); |
2643 int arg_count = args->length(); | 2651 int arg_count = args->length(); |
2644 { PreservePositionScope scope(masm()->positions_recorder()); | 2652 |
2645 for (int i = 0; i < arg_count; i++) { | 2653 CallFunctionFlags flags; |
2646 VisitForStackValue(args->at(i)); | 2654 // Get the target function. |
| 2655 if (callee->IsVariableProxy()) { |
| 2656 { StackValueContext context(this); |
| 2657 EmitVariableLoad(callee->AsVariableProxy()); |
| 2658 PrepareForBailout(callee, NO_REGISTERS); |
2647 } | 2659 } |
2648 __ li(a2, Operand(name)); | 2660 // Push undefined as receiver. This is patched in the method prologue if it |
| 2661 // is a classic mode method. |
| 2662 __ Push(isolate()->factory()->undefined_value()); |
| 2663 flags = NO_CALL_FUNCTION_FLAGS; |
| 2664 } else { |
| 2665 // Load the function from the receiver. |
| 2666 ASSERT(callee->IsProperty()); |
| 2667 __ lw(v0, MemOperand(sp, 0)); |
| 2668 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2669 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2670 // Push the target function under the receiver. |
| 2671 __ lw(at, MemOperand(sp, 0)); |
| 2672 __ push(at); |
| 2673 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2674 flags = CALL_AS_METHOD; |
2649 } | 2675 } |
2650 // Record source position for debugger. | |
2651 SetSourcePosition(expr->position()); | |
2652 // Call the IC initialization code. | |
2653 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); | |
2654 TypeFeedbackId ast_id = mode == CONTEXTUAL | |
2655 ? TypeFeedbackId::None() | |
2656 : expr->CallFeedbackId(); | |
2657 CallIC(ic, mode, ast_id); | |
2658 RecordJSReturnSite(expr); | |
2659 // Restore context register. | |
2660 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2661 context()->Plug(v0); | |
2662 } | |
2663 | 2676 |
2664 | 2677 // Load the arguments. |
2665 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | |
2666 Expression* key) { | |
2667 // Load the key. | |
2668 VisitForAccumulatorValue(key); | |
2669 | |
2670 // Swap the name of the function and the receiver on the stack to follow | |
2671 // the calling convention for call ICs. | |
2672 __ pop(a1); | |
2673 __ push(v0); | |
2674 __ push(a1); | |
2675 | |
2676 // Code common for calls using the IC. | |
2677 ZoneList<Expression*>* args = expr->arguments(); | |
2678 int arg_count = args->length(); | |
2679 { PreservePositionScope scope(masm()->positions_recorder()); | 2678 { PreservePositionScope scope(masm()->positions_recorder()); |
2680 for (int i = 0; i < arg_count; i++) { | 2679 for (int i = 0; i < arg_count; i++) { |
2681 VisitForStackValue(args->at(i)); | 2680 VisitForStackValue(args->at(i)); |
2682 } | 2681 } |
2683 } | 2682 } |
2684 // Record source position for debugger. | 2683 // Record source position for debugger. |
2685 SetSourcePosition(expr->position()); | 2684 SetSourcePosition(expr->position()); |
2686 // Call the IC initialization code. | 2685 CallFunctionStub stub(arg_count, flags); |
2687 Handle<Code> ic = | 2686 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2688 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2687 __ CallStub(&stub); |
2689 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2688 |
2690 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); | 2689 RecordJSReturnSite(expr); |
| 2690 |
| 2691 // Restore context register. |
| 2692 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2693 |
| 2694 context()->DropAndPlug(1, v0); |
| 2695 } |
| 2696 |
| 2697 |
| 2698 // Code common for calls using the IC. |
| 2699 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2700 Expression* key) { |
| 2701 // Load the key. |
| 2702 VisitForAccumulatorValue(key); |
| 2703 |
| 2704 Expression* callee = expr->expression(); |
| 2705 ZoneList<Expression*>* args = expr->arguments(); |
| 2706 int arg_count = args->length(); |
| 2707 |
| 2708 // Load the function from the receiver. |
| 2709 ASSERT(callee->IsProperty()); |
| 2710 __ lw(a1, MemOperand(sp, 0)); |
| 2711 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2712 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2713 |
| 2714 // Push the target function under the receiver. |
| 2715 __ lw(at, MemOperand(sp, 0)); |
| 2716 __ push(at); |
| 2717 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2718 |
| 2719 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2720 for (int i = 0; i < arg_count; i++) { |
| 2721 VisitForStackValue(args->at(i)); |
| 2722 } |
| 2723 } |
| 2724 |
| 2725 // Record source position for debugger. |
| 2726 SetSourcePosition(expr->position()); |
| 2727 CallFunctionStub stub(arg_count, CALL_AS_METHOD); |
| 2728 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2729 __ CallStub(&stub); |
| 2730 |
2691 RecordJSReturnSite(expr); | 2731 RecordJSReturnSite(expr); |
2692 // Restore context register. | 2732 // Restore context register. |
2693 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2733 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2694 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2734 |
| 2735 context()->DropAndPlug(1, v0); |
2695 } | 2736 } |
2696 | 2737 |
2697 | 2738 |
2698 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2739 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
2699 // Code common for calls using the call stub. | 2740 // Code common for calls using the call stub. |
2700 ZoneList<Expression*>* args = expr->arguments(); | 2741 ZoneList<Expression*>* args = expr->arguments(); |
2701 int arg_count = args->length(); | 2742 int arg_count = args->length(); |
2702 { PreservePositionScope scope(masm()->positions_recorder()); | 2743 { PreservePositionScope scope(masm()->positions_recorder()); |
2703 for (int i = 0; i < arg_count; i++) { | 2744 for (int i = 0; i < arg_count; i++) { |
2704 VisitForStackValue(args->at(i)); | 2745 VisitForStackValue(args->at(i)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 // Record source position for debugger. | 2832 // Record source position for debugger. |
2792 SetSourcePosition(expr->position()); | 2833 SetSourcePosition(expr->position()); |
2793 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2834 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |
2794 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2835 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2795 __ CallStub(&stub); | 2836 __ CallStub(&stub); |
2796 RecordJSReturnSite(expr); | 2837 RecordJSReturnSite(expr); |
2797 // Restore context register. | 2838 // Restore context register. |
2798 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2839 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2799 context()->DropAndPlug(1, v0); | 2840 context()->DropAndPlug(1, v0); |
2800 } else if (call_type == Call::GLOBAL_CALL) { | 2841 } else if (call_type == Call::GLOBAL_CALL) { |
2801 // Push global object as receiver for the call IC. | 2842 EmitCallWithIC(expr); |
2802 __ lw(a0, GlobalObjectOperand()); | |
2803 __ push(a0); | |
2804 VariableProxy* proxy = callee->AsVariableProxy(); | |
2805 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); | |
2806 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2843 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
2807 // Call to a lookup slot (dynamically introduced variable). | 2844 // Call to a lookup slot (dynamically introduced variable). |
2808 VariableProxy* proxy = callee->AsVariableProxy(); | 2845 VariableProxy* proxy = callee->AsVariableProxy(); |
2809 Label slow, done; | 2846 Label slow, done; |
2810 | 2847 |
2811 { PreservePositionScope scope(masm()->positions_recorder()); | 2848 { PreservePositionScope scope(masm()->positions_recorder()); |
2812 // Generate code for loading from variables potentially shadowed | 2849 // Generate code for loading from variables potentially shadowed |
2813 // by eval-introduced variables. | 2850 // by eval-introduced variables. |
2814 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2851 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2815 } | 2852 } |
(...skipping 25 matching lines...) Expand all Loading... |
2841 | 2878 |
2842 // The receiver is either the global receiver or an object found | 2879 // The receiver is either the global receiver or an object found |
2843 // by LoadContextSlot. | 2880 // by LoadContextSlot. |
2844 EmitCallWithStub(expr); | 2881 EmitCallWithStub(expr); |
2845 } else if (call_type == Call::PROPERTY_CALL) { | 2882 } else if (call_type == Call::PROPERTY_CALL) { |
2846 Property* property = callee->AsProperty(); | 2883 Property* property = callee->AsProperty(); |
2847 { PreservePositionScope scope(masm()->positions_recorder()); | 2884 { PreservePositionScope scope(masm()->positions_recorder()); |
2848 VisitForStackValue(property->obj()); | 2885 VisitForStackValue(property->obj()); |
2849 } | 2886 } |
2850 if (property->key()->IsPropertyName()) { | 2887 if (property->key()->IsPropertyName()) { |
2851 EmitCallWithIC(expr, | 2888 EmitCallWithIC(expr); |
2852 property->key()->AsLiteral()->value(), | |
2853 NOT_CONTEXTUAL); | |
2854 } else { | 2889 } else { |
2855 EmitKeyedCallWithIC(expr, property->key()); | 2890 EmitKeyedCallWithIC(expr, property->key()); |
2856 } | 2891 } |
2857 } else { | 2892 } else { |
2858 ASSERT(call_type == Call::OTHER_CALL); | 2893 ASSERT(call_type == Call::OTHER_CALL); |
2859 // Call to an arbitrary expression not handled specially above. | 2894 // Call to an arbitrary expression not handled specially above. |
2860 { PreservePositionScope scope(masm()->positions_recorder()); | 2895 { PreservePositionScope scope(masm()->positions_recorder()); |
2861 VisitForStackValue(callee); | 2896 VisitForStackValue(callee); |
2862 } | 2897 } |
2863 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 2898 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
(...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4153 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4188 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4154 Handle<String> name = expr->name(); | 4189 Handle<String> name = expr->name(); |
4155 if (name->length() > 0 && name->Get(0) == '_') { | 4190 if (name->length() > 0 && name->Get(0) == '_') { |
4156 Comment cmnt(masm_, "[ InlineRuntimeCall"); | 4191 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
4157 EmitInlineRuntimeCall(expr); | 4192 EmitInlineRuntimeCall(expr); |
4158 return; | 4193 return; |
4159 } | 4194 } |
4160 | 4195 |
4161 Comment cmnt(masm_, "[ CallRuntime"); | 4196 Comment cmnt(masm_, "[ CallRuntime"); |
4162 ZoneList<Expression*>* args = expr->arguments(); | 4197 ZoneList<Expression*>* args = expr->arguments(); |
| 4198 int arg_count = args->length(); |
4163 | 4199 |
4164 if (expr->is_jsruntime()) { | 4200 if (expr->is_jsruntime()) { |
4165 // Prepare for calling JS runtime function. | 4201 // Push the builtins object as the receiver. |
4166 __ lw(a0, GlobalObjectOperand()); | 4202 __ lw(a0, GlobalObjectOperand()); |
4167 __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset)); | 4203 __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset)); |
4168 __ push(a0); | 4204 __ push(a0); |
4169 } | 4205 // Load the function from the receiver. |
| 4206 __ li(a2, Operand(expr->name())); |
| 4207 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4170 | 4208 |
4171 // Push the arguments ("left-to-right"). | 4209 // Push the target function under the receiver. |
4172 int arg_count = args->length(); | 4210 __ lw(at, MemOperand(sp, 0)); |
4173 for (int i = 0; i < arg_count; i++) { | 4211 __ push(at); |
4174 VisitForStackValue(args->at(i)); | 4212 __ sw(v0, MemOperand(sp, kPointerSize)); |
4175 } | |
4176 | 4213 |
4177 if (expr->is_jsruntime()) { | 4214 // Push the arguments ("left-to-right"). |
4178 // Call the JS runtime function. | 4215 int arg_count = args->length(); |
4179 __ li(a2, Operand(expr->name())); | 4216 for (int i = 0; i < arg_count; i++) { |
4180 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); | 4217 VisitForStackValue(args->at(i)); |
4181 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4218 } |
| 4219 |
| 4220 // Record source position of the IC call. |
| 4221 SetSourcePosition(expr->position()); |
| 4222 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4223 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 4224 __ CallStub(&stub); |
| 4225 |
4182 // Restore context register. | 4226 // Restore context register. |
4183 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4227 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4228 |
| 4229 context()->DropAndPlug(1, v0); |
4184 } else { | 4230 } else { |
| 4231 // Push the arguments ("left-to-right"). |
| 4232 for (int i = 0; i < arg_count; i++) { |
| 4233 VisitForStackValue(args->at(i)); |
| 4234 } |
| 4235 |
4185 // Call the C runtime function. | 4236 // Call the C runtime function. |
4186 __ CallRuntime(expr->function(), arg_count); | 4237 __ CallRuntime(expr->function(), arg_count); |
| 4238 context()->Plug(v0); |
4187 } | 4239 } |
4188 context()->Plug(v0); | |
4189 } | 4240 } |
4190 | 4241 |
4191 | 4242 |
4192 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4243 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
4193 switch (expr->op()) { | 4244 switch (expr->op()) { |
4194 case Token::DELETE: { | 4245 case Token::DELETE: { |
4195 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4246 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
4196 Property* property = expr->expression()->AsProperty(); | 4247 Property* property = expr->expression()->AsProperty(); |
4197 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4248 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4198 | 4249 |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4927 Assembler::target_address_at(pc_immediate_load_address)) == | 4978 Assembler::target_address_at(pc_immediate_load_address)) == |
4928 reinterpret_cast<uint32_t>( | 4979 reinterpret_cast<uint32_t>( |
4929 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4980 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4930 return OSR_AFTER_STACK_CHECK; | 4981 return OSR_AFTER_STACK_CHECK; |
4931 } | 4982 } |
4932 | 4983 |
4933 | 4984 |
4934 } } // namespace v8::internal | 4985 } } // namespace v8::internal |
4935 | 4986 |
4936 #endif // V8_TARGET_ARCH_MIPS | 4987 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |