OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1514 | 1514 |
1515 // Load current lexical context from the stack frame. | 1515 // Load current lexical context from the stack frame. |
1516 ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1516 ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1517 // In debug mode, make sure the lexical context is set. | 1517 // In debug mode, make sure the lexical context is set. |
1518 #ifdef DEBUG | 1518 #ifdef DEBUG |
1519 cmp(scratch, Operand::Zero()); | 1519 cmp(scratch, Operand::Zero()); |
1520 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 1520 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
1521 #endif | 1521 #endif |
1522 | 1522 |
1523 // Load the native context of the current context. | 1523 // Load the native context of the current context. |
1524 ldr(scratch, ContextMemOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); | 1524 int offset = |
| 1525 Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; |
| 1526 ldr(scratch, FieldMemOperand(scratch, offset)); |
| 1527 ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kNativeContextOffset)); |
1525 | 1528 |
1526 // Check the context is a native context. | 1529 // Check the context is a native context. |
1527 if (emit_debug_code()) { | 1530 if (emit_debug_code()) { |
1528 // Cannot use ip as a temporary in this verification code. Due to the fact | 1531 // Cannot use ip as a temporary in this verification code. Due to the fact |
1529 // that ip is clobbered as part of cmp with an object Operand. | 1532 // that ip is clobbered as part of cmp with an object Operand. |
1530 push(holder_reg); // Temporarily save holder on the stack. | 1533 push(holder_reg); // Temporarily save holder on the stack. |
1531 // Read the first word and compare to the native_context_map. | 1534 // Read the first word and compare to the native_context_map. |
1532 ldr(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset)); | 1535 ldr(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset)); |
1533 LoadRoot(ip, Heap::kNativeContextMapRootIndex); | 1536 LoadRoot(ip, Heap::kNativeContextMapRootIndex); |
1534 cmp(holder_reg, ip); | 1537 cmp(holder_reg, ip); |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2510 CEntryStub stub(isolate(), 1); | 2513 CEntryStub stub(isolate(), 1); |
2511 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 2514 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
2512 } | 2515 } |
2513 | 2516 |
2514 | 2517 |
2515 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, | 2518 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, |
2516 const CallWrapper& call_wrapper) { | 2519 const CallWrapper& call_wrapper) { |
2517 // You can't call a builtin without a valid frame. | 2520 // You can't call a builtin without a valid frame. |
2518 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 2521 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
2519 | 2522 |
2520 LoadNativeContextSlot(native_context_index, r1); | 2523 GetBuiltinEntry(r2, native_context_index); |
2521 ldr(r2, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | |
2522 if (flag == CALL_FUNCTION) { | 2524 if (flag == CALL_FUNCTION) { |
2523 call_wrapper.BeforeCall(CallSize(r2)); | 2525 call_wrapper.BeforeCall(CallSize(r2)); |
2524 Call(r2); | 2526 Call(r2); |
2525 call_wrapper.AfterCall(); | 2527 call_wrapper.AfterCall(); |
2526 } else { | 2528 } else { |
2527 DCHECK(flag == JUMP_FUNCTION); | 2529 DCHECK(flag == JUMP_FUNCTION); |
2528 Jump(r2); | 2530 Jump(r2); |
2529 } | 2531 } |
2530 } | 2532 } |
2531 | 2533 |
2532 | 2534 |
| 2535 void MacroAssembler::GetBuiltinFunction(Register target, |
| 2536 int native_context_index) { |
| 2537 // Load the builtins object into target register. |
| 2538 ldr(target, |
| 2539 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 2540 ldr(target, FieldMemOperand(target, JSGlobalObject::kNativeContextOffset)); |
| 2541 // Load the JavaScript builtin function from the builtins object. |
| 2542 ldr(target, ContextOperand(target, native_context_index)); |
| 2543 } |
| 2544 |
| 2545 |
| 2546 void MacroAssembler::GetBuiltinEntry(Register target, |
| 2547 int native_context_index) { |
| 2548 DCHECK(!target.is(r1)); |
| 2549 GetBuiltinFunction(r1, native_context_index); |
| 2550 // Load the code entry point from the builtins object. |
| 2551 ldr(target, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 2552 } |
| 2553 |
| 2554 |
2533 void MacroAssembler::SetCounter(StatsCounter* counter, int value, | 2555 void MacroAssembler::SetCounter(StatsCounter* counter, int value, |
2534 Register scratch1, Register scratch2) { | 2556 Register scratch1, Register scratch2) { |
2535 if (FLAG_native_code_counters && counter->Enabled()) { | 2557 if (FLAG_native_code_counters && counter->Enabled()) { |
2536 mov(scratch1, Operand(value)); | 2558 mov(scratch1, Operand(value)); |
2537 mov(scratch2, Operand(ExternalReference(counter))); | 2559 mov(scratch2, Operand(ExternalReference(counter))); |
2538 str(scratch1, MemOperand(scratch2)); | 2560 str(scratch1, MemOperand(scratch2)); |
2539 } | 2561 } |
2540 } | 2562 } |
2541 | 2563 |
2542 | 2564 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 } | 2675 } |
2654 } else { | 2676 } else { |
2655 // Slot is in the current function context. Move it into the | 2677 // Slot is in the current function context. Move it into the |
2656 // destination register in case we store into it (the write barrier | 2678 // destination register in case we store into it (the write barrier |
2657 // cannot be allowed to destroy the context in esi). | 2679 // cannot be allowed to destroy the context in esi). |
2658 mov(dst, cp); | 2680 mov(dst, cp); |
2659 } | 2681 } |
2660 } | 2682 } |
2661 | 2683 |
2662 | 2684 |
| 2685 void MacroAssembler::LoadGlobalProxy(Register dst) { |
| 2686 ldr(dst, GlobalObjectOperand()); |
| 2687 ldr(dst, FieldMemOperand(dst, JSGlobalObject::kGlobalProxyOffset)); |
| 2688 } |
| 2689 |
| 2690 |
2663 void MacroAssembler::LoadTransitionedArrayMapConditional( | 2691 void MacroAssembler::LoadTransitionedArrayMapConditional( |
2664 ElementsKind expected_kind, | 2692 ElementsKind expected_kind, |
2665 ElementsKind transitioned_kind, | 2693 ElementsKind transitioned_kind, |
2666 Register map_in_out, | 2694 Register map_in_out, |
2667 Register scratch, | 2695 Register scratch, |
2668 Label* no_map_match) { | 2696 Label* no_map_match) { |
| 2697 // Load the global or builtins object from the current context. |
| 2698 ldr(scratch, |
| 2699 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 2700 ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kNativeContextOffset)); |
| 2701 |
2669 // Check that the function's map is the same as the expected cached map. | 2702 // Check that the function's map is the same as the expected cached map. |
2670 LoadNativeContextSlot(Context::JS_ARRAY_MAPS_INDEX, scratch); | 2703 ldr(scratch, |
2671 size_t offset = expected_kind * kPointerSize + FixedArrayBase::kHeaderSize; | 2704 MemOperand(scratch, |
| 2705 Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); |
| 2706 size_t offset = expected_kind * kPointerSize + |
| 2707 FixedArrayBase::kHeaderSize; |
2672 ldr(ip, FieldMemOperand(scratch, offset)); | 2708 ldr(ip, FieldMemOperand(scratch, offset)); |
2673 cmp(map_in_out, ip); | 2709 cmp(map_in_out, ip); |
2674 b(ne, no_map_match); | 2710 b(ne, no_map_match); |
2675 | 2711 |
2676 // Use the transitioned cached map. | 2712 // Use the transitioned cached map. |
2677 offset = transitioned_kind * kPointerSize + | 2713 offset = transitioned_kind * kPointerSize + |
2678 FixedArrayBase::kHeaderSize; | 2714 FixedArrayBase::kHeaderSize; |
2679 ldr(map_in_out, FieldMemOperand(scratch, offset)); | 2715 ldr(map_in_out, FieldMemOperand(scratch, offset)); |
2680 } | 2716 } |
2681 | 2717 |
2682 | 2718 |
2683 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { | 2719 void MacroAssembler::LoadGlobalFunction(int index, Register function) { |
2684 ldr(dst, NativeContextMemOperand()); | 2720 // Load the global or builtins object from the current context. |
2685 ldr(dst, ContextMemOperand(dst, index)); | 2721 ldr(function, |
| 2722 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
| 2723 // Load the native context from the global or builtins object. |
| 2724 ldr(function, |
| 2725 FieldMemOperand(function, JSGlobalObject::kNativeContextOffset)); |
| 2726 // Load the function from the native context. |
| 2727 ldr(function, MemOperand(function, Context::SlotOffset(index))); |
2686 } | 2728 } |
2687 | 2729 |
2688 | 2730 |
2689 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 2731 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
2690 Register map, | 2732 Register map, |
2691 Register scratch) { | 2733 Register scratch) { |
2692 // Load the initial map. The global functions all have initial maps. | 2734 // Load the initial map. The global functions all have initial maps. |
2693 ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 2735 ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
2694 if (emit_debug_code()) { | 2736 if (emit_debug_code()) { |
2695 Label ok, fail; | 2737 Label ok, fail; |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3687 } | 3729 } |
3688 } | 3730 } |
3689 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3731 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3690 add(result, result, Operand(dividend, LSR, 31)); | 3732 add(result, result, Operand(dividend, LSR, 31)); |
3691 } | 3733 } |
3692 | 3734 |
3693 } // namespace internal | 3735 } // namespace internal |
3694 } // namespace v8 | 3736 } // namespace v8 |
3695 | 3737 |
3696 #endif // V8_TARGET_ARCH_ARM | 3738 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |