OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 2500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 // All calls must have a predictable size in full-codegen code to ensure that | 2511 // All calls must have a predictable size in full-codegen code to ensure that |
2512 // the debugger can patch them correctly. | 2512 // the debugger can patch them correctly. |
2513 __ Call(code, RelocInfo::CODE_TARGET, ast_id); | 2513 __ Call(code, RelocInfo::CODE_TARGET, ast_id); |
2514 } | 2514 } |
2515 | 2515 |
2516 | 2516 |
2517 // Code common for calls using the IC. | 2517 // Code common for calls using the IC. |
2518 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 2518 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2519 Expression* callee = expr->expression(); | 2519 Expression* callee = expr->expression(); |
2520 | 2520 |
2521 CallICState::CallType call_type = | |
2522 callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD; | |
2523 | |
2524 // Get the target function. | 2521 // Get the target function. |
2525 if (call_type == CallICState::FUNCTION) { | 2522 if (callee->IsVariableProxy()) { |
2526 { StackValueContext context(this); | 2523 { StackValueContext context(this); |
2527 EmitVariableLoad(callee->AsVariableProxy()); | 2524 EmitVariableLoad(callee->AsVariableProxy()); |
2528 PrepareForBailout(callee, NO_REGISTERS); | 2525 PrepareForBailout(callee, NO_REGISTERS); |
2529 } | 2526 } |
2530 // Push undefined as receiver. This is patched in the method prologue if it | 2527 // Push undefined as receiver. This is patched in the method prologue if it |
2531 // is a sloppy mode method. | 2528 // is a sloppy mode method. |
2532 { | 2529 { |
2533 UseScratchRegisterScope temps(masm_); | 2530 UseScratchRegisterScope temps(masm_); |
2534 Register temp = temps.AcquireX(); | 2531 Register temp = temps.AcquireX(); |
2535 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); | 2532 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); |
2536 __ Push(temp); | 2533 __ Push(temp); |
2537 } | 2534 } |
2538 } else { | 2535 } else { |
2539 // Load the function from the receiver. | 2536 // Load the function from the receiver. |
2540 DCHECK(callee->IsProperty()); | 2537 DCHECK(callee->IsProperty()); |
2541 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2538 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2542 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2539 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2543 EmitNamedPropertyLoad(callee->AsProperty()); | 2540 EmitNamedPropertyLoad(callee->AsProperty()); |
2544 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2541 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2545 // Push the target function under the receiver. | 2542 // Push the target function under the receiver. |
2546 __ Pop(x10); | 2543 __ Pop(x10); |
2547 __ Push(x0, x10); | 2544 __ Push(x0, x10); |
2548 } | 2545 } |
2549 | 2546 |
2550 EmitCall(expr, call_type); | 2547 EmitCall(expr); |
2551 } | 2548 } |
2552 | 2549 |
2553 | 2550 |
2554 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2551 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2555 Expression* callee = expr->expression(); | 2552 Expression* callee = expr->expression(); |
2556 DCHECK(callee->IsProperty()); | 2553 DCHECK(callee->IsProperty()); |
2557 Property* prop = callee->AsProperty(); | 2554 Property* prop = callee->AsProperty(); |
2558 DCHECK(prop->IsSuperAccess()); | 2555 DCHECK(prop->IsSuperAccess()); |
2559 SetExpressionPosition(prop); | 2556 SetExpressionPosition(prop); |
2560 | 2557 |
(...skipping 19 matching lines...) Expand all Loading... |
2580 // - home_object | 2577 // - home_object |
2581 // - language_mode | 2578 // - language_mode |
2582 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2579 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
2583 | 2580 |
2584 // Replace home_object with target function. | 2581 // Replace home_object with target function. |
2585 __ Poke(x0, kPointerSize); | 2582 __ Poke(x0, kPointerSize); |
2586 | 2583 |
2587 // Stack here: | 2584 // Stack here: |
2588 // - target function | 2585 // - target function |
2589 // - this (receiver) | 2586 // - this (receiver) |
2590 EmitCall(expr, CallICState::METHOD); | 2587 EmitCall(expr); |
2591 } | 2588 } |
2592 | 2589 |
2593 | 2590 |
2594 // Code common for calls using the IC. | 2591 // Code common for calls using the IC. |
2595 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2592 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2596 Expression* key) { | 2593 Expression* key) { |
2597 // Load the key. | 2594 // Load the key. |
2598 VisitForAccumulatorValue(key); | 2595 VisitForAccumulatorValue(key); |
2599 | 2596 |
2600 Expression* callee = expr->expression(); | 2597 Expression* callee = expr->expression(); |
2601 | 2598 |
2602 // Load the function from the receiver. | 2599 // Load the function from the receiver. |
2603 DCHECK(callee->IsProperty()); | 2600 DCHECK(callee->IsProperty()); |
2604 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2601 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2605 __ Move(LoadDescriptor::NameRegister(), x0); | 2602 __ Move(LoadDescriptor::NameRegister(), x0); |
2606 EmitKeyedPropertyLoad(callee->AsProperty()); | 2603 EmitKeyedPropertyLoad(callee->AsProperty()); |
2607 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2604 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2608 | 2605 |
2609 // Push the target function under the receiver. | 2606 // Push the target function under the receiver. |
2610 __ Pop(x10); | 2607 __ Pop(x10); |
2611 __ Push(x0, x10); | 2608 __ Push(x0, x10); |
2612 | 2609 |
2613 EmitCall(expr, CallICState::METHOD); | 2610 EmitCall(expr); |
2614 } | 2611 } |
2615 | 2612 |
2616 | 2613 |
2617 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2614 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2618 Expression* callee = expr->expression(); | 2615 Expression* callee = expr->expression(); |
2619 DCHECK(callee->IsProperty()); | 2616 DCHECK(callee->IsProperty()); |
2620 Property* prop = callee->AsProperty(); | 2617 Property* prop = callee->AsProperty(); |
2621 DCHECK(prop->IsSuperAccess()); | 2618 DCHECK(prop->IsSuperAccess()); |
2622 SetExpressionPosition(prop); | 2619 SetExpressionPosition(prop); |
2623 | 2620 |
(...skipping 17 matching lines...) Expand all Loading... |
2641 // - key | 2638 // - key |
2642 // - language_mode | 2639 // - language_mode |
2643 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2640 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
2644 | 2641 |
2645 // Replace home_object with target function. | 2642 // Replace home_object with target function. |
2646 __ Poke(x0, kPointerSize); | 2643 __ Poke(x0, kPointerSize); |
2647 | 2644 |
2648 // Stack here: | 2645 // Stack here: |
2649 // - target function | 2646 // - target function |
2650 // - this (receiver) | 2647 // - this (receiver) |
2651 EmitCall(expr, CallICState::METHOD); | 2648 EmitCall(expr); |
2652 } | 2649 } |
2653 | 2650 |
2654 | 2651 |
2655 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2652 void FullCodeGenerator::EmitCall(Call* expr) { |
2656 // Load the arguments. | 2653 // Load the arguments. |
2657 ZoneList<Expression*>* args = expr->arguments(); | 2654 ZoneList<Expression*>* args = expr->arguments(); |
2658 int arg_count = args->length(); | 2655 int arg_count = args->length(); |
2659 for (int i = 0; i < arg_count; i++) { | 2656 for (int i = 0; i < arg_count; i++) { |
2660 VisitForStackValue(args->at(i)); | 2657 VisitForStackValue(args->at(i)); |
2661 } | 2658 } |
2662 | 2659 |
2663 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2660 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2664 SetCallPosition(expr, arg_count); | 2661 SetCallPosition(expr, arg_count); |
2665 | 2662 |
2666 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2663 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code(); |
2667 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2664 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
2668 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2665 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2669 // Don't assign a type feedback id to the IC, since type feedback is provided | 2666 // Don't assign a type feedback id to the IC, since type feedback is provided |
2670 // by the vector above. | 2667 // by the vector above. |
2671 CallIC(ic); | 2668 CallIC(ic); |
2672 | 2669 |
2673 RecordJSReturnSite(expr); | 2670 RecordJSReturnSite(expr); |
2674 // Restore context register. | 2671 // Restore context register. |
2675 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2672 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2676 context()->DropAndPlug(1, x0); | 2673 context()->DropAndPlug(1, x0); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2766 | 2763 |
2767 // Touch up the stack with the resolved function. | 2764 // Touch up the stack with the resolved function. |
2768 __ Poke(x0, (arg_count + 1) * kPointerSize); | 2765 __ Poke(x0, (arg_count + 1) * kPointerSize); |
2769 | 2766 |
2770 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2767 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2771 | 2768 |
2772 // Record source position for debugger. | 2769 // Record source position for debugger. |
2773 SetCallPosition(expr, arg_count); | 2770 SetCallPosition(expr, arg_count); |
2774 | 2771 |
2775 // Call the evaluated function. | 2772 // Call the evaluated function. |
2776 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
2777 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2773 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2778 __ CallStub(&stub); | 2774 __ Mov(x0, arg_count); |
| 2775 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2779 RecordJSReturnSite(expr); | 2776 RecordJSReturnSite(expr); |
2780 // Restore context register. | 2777 // Restore context register. |
2781 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2778 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2782 context()->DropAndPlug(1, x0); | 2779 context()->DropAndPlug(1, x0); |
2783 } | 2780 } |
2784 | 2781 |
2785 | 2782 |
2786 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2783 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2787 Comment cmnt(masm_, "[ CallNew"); | 2784 Comment cmnt(masm_, "[ CallNew"); |
2788 // According to ECMA-262, section 11.2.2, page 44, the function | 2785 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3985 __ Ldr(x0, FieldMemOperand(x0, JSGlobalObject::kNativeContextOffset)); | 3982 __ Ldr(x0, FieldMemOperand(x0, JSGlobalObject::kNativeContextOffset)); |
3986 __ Ldr(x0, ContextMemOperand(x0, expr->context_index())); | 3983 __ Ldr(x0, ContextMemOperand(x0, expr->context_index())); |
3987 } | 3984 } |
3988 | 3985 |
3989 | 3986 |
3990 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3987 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3991 ZoneList<Expression*>* args = expr->arguments(); | 3988 ZoneList<Expression*>* args = expr->arguments(); |
3992 int arg_count = args->length(); | 3989 int arg_count = args->length(); |
3993 | 3990 |
3994 SetCallPosition(expr, arg_count); | 3991 SetCallPosition(expr, arg_count); |
3995 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
3996 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3992 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3997 __ CallStub(&stub); | 3993 __ Mov(x0, arg_count); |
| 3994 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3998 } | 3995 } |
3999 | 3996 |
4000 | 3997 |
4001 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3998 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4002 ZoneList<Expression*>* args = expr->arguments(); | 3999 ZoneList<Expression*>* args = expr->arguments(); |
4003 int arg_count = args->length(); | 4000 int arg_count = args->length(); |
4004 | 4001 |
4005 if (expr->is_jsruntime()) { | 4002 if (expr->is_jsruntime()) { |
4006 Comment cmnt(masm_, "[ CallRunTime"); | 4003 Comment cmnt(masm_, "[ CallRunTime"); |
4007 EmitLoadJSRuntimeFunction(expr); | 4004 EmitLoadJSRuntimeFunction(expr); |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4753 __ Bind(&l_call); | 4750 __ Bind(&l_call); |
4754 __ Peek(load_receiver, 1 * kPointerSize); | 4751 __ Peek(load_receiver, 1 * kPointerSize); |
4755 __ Peek(load_name, 2 * kPointerSize); | 4752 __ Peek(load_name, 2 * kPointerSize); |
4756 __ Mov(LoadDescriptor::SlotRegister(), | 4753 __ Mov(LoadDescriptor::SlotRegister(), |
4757 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); | 4754 SmiFromSlot(expr->KeyedLoadFeedbackSlot())); |
4758 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); | 4755 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |
4759 CallIC(ic, TypeFeedbackId::None()); | 4756 CallIC(ic, TypeFeedbackId::None()); |
4760 __ Mov(x1, x0); | 4757 __ Mov(x1, x0); |
4761 __ Poke(x1, 2 * kPointerSize); | 4758 __ Poke(x1, 2 * kPointerSize); |
4762 SetCallPosition(expr, 1); | 4759 SetCallPosition(expr, 1); |
4763 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 4760 __ Mov(x0, 1); |
4764 __ CallStub(&stub); | 4761 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
4765 | 4762 |
4766 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4763 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4767 __ Drop(1); // The function is still on the stack; drop it. | 4764 __ Drop(1); // The function is still on the stack; drop it. |
4768 | 4765 |
4769 // if (!result.done) goto l_try; | 4766 // if (!result.done) goto l_try; |
4770 __ Bind(&l_loop); | 4767 __ Bind(&l_loop); |
4771 __ Move(load_receiver, x0); | 4768 __ Move(load_receiver, x0); |
4772 | 4769 |
4773 __ Push(load_receiver); // save result | 4770 __ Push(load_receiver); // save result |
4774 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 4771 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5133 } | 5130 } |
5134 | 5131 |
5135 return INTERRUPT; | 5132 return INTERRUPT; |
5136 } | 5133 } |
5137 | 5134 |
5138 | 5135 |
5139 } // namespace internal | 5136 } // namespace internal |
5140 } // namespace v8 | 5137 } // namespace v8 |
5141 | 5138 |
5142 #endif // V8_TARGET_ARCH_ARM64 | 5139 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |