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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 mov_operand.instructions_required(this, mov_instr) * kInstrSize; | 82 mov_operand.instructions_required(this, mov_instr) * kInstrSize; |
83 } | 83 } |
84 | 84 |
85 | 85 |
86 int MacroAssembler::CallStubSize( | 86 int MacroAssembler::CallStubSize( |
87 CodeStub* stub, TypeFeedbackId ast_id, Condition cond) { | 87 CodeStub* stub, TypeFeedbackId ast_id, Condition cond) { |
88 return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); | 88 return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); |
89 } | 89 } |
90 | 90 |
91 | 91 |
92 int MacroAssembler::CallSizeNotPredictableCodeSize(Isolate* isolate, | |
93 Address target, | |
94 RelocInfo::Mode rmode, | |
95 Condition cond) { | |
96 Instr mov_instr = cond | MOV | LeaveCC; | |
97 Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode); | |
98 return kInstrSize + | |
99 mov_operand.instructions_required(NULL, mov_instr) * kInstrSize; | |
100 } | |
101 | |
102 | |
103 void MacroAssembler::Call(Address target, | 92 void MacroAssembler::Call(Address target, |
104 RelocInfo::Mode rmode, | 93 RelocInfo::Mode rmode, |
105 Condition cond, | 94 Condition cond, |
106 TargetAddressStorageMode mode) { | 95 TargetAddressStorageMode mode) { |
107 // Block constant pool for the call instruction sequence. | 96 // Block constant pool for the call instruction sequence. |
108 BlockConstPoolScope block_const_pool(this); | 97 BlockConstPoolScope block_const_pool(this); |
109 Label start; | 98 Label start; |
110 bind(&start); | 99 bind(&start); |
111 | 100 |
112 bool old_predictable_code_size = predictable_code_size(); | 101 bool old_predictable_code_size = predictable_code_size(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 DCHECK(RelocInfo::IsCodeTarget(rmode)); | 155 DCHECK(RelocInfo::IsCodeTarget(rmode)); |
167 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { | 156 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { |
168 SetRecordedAstId(ast_id); | 157 SetRecordedAstId(ast_id); |
169 rmode = RelocInfo::CODE_TARGET_WITH_ID; | 158 rmode = RelocInfo::CODE_TARGET_WITH_ID; |
170 } | 159 } |
171 // 'code' is always generated ARM code, never THUMB code | 160 // 'code' is always generated ARM code, never THUMB code |
172 AllowDeferredHandleDereference embedding_raw_address; | 161 AllowDeferredHandleDereference embedding_raw_address; |
173 Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode); | 162 Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode); |
174 } | 163 } |
175 | 164 |
| 165 void MacroAssembler::CallDeoptimizer(Address target) { |
| 166 BlockConstPoolScope block_const_pool(this); |
| 167 |
| 168 uintptr_t target_raw = reinterpret_cast<uintptr_t>(target); |
| 169 |
| 170 // We use blx, like a call, but it does not return here. The link register is |
| 171 // used by the deoptimizer to work out what called it. |
| 172 if (CpuFeatures::IsSupported(ARMv7)) { |
| 173 CpuFeatureScope scope(this, ARMv7); |
| 174 movw(ip, target_raw & 0xffff); |
| 175 movt(ip, (target_raw >> 16) & 0xffff); |
| 176 blx(ip); |
| 177 } else { |
| 178 // We need to load a literal, but we can't use the usual constant pool |
| 179 // because we call this from a patcher, and cannot afford the guard |
| 180 // instruction and other administrative overhead. |
| 181 ldr(ip, MemOperand(pc, (2 * kInstrSize) - kPcLoadDelta)); |
| 182 blx(ip); |
| 183 dd(target_raw); |
| 184 } |
| 185 } |
| 186 |
| 187 int MacroAssembler::CallDeoptimizerSize() { |
| 188 // ARMv7+: |
| 189 // movw ip, ... |
| 190 // movt ip, ... |
| 191 // blx ip @ This never returns. |
| 192 // |
| 193 // ARMv6: |
| 194 // ldr ip, =address |
| 195 // blx ip @ This never returns. |
| 196 // .word address |
| 197 return 3 * kInstrSize; |
| 198 } |
176 | 199 |
177 void MacroAssembler::Ret(Condition cond) { | 200 void MacroAssembler::Ret(Condition cond) { |
178 bx(lr, cond); | 201 bx(lr, cond); |
179 } | 202 } |
180 | 203 |
181 | 204 |
182 void MacroAssembler::Drop(int count, Condition cond) { | 205 void MacroAssembler::Drop(int count, Condition cond) { |
183 if (count > 0) { | 206 if (count > 0) { |
184 add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond); | 207 add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond); |
185 } | 208 } |
(...skipping 3771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3957 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3980 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
3958 } | 3981 } |
3959 | 3982 |
3960 | 3983 |
3961 CodePatcher::~CodePatcher() { | 3984 CodePatcher::~CodePatcher() { |
3962 // Indicate that code has changed. | 3985 // Indicate that code has changed. |
3963 if (flush_cache_ == FLUSH) { | 3986 if (flush_cache_ == FLUSH) { |
3964 Assembler::FlushICache(masm_.isolate(), address_, size_); | 3987 Assembler::FlushICache(masm_.isolate(), address_, size_); |
3965 } | 3988 } |
3966 | 3989 |
| 3990 // Check that we don't have any pending constant pools. |
| 3991 DCHECK(masm_.num_pending_32_bit_constants_ == 0); |
| 3992 DCHECK(masm_.num_pending_64_bit_constants_ == 0); |
| 3993 |
3967 // Check that the code was patched as expected. | 3994 // Check that the code was patched as expected. |
3968 DCHECK(masm_.pc_ == address_ + size_); | 3995 DCHECK(masm_.pc_ == address_ + size_); |
3969 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3996 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
3970 } | 3997 } |
3971 | 3998 |
3972 | 3999 |
3973 void CodePatcher::Emit(Instr instr) { | 4000 void CodePatcher::Emit(Instr instr) { |
3974 masm()->emit(instr); | 4001 masm()->emit(instr); |
3975 } | 4002 } |
3976 | 4003 |
(...skipping 29 matching lines...) Expand all Loading... |
4006 } | 4033 } |
4007 } | 4034 } |
4008 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 4035 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
4009 add(result, result, Operand(dividend, LSR, 31)); | 4036 add(result, result, Operand(dividend, LSR, 31)); |
4010 } | 4037 } |
4011 | 4038 |
4012 } // namespace internal | 4039 } // namespace internal |
4013 } // namespace v8 | 4040 } // namespace v8 |
4014 | 4041 |
4015 #endif // V8_TARGET_ARCH_ARM | 4042 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |