| 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 |