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 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 | 2042 |
2043 Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 2043 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
2044 Label l_next, l_call, l_loop; | 2044 Label l_next, l_call, l_loop; |
2045 // Initial send value is undefined. | 2045 // Initial send value is undefined. |
2046 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 2046 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
2047 __ b(&l_next); | 2047 __ b(&l_next); |
2048 | 2048 |
2049 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2049 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
2050 __ bind(&l_catch); | 2050 __ bind(&l_catch); |
2051 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2051 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
2052 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" | 2052 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" |
2053 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2053 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
2054 __ Push(r3, r0); // iter, exception | 2054 __ Push(r2, r3, r0); // "throw", iter, except |
2055 __ jmp(&l_call); | 2055 __ jmp(&l_call); |
2056 | 2056 |
2057 // try { received = %yield result } | 2057 // try { received = %yield result } |
2058 // Shuffle the received result above a try handler and yield it without | 2058 // Shuffle the received result above a try handler and yield it without |
2059 // re-boxing. | 2059 // re-boxing. |
2060 __ bind(&l_try); | 2060 __ bind(&l_try); |
2061 __ pop(r0); // result | 2061 __ pop(r0); // result |
2062 __ PushTryHandler(StackHandler::CATCH, expr->index()); | 2062 __ PushTryHandler(StackHandler::CATCH, expr->index()); |
2063 const int handler_size = StackHandlerConstants::kSize; | 2063 const int handler_size = StackHandlerConstants::kSize; |
2064 __ push(r0); // result | 2064 __ push(r0); // result |
2065 __ jmp(&l_suspend); | 2065 __ jmp(&l_suspend); |
2066 __ bind(&l_continuation); | 2066 __ bind(&l_continuation); |
2067 __ jmp(&l_resume); | 2067 __ jmp(&l_resume); |
2068 __ bind(&l_suspend); | 2068 __ bind(&l_suspend); |
2069 const int generator_object_depth = kPointerSize + handler_size; | 2069 const int generator_object_depth = kPointerSize + handler_size; |
2070 __ ldr(r0, MemOperand(sp, generator_object_depth)); | 2070 __ ldr(r0, MemOperand(sp, generator_object_depth)); |
2071 __ push(r0); // g | 2071 __ push(r0); // g |
2072 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2072 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
2073 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); | 2073 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); |
2074 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 2074 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
2075 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 2075 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
2076 __ mov(r1, cp); | 2076 __ mov(r1, cp); |
2077 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 2077 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
2078 kLRHasBeenSaved, kDontSaveFPRegs); | 2078 kLRHasBeenSaved, kDontSaveFPRegs); |
2079 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2079 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
2080 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2080 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2081 __ pop(r0); // result | 2081 __ pop(r0); // result |
2082 EmitReturnSequence(); | 2082 EmitReturnSequence(); |
2083 __ bind(&l_resume); // received in r0 | 2083 __ bind(&l_resume); // received in r0 |
2084 __ PopTryHandler(); | 2084 __ PopTryHandler(); |
2085 | 2085 |
2086 // receiver = iter; f = 'next'; arg = received; | 2086 // receiver = iter; f = 'next'; arg = received; |
2087 __ bind(&l_next); | 2087 __ bind(&l_next); |
2088 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" | 2088 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" |
2089 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2089 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
2090 __ Push(r3, r0); // iter, received | 2090 __ Push(r2, r3, r0); // "next", iter, received |
2091 | 2091 |
2092 // result = receiver[f](arg); | 2092 // result = receiver[f](arg); |
2093 __ bind(&l_call); | 2093 __ bind(&l_call); |
2094 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2094 __ ldr(r1, MemOperand(sp, kPointerSize)); |
2095 CallIC(ic); | 2095 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); |
| 2096 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2097 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); |
| 2098 __ mov(r1, r0); |
| 2099 __ str(r1, MemOperand(sp, 2 * kPointerSize)); |
| 2100 CallFunctionStub stub(1, CALL_AS_METHOD); |
| 2101 __ CallStub(&stub); |
| 2102 |
2096 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2103 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2104 __ Drop(1); // The function is still on the stack; drop it. |
2097 | 2105 |
2098 // if (!result.done) goto l_try; | 2106 // if (!result.done) goto l_try; |
2099 __ bind(&l_loop); | 2107 __ bind(&l_loop); |
2100 __ push(r0); // save result | 2108 __ push(r0); // save result |
2101 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" | 2109 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" |
2102 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 | 2110 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 |
2103 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2111 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2104 CallIC(bool_ic); | 2112 CallIC(bool_ic); |
2105 __ cmp(r0, Operand(0)); | 2113 __ cmp(r0, Operand(0)); |
2106 __ b(eq, &l_try); | 2114 __ b(eq, &l_try); |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2594 ContextualMode mode, | 2602 ContextualMode mode, |
2595 TypeFeedbackId ast_id) { | 2603 TypeFeedbackId ast_id) { |
2596 ic_total_count_++; | 2604 ic_total_count_++; |
2597 // All calls must have a predictable size in full-codegen code to ensure that | 2605 // All calls must have a predictable size in full-codegen code to ensure that |
2598 // the debugger can patch them correctly. | 2606 // the debugger can patch them correctly. |
2599 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); | 2607 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
2600 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, | 2608 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, |
2601 NEVER_INLINE_TARGET_ADDRESS); | 2609 NEVER_INLINE_TARGET_ADDRESS); |
2602 } | 2610 } |
2603 | 2611 |
2604 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2612 |
2605 Handle<Object> name, | 2613 // Code common for calls using the IC. |
2606 ContextualMode mode) { | 2614 void FullCodeGenerator::EmitCallWithIC(Call* expr) { |
2607 // Code common for calls using the IC. | 2615 Expression* callee = expr->expression(); |
2608 ZoneList<Expression*>* args = expr->arguments(); | 2616 ZoneList<Expression*>* args = expr->arguments(); |
2609 int arg_count = args->length(); | 2617 int arg_count = args->length(); |
| 2618 |
| 2619 CallFunctionFlags flags; |
| 2620 // Get the target function. |
| 2621 if (callee->IsVariableProxy()) { |
| 2622 { StackValueContext context(this); |
| 2623 EmitVariableLoad(callee->AsVariableProxy()); |
| 2624 PrepareForBailout(callee, NO_REGISTERS); |
| 2625 } |
| 2626 // Push undefined as receiver. This is patched in the method prologue if it |
| 2627 // is a classic mode method. |
| 2628 __ Push(isolate()->factory()->undefined_value()); |
| 2629 flags = NO_CALL_FUNCTION_FLAGS; |
| 2630 } else { |
| 2631 // Load the function from the receiver. |
| 2632 ASSERT(callee->IsProperty()); |
| 2633 __ ldr(r0, MemOperand(sp, 0)); |
| 2634 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2635 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2636 // Push the target function under the receiver. |
| 2637 __ ldr(ip, MemOperand(sp, 0)); |
| 2638 __ push(ip); |
| 2639 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2640 flags = CALL_AS_METHOD; |
| 2641 } |
| 2642 |
| 2643 // Load the arguments. |
2610 { PreservePositionScope scope(masm()->positions_recorder()); | 2644 { PreservePositionScope scope(masm()->positions_recorder()); |
2611 for (int i = 0; i < arg_count; i++) { | 2645 for (int i = 0; i < arg_count; i++) { |
2612 VisitForStackValue(args->at(i)); | 2646 VisitForStackValue(args->at(i)); |
2613 } | 2647 } |
2614 __ mov(r2, Operand(name)); | |
2615 } | 2648 } |
| 2649 |
2616 // Record source position for debugger. | 2650 // Record source position for debugger. |
2617 SetSourcePosition(expr->position()); | 2651 SetSourcePosition(expr->position()); |
2618 // Call the IC initialization code. | 2652 CallFunctionStub stub(arg_count, flags); |
2619 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); | 2653 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2620 TypeFeedbackId ast_id = mode == CONTEXTUAL | 2654 __ CallStub(&stub); |
2621 ? TypeFeedbackId::None() | 2655 |
2622 : expr->CallFeedbackId(); | |
2623 CallIC(ic, mode, ast_id); | |
2624 RecordJSReturnSite(expr); | 2656 RecordJSReturnSite(expr); |
| 2657 |
2625 // Restore context register. | 2658 // Restore context register. |
2626 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2659 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2627 context()->Plug(r0); | 2660 |
| 2661 context()->DropAndPlug(1, r0); |
2628 } | 2662 } |
2629 | 2663 |
2630 | 2664 |
| 2665 // Code common for calls using the IC. |
2631 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2666 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2632 Expression* key) { | 2667 Expression* key) { |
2633 // Load the key. | 2668 // Load the key. |
2634 VisitForAccumulatorValue(key); | 2669 VisitForAccumulatorValue(key); |
2635 | 2670 |
2636 // Swap the name of the function and the receiver on the stack to follow | 2671 Expression* callee = expr->expression(); |
2637 // the calling convention for call ICs. | |
2638 __ pop(r1); | |
2639 __ push(r0); | |
2640 __ push(r1); | |
2641 | |
2642 // Code common for calls using the IC. | |
2643 ZoneList<Expression*>* args = expr->arguments(); | 2672 ZoneList<Expression*>* args = expr->arguments(); |
2644 int arg_count = args->length(); | 2673 int arg_count = args->length(); |
| 2674 |
| 2675 // Load the function from the receiver. |
| 2676 ASSERT(callee->IsProperty()); |
| 2677 __ ldr(r1, MemOperand(sp, 0)); |
| 2678 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2679 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2680 |
| 2681 // Push the target function under the receiver. |
| 2682 __ ldr(ip, MemOperand(sp, 0)); |
| 2683 __ push(ip); |
| 2684 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2685 |
2645 { PreservePositionScope scope(masm()->positions_recorder()); | 2686 { PreservePositionScope scope(masm()->positions_recorder()); |
2646 for (int i = 0; i < arg_count; i++) { | 2687 for (int i = 0; i < arg_count; i++) { |
2647 VisitForStackValue(args->at(i)); | 2688 VisitForStackValue(args->at(i)); |
2648 } | 2689 } |
2649 } | 2690 } |
| 2691 |
2650 // Record source position for debugger. | 2692 // Record source position for debugger. |
2651 SetSourcePosition(expr->position()); | 2693 SetSourcePosition(expr->position()); |
2652 // Call the IC initialization code. | 2694 CallFunctionStub stub(arg_count, CALL_AS_METHOD); |
2653 Handle<Code> ic = | 2695 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2654 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2696 __ CallStub(&stub); |
2655 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2697 |
2656 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); | |
2657 RecordJSReturnSite(expr); | 2698 RecordJSReturnSite(expr); |
2658 // Restore context register. | 2699 // Restore context register. |
2659 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2700 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2660 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2701 |
| 2702 context()->DropAndPlug(1, r0); |
2661 } | 2703 } |
2662 | 2704 |
2663 | 2705 |
2664 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2706 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
2665 // Code common for calls using the call stub. | 2707 // Code common for calls using the call stub. |
2666 ZoneList<Expression*>* args = expr->arguments(); | 2708 ZoneList<Expression*>* args = expr->arguments(); |
2667 int arg_count = args->length(); | 2709 int arg_count = args->length(); |
2668 { PreservePositionScope scope(masm()->positions_recorder()); | 2710 { PreservePositionScope scope(masm()->positions_recorder()); |
2669 for (int i = 0; i < arg_count; i++) { | 2711 for (int i = 0; i < arg_count; i++) { |
2670 VisitForStackValue(args->at(i)); | 2712 VisitForStackValue(args->at(i)); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 // Record source position for debugger. | 2800 // Record source position for debugger. |
2759 SetSourcePosition(expr->position()); | 2801 SetSourcePosition(expr->position()); |
2760 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2802 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |
2761 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2803 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2762 __ CallStub(&stub); | 2804 __ CallStub(&stub); |
2763 RecordJSReturnSite(expr); | 2805 RecordJSReturnSite(expr); |
2764 // Restore context register. | 2806 // Restore context register. |
2765 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2807 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2766 context()->DropAndPlug(1, r0); | 2808 context()->DropAndPlug(1, r0); |
2767 } else if (call_type == Call::GLOBAL_CALL) { | 2809 } else if (call_type == Call::GLOBAL_CALL) { |
2768 // Push global object as receiver for the call IC. | 2810 EmitCallWithIC(expr); |
2769 __ ldr(r0, GlobalObjectOperand()); | 2811 |
2770 __ push(r0); | |
2771 VariableProxy* proxy = callee->AsVariableProxy(); | |
2772 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); | |
2773 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2812 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
2774 // Call to a lookup slot (dynamically introduced variable). | 2813 // Call to a lookup slot (dynamically introduced variable). |
2775 VariableProxy* proxy = callee->AsVariableProxy(); | 2814 VariableProxy* proxy = callee->AsVariableProxy(); |
2776 Label slow, done; | 2815 Label slow, done; |
2777 | 2816 |
2778 { PreservePositionScope scope(masm()->positions_recorder()); | 2817 { PreservePositionScope scope(masm()->positions_recorder()); |
2779 // Generate code for loading from variables potentially shadowed | 2818 // Generate code for loading from variables potentially shadowed |
2780 // by eval-introduced variables. | 2819 // by eval-introduced variables. |
2781 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2820 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2782 } | 2821 } |
(...skipping 25 matching lines...) Expand all Loading... |
2808 | 2847 |
2809 // The receiver is either the global receiver or an object found | 2848 // The receiver is either the global receiver or an object found |
2810 // by LoadContextSlot. | 2849 // by LoadContextSlot. |
2811 EmitCallWithStub(expr); | 2850 EmitCallWithStub(expr); |
2812 } else if (call_type == Call::PROPERTY_CALL) { | 2851 } else if (call_type == Call::PROPERTY_CALL) { |
2813 Property* property = callee->AsProperty(); | 2852 Property* property = callee->AsProperty(); |
2814 { PreservePositionScope scope(masm()->positions_recorder()); | 2853 { PreservePositionScope scope(masm()->positions_recorder()); |
2815 VisitForStackValue(property->obj()); | 2854 VisitForStackValue(property->obj()); |
2816 } | 2855 } |
2817 if (property->key()->IsPropertyName()) { | 2856 if (property->key()->IsPropertyName()) { |
2818 EmitCallWithIC(expr, | 2857 EmitCallWithIC(expr); |
2819 property->key()->AsLiteral()->value(), | |
2820 NOT_CONTEXTUAL); | |
2821 } else { | 2858 } else { |
2822 EmitKeyedCallWithIC(expr, property->key()); | 2859 EmitKeyedCallWithIC(expr, property->key()); |
2823 } | 2860 } |
2824 } else { | 2861 } else { |
2825 ASSERT(call_type == Call::OTHER_CALL); | 2862 ASSERT(call_type == Call::OTHER_CALL); |
2826 // Call to an arbitrary expression not handled specially above. | 2863 // Call to an arbitrary expression not handled specially above. |
2827 { PreservePositionScope scope(masm()->positions_recorder()); | 2864 { PreservePositionScope scope(masm()->positions_recorder()); |
2828 VisitForStackValue(callee); | 2865 VisitForStackValue(callee); |
2829 } | 2866 } |
2830 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | 2867 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4086 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4123 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4087 Handle<String> name = expr->name(); | 4124 Handle<String> name = expr->name(); |
4088 if (name->length() > 0 && name->Get(0) == '_') { | 4125 if (name->length() > 0 && name->Get(0) == '_') { |
4089 Comment cmnt(masm_, "[ InlineRuntimeCall"); | 4126 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
4090 EmitInlineRuntimeCall(expr); | 4127 EmitInlineRuntimeCall(expr); |
4091 return; | 4128 return; |
4092 } | 4129 } |
4093 | 4130 |
4094 Comment cmnt(masm_, "[ CallRuntime"); | 4131 Comment cmnt(masm_, "[ CallRuntime"); |
4095 ZoneList<Expression*>* args = expr->arguments(); | 4132 ZoneList<Expression*>* args = expr->arguments(); |
| 4133 int arg_count = args->length(); |
4096 | 4134 |
4097 if (expr->is_jsruntime()) { | 4135 if (expr->is_jsruntime()) { |
4098 // Prepare for calling JS runtime function. | 4136 // Push the builtins object as the receiver. |
4099 __ ldr(r0, GlobalObjectOperand()); | 4137 __ ldr(r0, GlobalObjectOperand()); |
4100 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); | 4138 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); |
4101 __ push(r0); | 4139 __ push(r0); |
4102 } | |
4103 | 4140 |
4104 // Push the arguments ("left-to-right"). | 4141 // Load the function from the receiver. |
4105 int arg_count = args->length(); | 4142 __ mov(r2, Operand(expr->name())); |
4106 for (int i = 0; i < arg_count; i++) { | 4143 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4107 VisitForStackValue(args->at(i)); | |
4108 } | |
4109 | 4144 |
4110 if (expr->is_jsruntime()) { | 4145 // Push the target function under the receiver. |
4111 // Call the JS runtime function. | 4146 __ ldr(ip, MemOperand(sp, 0)); |
4112 __ mov(r2, Operand(expr->name())); | 4147 __ push(ip); |
4113 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); | 4148 __ str(r0, MemOperand(sp, kPointerSize)); |
4114 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4149 |
| 4150 // Push the arguments ("left-to-right"). |
| 4151 int arg_count = args->length(); |
| 4152 for (int i = 0; i < arg_count; i++) { |
| 4153 VisitForStackValue(args->at(i)); |
| 4154 } |
| 4155 |
| 4156 // Record source position of the IC call. |
| 4157 SetSourcePosition(expr->position()); |
| 4158 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4159 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 4160 __ CallStub(&stub); |
| 4161 |
4115 // Restore context register. | 4162 // Restore context register. |
4116 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4163 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4164 |
| 4165 context()->DropAndPlug(1, r0); |
4117 } else { | 4166 } else { |
| 4167 // Push the arguments ("left-to-right"). |
| 4168 for (int i = 0; i < arg_count; i++) { |
| 4169 VisitForStackValue(args->at(i)); |
| 4170 } |
| 4171 |
4118 // Call the C runtime function. | 4172 // Call the C runtime function. |
4119 __ CallRuntime(expr->function(), arg_count); | 4173 __ CallRuntime(expr->function(), arg_count); |
| 4174 context()->Plug(r0); |
4120 } | 4175 } |
4121 context()->Plug(r0); | |
4122 } | 4176 } |
4123 | 4177 |
4124 | 4178 |
4125 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4179 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
4126 switch (expr->op()) { | 4180 switch (expr->op()) { |
4127 case Token::DELETE: { | 4181 case Token::DELETE: { |
4128 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4182 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
4129 Property* property = expr->expression()->AsProperty(); | 4183 Property* property = expr->expression()->AsProperty(); |
4130 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4184 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4131 | 4185 |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4866 ASSERT(Memory::uint32_at(interrupt_address_pointer) == | 4920 ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
4867 reinterpret_cast<uint32_t>( | 4921 reinterpret_cast<uint32_t>( |
4868 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4922 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4869 return OSR_AFTER_STACK_CHECK; | 4923 return OSR_AFTER_STACK_CHECK; |
4870 } | 4924 } |
4871 | 4925 |
4872 | 4926 |
4873 } } // namespace v8::internal | 4927 } } // namespace v8::internal |
4874 | 4928 |
4875 #endif // V8_TARGET_ARCH_ARM | 4929 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |