OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
11 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
12 #include "vm/simulator.h" | 12 #include "vm/simulator.h" |
13 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
14 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
15 | 15 |
16 namespace dart { | 16 namespace dart { |
17 | 17 |
18 DECLARE_FLAG(bool, check_code_pointer); | 18 DECLARE_FLAG(bool, check_code_pointer); |
19 DECLARE_FLAG(bool, inline_alloc); | 19 DECLARE_FLAG(bool, inline_alloc); |
20 | 20 |
21 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); | 21 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); |
22 | 22 |
23 | 23 |
24 Assembler::Assembler(bool use_far_branches) | 24 Assembler::Assembler(bool use_far_branches) |
25 : buffer_(), | 25 : buffer_(), |
26 prologue_offset_(-1), | 26 prologue_offset_(-1), |
27 use_far_branches_(use_far_branches), | 27 use_far_branches_(use_far_branches), |
28 comments_(), | 28 comments_(), |
29 constant_pool_allowed_(false) { | 29 constant_pool_allowed_(false) { |
| 30 MonomorphicCheckedEntry(); |
30 } | 31 } |
31 | 32 |
32 | 33 |
33 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
34 ASSERT(Utils::IsAligned(data, 4)); | 35 ASSERT(Utils::IsAligned(data, 4)); |
35 ASSERT(Utils::IsAligned(length, 4)); | 36 ASSERT(Utils::IsAligned(length, 4)); |
36 const uword end = data + length; | 37 const uword end = data + length; |
37 while (data < end) { | 38 while (data < end) { |
38 *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; | 39 *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; |
39 data += 4; | 40 data += 4; |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 void Assembler::EnterStubFrame() { | 1231 void Assembler::EnterStubFrame() { |
1231 EnterDartFrame(0); | 1232 EnterDartFrame(0); |
1232 } | 1233 } |
1233 | 1234 |
1234 | 1235 |
1235 void Assembler::LeaveStubFrame() { | 1236 void Assembler::LeaveStubFrame() { |
1236 LeaveDartFrame(); | 1237 LeaveDartFrame(); |
1237 } | 1238 } |
1238 | 1239 |
1239 | 1240 |
| 1241 void Assembler::NoMonomorphicCheckedEntry() { |
| 1242 buffer_.Reset(); |
| 1243 brk(0); |
| 1244 brk(0); |
| 1245 brk(0); |
| 1246 brk(0); |
| 1247 brk(0); |
| 1248 brk(0); |
| 1249 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset); |
| 1250 } |
| 1251 |
| 1252 |
| 1253 // R0 receiver, R5 guarded cid as Smi |
| 1254 void Assembler::MonomorphicCheckedEntry() { |
| 1255 bool saved_use_far_branches = use_far_branches(); |
| 1256 set_use_far_branches(false); |
| 1257 |
| 1258 Label immediate, have_cid, miss; |
| 1259 Bind(&miss); |
| 1260 ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset())); |
| 1261 ldr(IP0, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 1262 br(IP0); |
| 1263 brk(0); |
| 1264 |
| 1265 Bind(&immediate); |
| 1266 movz(R4, Immediate(kSmiCid), 0); |
| 1267 b(&have_cid); |
| 1268 |
| 1269 Comment("MonomorphicCheckedEntry"); |
| 1270 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset); |
| 1271 tsti(R0, Immediate(kSmiTagMask)); |
| 1272 SmiUntag(R5); |
| 1273 b(&immediate, EQ); |
| 1274 |
| 1275 LoadClassId(R4, R0); |
| 1276 |
| 1277 Bind(&have_cid); |
| 1278 cmp(R4, Operand(R5)); |
| 1279 b(&miss, NE); |
| 1280 |
| 1281 // Fall through to unchecked entry. |
| 1282 ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset); |
| 1283 |
| 1284 set_use_far_branches(saved_use_far_branches); |
| 1285 } |
| 1286 |
| 1287 |
1240 #ifndef PRODUCT | 1288 #ifndef PRODUCT |
1241 void Assembler::MaybeTraceAllocation(intptr_t cid, | 1289 void Assembler::MaybeTraceAllocation(intptr_t cid, |
1242 Register temp_reg, | 1290 Register temp_reg, |
1243 Label* trace) { | 1291 Label* trace) { |
1244 ASSERT(cid > 0); | 1292 ASSERT(cid > 0); |
1245 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 1293 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
1246 LoadIsolate(temp_reg); | 1294 LoadIsolate(temp_reg); |
1247 intptr_t table_offset = | 1295 intptr_t table_offset = |
1248 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 1296 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
1249 ldr(temp_reg, Address(temp_reg, table_offset)); | 1297 ldr(temp_reg, Address(temp_reg, table_offset)); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 add(base, array, Operand(index, LSL, shift)); | 1470 add(base, array, Operand(index, LSL, shift)); |
1423 } | 1471 } |
1424 const OperandSize size = Address::OperandSizeFor(cid); | 1472 const OperandSize size = Address::OperandSizeFor(cid); |
1425 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1473 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1426 return Address(base, offset, Address::Offset, size); | 1474 return Address(base, offset, Address::Offset, size); |
1427 } | 1475 } |
1428 | 1476 |
1429 } // namespace dart | 1477 } // namespace dart |
1430 | 1478 |
1431 #endif // defined TARGET_ARCH_ARM64 | 1479 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |