| 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/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1694 } | 1694 } |
| 1695 | 1695 |
| 1696 | 1696 |
| 1697 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { | 1697 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { |
| 1698 Mov(x1, builtin); | 1698 Mov(x1, builtin); |
| 1699 CEntryStub stub(isolate(), 1); | 1699 CEntryStub stub(isolate(), 1); |
| 1700 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 1700 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 1701 } | 1701 } |
| 1702 | 1702 |
| 1703 | 1703 |
| 1704 void MacroAssembler::GetBuiltinFunction(Register target, | |
| 1705 int native_context_index) { | |
| 1706 // Load the builtins object into target register. | |
| 1707 Ldr(target, GlobalObjectMemOperand()); | |
| 1708 Ldr(target, FieldMemOperand(target, JSGlobalObject::kNativeContextOffset)); | |
| 1709 // Load the JavaScript builtin function from the builtins object. | |
| 1710 Ldr(target, ContextMemOperand(target, native_context_index)); | |
| 1711 } | |
| 1712 | |
| 1713 | |
| 1714 void MacroAssembler::GetBuiltinEntry(Register target, Register function, | |
| 1715 int native_context_index) { | |
| 1716 DCHECK(!AreAliased(target, function)); | |
| 1717 GetBuiltinFunction(function, native_context_index); | |
| 1718 // Load the code entry point from the builtins object. | |
| 1719 Ldr(target, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | |
| 1720 } | |
| 1721 | |
| 1722 | |
| 1723 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, | 1704 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, |
| 1724 const CallWrapper& call_wrapper) { | 1705 const CallWrapper& call_wrapper) { |
| 1725 ASM_LOCATION("MacroAssembler::InvokeBuiltin"); | 1706 ASM_LOCATION("MacroAssembler::InvokeBuiltin"); |
| 1726 // You can't call a builtin without a valid frame. | 1707 // You can't call a builtin without a valid frame. |
| 1727 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1708 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 1728 | 1709 |
| 1729 // Get the builtin entry in x2 and setup the function object in x1. | 1710 // Get the builtin entry in x2 and setup the function object in x1. |
| 1730 GetBuiltinEntry(x2, x1, native_context_index); | 1711 LoadNativeContextSlot(native_context_index, x1); |
| 1712 Ldr(x2, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); |
| 1731 if (flag == CALL_FUNCTION) { | 1713 if (flag == CALL_FUNCTION) { |
| 1732 call_wrapper.BeforeCall(CallSize(x2)); | 1714 call_wrapper.BeforeCall(CallSize(x2)); |
| 1733 Call(x2); | 1715 Call(x2); |
| 1734 call_wrapper.AfterCall(); | 1716 call_wrapper.AfterCall(); |
| 1735 } else { | 1717 } else { |
| 1736 DCHECK(flag == JUMP_FUNCTION); | 1718 DCHECK(flag == JUMP_FUNCTION); |
| 1737 Jump(x2); | 1719 Jump(x2); |
| 1738 } | 1720 } |
| 1739 } | 1721 } |
| 1740 | 1722 |
| (...skipping 1144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2885 } | 2867 } |
| 2886 } else { | 2868 } else { |
| 2887 // Slot is in the current function context. Move it into the | 2869 // Slot is in the current function context. Move it into the |
| 2888 // destination register in case we store into it (the write barrier | 2870 // destination register in case we store into it (the write barrier |
| 2889 // cannot be allowed to destroy the context in cp). | 2871 // cannot be allowed to destroy the context in cp). |
| 2890 Mov(dst, cp); | 2872 Mov(dst, cp); |
| 2891 } | 2873 } |
| 2892 } | 2874 } |
| 2893 | 2875 |
| 2894 | 2876 |
| 2895 void MacroAssembler::LoadGlobalProxy(Register dst) { | |
| 2896 Ldr(dst, GlobalObjectMemOperand()); | |
| 2897 Ldr(dst, FieldMemOperand(dst, JSGlobalObject::kGlobalProxyOffset)); | |
| 2898 } | |
| 2899 | |
| 2900 | |
| 2901 void MacroAssembler::DebugBreak() { | 2877 void MacroAssembler::DebugBreak() { |
| 2902 Mov(x0, 0); | 2878 Mov(x0, 0); |
| 2903 Mov(x1, ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); | 2879 Mov(x1, ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); |
| 2904 CEntryStub ces(isolate(), 1); | 2880 CEntryStub ces(isolate(), 1); |
| 2905 DCHECK(AllowThisStubCall(&ces)); | 2881 DCHECK(AllowThisStubCall(&ces)); |
| 2906 Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); | 2882 Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); |
| 2907 } | 2883 } |
| 2908 | 2884 |
| 2909 | 2885 |
| 2910 void MacroAssembler::PushStackHandler() { | 2886 void MacroAssembler::PushStackHandler() { |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3664 | 3640 |
| 3665 // Load current lexical context from the stack frame. | 3641 // Load current lexical context from the stack frame. |
| 3666 Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3642 Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3667 // In debug mode, make sure the lexical context is set. | 3643 // In debug mode, make sure the lexical context is set. |
| 3668 #ifdef DEBUG | 3644 #ifdef DEBUG |
| 3669 Cmp(scratch1, 0); | 3645 Cmp(scratch1, 0); |
| 3670 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 3646 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
| 3671 #endif | 3647 #endif |
| 3672 | 3648 |
| 3673 // Load the native context of the current context. | 3649 // Load the native context of the current context. |
| 3674 int offset = | 3650 Ldr(scratch1, ContextMemOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); |
| 3675 Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; | |
| 3676 Ldr(scratch1, FieldMemOperand(scratch1, offset)); | |
| 3677 Ldr(scratch1, | |
| 3678 FieldMemOperand(scratch1, JSGlobalObject::kNativeContextOffset)); | |
| 3679 | 3651 |
| 3680 // Check the context is a native context. | 3652 // Check the context is a native context. |
| 3681 if (emit_debug_code()) { | 3653 if (emit_debug_code()) { |
| 3682 // Read the first word and compare to the native_context_map. | 3654 // Read the first word and compare to the native_context_map. |
| 3683 Ldr(scratch2, FieldMemOperand(scratch1, HeapObject::kMapOffset)); | 3655 Ldr(scratch2, FieldMemOperand(scratch1, HeapObject::kMapOffset)); |
| 3684 CompareRoot(scratch2, Heap::kNativeContextMapRootIndex); | 3656 CompareRoot(scratch2, Heap::kNativeContextMapRootIndex); |
| 3685 Check(eq, kExpectedNativeContext); | 3657 Check(eq, kExpectedNativeContext); |
| 3686 } | 3658 } |
| 3687 | 3659 |
| 3688 // Check if both contexts are the same. | 3660 // Check if both contexts are the same. |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4500 } | 4472 } |
| 4501 | 4473 |
| 4502 | 4474 |
| 4503 void MacroAssembler::LoadTransitionedArrayMapConditional( | 4475 void MacroAssembler::LoadTransitionedArrayMapConditional( |
| 4504 ElementsKind expected_kind, | 4476 ElementsKind expected_kind, |
| 4505 ElementsKind transitioned_kind, | 4477 ElementsKind transitioned_kind, |
| 4506 Register map_in_out, | 4478 Register map_in_out, |
| 4507 Register scratch1, | 4479 Register scratch1, |
| 4508 Register scratch2, | 4480 Register scratch2, |
| 4509 Label* no_map_match) { | 4481 Label* no_map_match) { |
| 4510 // Load the global or builtins object from the current context. | |
| 4511 Ldr(scratch1, GlobalObjectMemOperand()); | |
| 4512 Ldr(scratch1, | |
| 4513 FieldMemOperand(scratch1, JSGlobalObject::kNativeContextOffset)); | |
| 4514 | |
| 4515 // Check that the function's map is the same as the expected cached map. | 4482 // Check that the function's map is the same as the expected cached map. |
| 4516 Ldr(scratch1, ContextMemOperand(scratch1, Context::JS_ARRAY_MAPS_INDEX)); | 4483 LoadNativeContextSlot(Context::JS_ARRAY_MAPS_INDEX, scratch1); |
| 4517 int offset = (expected_kind * kPointerSize) + FixedArrayBase::kHeaderSize; | 4484 int offset = (expected_kind * kPointerSize) + FixedArrayBase::kHeaderSize; |
| 4518 Ldr(scratch2, FieldMemOperand(scratch1, offset)); | 4485 Ldr(scratch2, FieldMemOperand(scratch1, offset)); |
| 4519 Cmp(map_in_out, scratch2); | 4486 Cmp(map_in_out, scratch2); |
| 4520 B(ne, no_map_match); | 4487 B(ne, no_map_match); |
| 4521 | 4488 |
| 4522 // Use the transitioned cached map. | 4489 // Use the transitioned cached map. |
| 4523 offset = (transitioned_kind * kPointerSize) + FixedArrayBase::kHeaderSize; | 4490 offset = (transitioned_kind * kPointerSize) + FixedArrayBase::kHeaderSize; |
| 4524 Ldr(map_in_out, FieldMemOperand(scratch1, offset)); | 4491 Ldr(map_in_out, FieldMemOperand(scratch1, offset)); |
| 4525 } | 4492 } |
| 4526 | 4493 |
| 4527 | 4494 |
| 4528 void MacroAssembler::LoadGlobalFunction(int index, Register function) { | 4495 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { |
| 4529 // Load the global or builtins object from the current context. | 4496 Ldr(dst, NativeContextMemOperand()); |
| 4530 Ldr(function, GlobalObjectMemOperand()); | 4497 Ldr(dst, ContextMemOperand(dst, index)); |
| 4531 // Load the native context from the global or builtins object. | |
| 4532 Ldr(function, | |
| 4533 FieldMemOperand(function, JSGlobalObject::kNativeContextOffset)); | |
| 4534 // Load the function from the native context. | |
| 4535 Ldr(function, ContextMemOperand(function, index)); | |
| 4536 } | 4498 } |
| 4537 | 4499 |
| 4538 | 4500 |
| 4539 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 4501 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
| 4540 Register map, | 4502 Register map, |
| 4541 Register scratch) { | 4503 Register scratch) { |
| 4542 // Load the initial map. The global functions all have initial maps. | 4504 // Load the initial map. The global functions all have initial maps. |
| 4543 Ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 4505 Ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4544 if (emit_debug_code()) { | 4506 if (emit_debug_code()) { |
| 4545 Label ok, fail; | 4507 Label ok, fail; |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4969 } | 4931 } |
| 4970 | 4932 |
| 4971 | 4933 |
| 4972 #undef __ | 4934 #undef __ |
| 4973 | 4935 |
| 4974 | 4936 |
| 4975 } // namespace internal | 4937 } // namespace internal |
| 4976 } // namespace v8 | 4938 } // namespace v8 |
| 4977 | 4939 |
| 4978 #endif // V8_TARGET_ARCH_ARM64 | 4940 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |