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

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

Issue 155723005: A64: Synchronize with r19001. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/code-stubs-arm.cc ('k') | src/arm/ic-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 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 __ bind(&not_found); 3844 __ bind(&not_found);
3808 // Call runtime to perform the lookup. 3845 // Call runtime to perform the lookup.
3809 __ Push(cache, key); 3846 __ Push(cache, key);
3810 __ CallRuntime(Runtime::kGetFromCache, 2); 3847 __ CallRuntime(Runtime::kGetFromCache, 2);
3811 3848
3812 __ bind(&done); 3849 __ bind(&done);
3813 context()->Plug(r0); 3850 context()->Plug(r0);
3814 } 3851 }
3815 3852
3816 3853
3817 void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) {
3818 ZoneList<Expression*>* args = expr->arguments();
3819 ASSERT_EQ(2, args->length());
3820
3821 Register right = r0;
3822 Register left = r1;
3823 Register tmp = r2;
3824 Register tmp2 = r3;
3825
3826 VisitForStackValue(args->at(0));
3827 VisitForAccumulatorValue(args->at(1));
3828 __ pop(left);
3829
3830 Label done, fail, ok;
3831 __ cmp(left, Operand(right));
3832 __ b(eq, &ok);
3833 // Fail if either is a non-HeapObject.
3834 __ and_(tmp, left, Operand(right));
3835 __ JumpIfSmi(tmp, &fail);
3836 __ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset));
3837 __ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
3838 __ cmp(tmp2, Operand(JS_REGEXP_TYPE));
3839 __ b(ne, &fail);
3840 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
3841 __ cmp(tmp, Operand(tmp2));
3842 __ b(ne, &fail);
3843 __ ldr(tmp, FieldMemOperand(left, JSRegExp::kDataOffset));
3844 __ ldr(tmp2, FieldMemOperand(right, JSRegExp::kDataOffset));
3845 __ cmp(tmp, tmp2);
3846 __ b(eq, &ok);
3847 __ bind(&fail);
3848 __ LoadRoot(r0, Heap::kFalseValueRootIndex);
3849 __ jmp(&done);
3850 __ bind(&ok);
3851 __ LoadRoot(r0, Heap::kTrueValueRootIndex);
3852 __ bind(&done);
3853
3854 context()->Plug(r0);
3855 }
3856
3857
3858 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3854 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3859 ZoneList<Expression*>* args = expr->arguments(); 3855 ZoneList<Expression*>* args = expr->arguments();
3860 VisitForAccumulatorValue(args->at(0)); 3856 VisitForAccumulatorValue(args->at(0));
3861 3857
3862 Label materialize_true, materialize_false; 3858 Label materialize_true, materialize_false;
3863 Label* if_true = NULL; 3859 Label* if_true = NULL;
3864 Label* if_false = NULL; 3860 Label* if_false = NULL;
3865 Label* fall_through = NULL; 3861 Label* fall_through = NULL;
3866 context()->PrepareTest(&materialize_true, &materialize_false, 3862 context()->PrepareTest(&materialize_true, &materialize_false,
3867 &if_true, &if_false, &fall_through); 3863 &if_true, &if_false, &fall_through);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4127 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4123 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4128 Handle<String> name = expr->name(); 4124 Handle<String> name = expr->name();
4129 if (name->length() > 0 && name->Get(0) == '_') { 4125 if (name->length() > 0 && name->Get(0) == '_') {
4130 Comment cmnt(masm_, "[ InlineRuntimeCall"); 4126 Comment cmnt(masm_, "[ InlineRuntimeCall");
4131 EmitInlineRuntimeCall(expr); 4127 EmitInlineRuntimeCall(expr);
4132 return; 4128 return;
4133 } 4129 }
4134 4130
4135 Comment cmnt(masm_, "[ CallRuntime"); 4131 Comment cmnt(masm_, "[ CallRuntime");
4136 ZoneList<Expression*>* args = expr->arguments(); 4132 ZoneList<Expression*>* args = expr->arguments();
4133 int arg_count = args->length();
4137 4134
4138 if (expr->is_jsruntime()) { 4135 if (expr->is_jsruntime()) {
4139 // Prepare for calling JS runtime function. 4136 // Push the builtins object as the receiver.
4140 __ ldr(r0, GlobalObjectOperand()); 4137 __ ldr(r0, GlobalObjectOperand());
4141 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); 4138 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
4142 __ push(r0); 4139 __ push(r0);
4143 }
4144 4140
4145 // Push the arguments ("left-to-right"). 4141 // Load the function from the receiver.
4146 int arg_count = args->length(); 4142 __ mov(r2, Operand(expr->name()));
4147 for (int i = 0; i < arg_count; i++) { 4143 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4148 VisitForStackValue(args->at(i));
4149 }
4150 4144
4151 if (expr->is_jsruntime()) { 4145 // Push the target function under the receiver.
4152 // Call the JS runtime function. 4146 __ ldr(ip, MemOperand(sp, 0));
4153 __ mov(r2, Operand(expr->name())); 4147 __ push(ip);
4154 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); 4148 __ str(r0, MemOperand(sp, kPointerSize));
4155 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
4156 // Restore context register. 4162 // Restore context register.
4157 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4163 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4164
4165 context()->DropAndPlug(1, r0);
4158 } 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
4159 // Call the C runtime function. 4172 // Call the C runtime function.
4160 __ CallRuntime(expr->function(), arg_count); 4173 __ CallRuntime(expr->function(), arg_count);
4174 context()->Plug(r0);
4161 } 4175 }
4162 context()->Plug(r0);
4163 } 4176 }
4164 4177
4165 4178
4166 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4179 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4167 switch (expr->op()) { 4180 switch (expr->op()) {
4168 case Token::DELETE: { 4181 case Token::DELETE: {
4169 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4182 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4170 Property* property = expr->expression()->AsProperty(); 4183 Property* property = expr->expression()->AsProperty();
4171 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4184 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4172 4185
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4920 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4908 reinterpret_cast<uint32_t>( 4921 reinterpret_cast<uint32_t>(
4909 isolate->builtins()->OsrAfterStackCheck()->entry())); 4922 isolate->builtins()->OsrAfterStackCheck()->entry()));
4910 return OSR_AFTER_STACK_CHECK; 4923 return OSR_AFTER_STACK_CHECK;
4911 } 4924 }
4912 4925
4913 4926
4914 } } // namespace v8::internal 4927 } } // namespace v8::internal
4915 4928
4916 #endif // V8_TARGET_ARCH_ARM 4929 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698