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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 3569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3580 Bind(&loop); | 3580 Bind(&loop); |
3581 JumpIfSmi(result, &done); | 3581 JumpIfSmi(result, &done); |
3582 CompareObjectType(result, temp, temp2, MAP_TYPE); | 3582 CompareObjectType(result, temp, temp2, MAP_TYPE); |
3583 B(ne, &done); | 3583 B(ne, &done); |
3584 Ldr(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset)); | 3584 Ldr(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset)); |
3585 B(&loop); | 3585 B(&loop); |
3586 Bind(&done); | 3586 Bind(&done); |
3587 } | 3587 } |
3588 | 3588 |
3589 | 3589 |
3590 void MacroAssembler::TryGetFunctionPrototype(Register function, | 3590 void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, |
3591 Register result, | 3591 Register scratch, Label* miss) { |
3592 Register scratch, | |
3593 Label* miss, | |
3594 BoundFunctionAction action) { | |
3595 DCHECK(!AreAliased(function, result, scratch)); | 3592 DCHECK(!AreAliased(function, result, scratch)); |
3596 | 3593 |
3597 Label non_instance; | |
3598 if (action == kMissOnBoundFunction) { | |
3599 // Check that the receiver isn't a smi. | |
3600 JumpIfSmi(function, miss); | |
3601 | |
3602 // Check that the function really is a function. Load map into result reg. | |
3603 JumpIfNotObjectType(function, result, scratch, JS_FUNCTION_TYPE, miss); | |
3604 | |
3605 Register scratch_w = scratch.W(); | |
3606 Ldr(scratch, | |
3607 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | |
3608 // On 64-bit platforms, compiler hints field is not a smi. See definition of | |
3609 // kCompilerHintsOffset in src/objects.h. | |
3610 Ldr(scratch_w, | |
3611 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); | |
3612 Tbnz(scratch, SharedFunctionInfo::kBoundFunction, miss); | |
3613 | |
3614 // Make sure that the function has an instance prototype. | |
3615 Ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); | |
3616 Tbnz(scratch, Map::kHasNonInstancePrototype, &non_instance); | |
3617 } | |
3618 | |
3619 // Get the prototype or initial map from the function. | 3594 // Get the prototype or initial map from the function. |
3620 Ldr(result, | 3595 Ldr(result, |
3621 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 3596 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
3622 | 3597 |
3623 // If the prototype or initial map is the hole, don't return it and simply | 3598 // If the prototype or initial map is the hole, don't return it and simply |
3624 // miss the cache instead. This will allow us to allocate a prototype object | 3599 // miss the cache instead. This will allow us to allocate a prototype object |
3625 // on-demand in the runtime system. | 3600 // on-demand in the runtime system. |
3626 JumpIfRoot(result, Heap::kTheHoleValueRootIndex, miss); | 3601 JumpIfRoot(result, Heap::kTheHoleValueRootIndex, miss); |
3627 | 3602 |
3628 // If the function does not have an initial map, we're done. | 3603 // If the function does not have an initial map, we're done. |
3629 Label done; | 3604 Label done; |
3630 JumpIfNotObjectType(result, scratch, scratch, MAP_TYPE, &done); | 3605 JumpIfNotObjectType(result, scratch, scratch, MAP_TYPE, &done); |
3631 | 3606 |
3632 // Get the prototype from the initial map. | 3607 // Get the prototype from the initial map. |
3633 Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); | 3608 Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); |
3634 | 3609 |
3635 if (action == kMissOnBoundFunction) { | |
3636 B(&done); | |
3637 | |
3638 // Non-instance prototype: fetch prototype from constructor field in initial | |
3639 // map. | |
3640 Bind(&non_instance); | |
3641 GetMapConstructor(result, result, scratch, scratch); | |
3642 } | |
3643 | |
3644 // All done. | 3610 // All done. |
3645 Bind(&done); | 3611 Bind(&done); |
3646 } | 3612 } |
3647 | 3613 |
3648 | 3614 |
3649 void MacroAssembler::CompareRoot(const Register& obj, | 3615 void MacroAssembler::CompareRoot(const Register& obj, |
3650 Heap::RootListIndex index) { | 3616 Heap::RootListIndex index) { |
3651 UseScratchRegisterScope temps(this); | 3617 UseScratchRegisterScope temps(this); |
3652 Register temp = temps.AcquireX(); | 3618 Register temp = temps.AcquireX(); |
3653 DCHECK(!AreAliased(obj, temp)); | 3619 DCHECK(!AreAliased(obj, temp)); |
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4434 Ldrb(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); | 4400 Ldrb(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); |
4435 DecodeField<Map::ElementsKindBits>(scratch1); | 4401 DecodeField<Map::ElementsKindBits>(scratch1); |
4436 CompareAndBranch(scratch1, DICTIONARY_ELEMENTS, eq, found); | 4402 CompareAndBranch(scratch1, DICTIONARY_ELEMENTS, eq, found); |
4437 Ldr(current, FieldMemOperand(current, Map::kPrototypeOffset)); | 4403 Ldr(current, FieldMemOperand(current, Map::kPrototypeOffset)); |
4438 CompareAndBranch(current, Heap::kNullValueRootIndex, ne, &loop_again); | 4404 CompareAndBranch(current, Heap::kNullValueRootIndex, ne, &loop_again); |
4439 | 4405 |
4440 Bind(&end); | 4406 Bind(&end); |
4441 } | 4407 } |
4442 | 4408 |
4443 | 4409 |
4444 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, | |
4445 Register result) { | |
4446 DCHECK(!result.Is(ldr_location)); | |
4447 const uint32_t kLdrLitOffset_lsb = 5; | |
4448 const uint32_t kLdrLitOffset_width = 19; | |
4449 Ldr(result, MemOperand(ldr_location)); | |
4450 if (emit_debug_code()) { | |
4451 And(result, result, LoadLiteralFMask); | |
4452 Cmp(result, LoadLiteralFixed); | |
4453 Check(eq, kTheInstructionToPatchShouldBeAnLdrLiteral); | |
4454 // The instruction was clobbered. Reload it. | |
4455 Ldr(result, MemOperand(ldr_location)); | |
4456 } | |
4457 Sbfx(result, result, kLdrLitOffset_lsb, kLdrLitOffset_width); | |
4458 Add(result, ldr_location, Operand(result, LSL, kWordSizeInBytesLog2)); | |
4459 } | |
4460 | |
4461 | |
4462 void MacroAssembler::EnsureNotWhite( | 4410 void MacroAssembler::EnsureNotWhite( |
4463 Register value, | 4411 Register value, |
4464 Register bitmap_scratch, | 4412 Register bitmap_scratch, |
4465 Register shift_scratch, | 4413 Register shift_scratch, |
4466 Register load_scratch, | 4414 Register load_scratch, |
4467 Register length_scratch, | 4415 Register length_scratch, |
4468 Label* value_is_white_and_not_data) { | 4416 Label* value_is_white_and_not_data) { |
4469 DCHECK(!AreAliased( | 4417 DCHECK(!AreAliased( |
4470 value, bitmap_scratch, shift_scratch, load_scratch, length_scratch)); | 4418 value, bitmap_scratch, shift_scratch, load_scratch, length_scratch)); |
4471 | 4419 |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5155 } | 5103 } |
5156 | 5104 |
5157 | 5105 |
5158 #undef __ | 5106 #undef __ |
5159 | 5107 |
5160 | 5108 |
5161 } // namespace internal | 5109 } // namespace internal |
5162 } // namespace v8 | 5110 } // namespace v8 |
5163 | 5111 |
5164 #endif // V8_TARGET_ARCH_ARM64 | 5112 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |