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" |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); | 27 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); |
28 | 28 |
29 | 29 |
30 Assembler::Assembler(bool use_far_branches) | 30 Assembler::Assembler(bool use_far_branches) |
31 : buffer_(), | 31 : buffer_(), |
32 prologue_offset_(-1), | 32 prologue_offset_(-1), |
33 use_far_branches_(use_far_branches), | 33 use_far_branches_(use_far_branches), |
34 comments_(), | 34 comments_(), |
35 constant_pool_allowed_(false) { | 35 constant_pool_allowed_(false) { |
| 36 MonomorphicCheckedEntry(); |
36 } | 37 } |
37 | 38 |
38 | 39 |
39 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 40 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
40 ASSERT(Utils::IsAligned(data, 4)); | 41 ASSERT(Utils::IsAligned(data, 4)); |
41 ASSERT(Utils::IsAligned(length, 4)); | 42 ASSERT(Utils::IsAligned(length, 4)); |
42 const uword end = data + length; | 43 const uword end = data + length; |
43 while (data < end) { | 44 while (data < end) { |
44 *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; | 45 *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; |
45 data += 4; | 46 data += 4; |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 void Assembler::EnterStubFrame() { | 1237 void Assembler::EnterStubFrame() { |
1237 EnterDartFrame(0); | 1238 EnterDartFrame(0); |
1238 } | 1239 } |
1239 | 1240 |
1240 | 1241 |
1241 void Assembler::LeaveStubFrame() { | 1242 void Assembler::LeaveStubFrame() { |
1242 LeaveDartFrame(); | 1243 LeaveDartFrame(); |
1243 } | 1244 } |
1244 | 1245 |
1245 | 1246 |
| 1247 void Assembler::NoMonomorphicCheckedEntry() { |
| 1248 buffer_.Reset(); |
| 1249 brk(0); |
| 1250 brk(0); |
| 1251 brk(0); |
| 1252 brk(0); |
| 1253 brk(0); |
| 1254 brk(0); |
| 1255 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset); |
| 1256 } |
| 1257 |
| 1258 |
| 1259 // R0 receiver, R5 guarded cid as Smi |
| 1260 void Assembler::MonomorphicCheckedEntry() { |
| 1261 bool saved_use_far_branches = use_far_branches(); |
| 1262 set_use_far_branches(false); |
| 1263 |
| 1264 Label immediate, have_cid, miss; |
| 1265 Bind(&miss); |
| 1266 ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset())); |
| 1267 ldr(IP0, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 1268 br(IP0); |
| 1269 brk(0); |
| 1270 |
| 1271 Bind(&immediate); |
| 1272 movz(R1, Immediate(kSmiCid), 0); |
| 1273 b(&have_cid); |
| 1274 |
| 1275 Comment("MonomorphicCheckedEntry"); |
| 1276 ASSERT(CodeSize() == Instructions::kCheckedEntryOffset); |
| 1277 tsti(R0, Immediate(kSmiTagMask)); |
| 1278 SmiUntag(R5); |
| 1279 b(&immediate, EQ); |
| 1280 |
| 1281 LoadClassId(R1, R0); |
| 1282 |
| 1283 Bind(&have_cid); |
| 1284 cmp(R1, Operand(R5)); |
| 1285 b(&miss, NE); |
| 1286 |
| 1287 // Fall through to unchecked entry. |
| 1288 ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset); |
| 1289 |
| 1290 set_use_far_branches(saved_use_far_branches); |
| 1291 } |
| 1292 |
| 1293 |
1246 #ifndef PRODUCT | 1294 #ifndef PRODUCT |
1247 void Assembler::MaybeTraceAllocation(intptr_t cid, | 1295 void Assembler::MaybeTraceAllocation(intptr_t cid, |
1248 Register temp_reg, | 1296 Register temp_reg, |
1249 Label* trace) { | 1297 Label* trace) { |
1250 ASSERT(cid > 0); | 1298 ASSERT(cid > 0); |
1251 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 1299 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
1252 LoadIsolate(temp_reg); | 1300 LoadIsolate(temp_reg); |
1253 intptr_t table_offset = | 1301 intptr_t table_offset = |
1254 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 1302 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
1255 ldr(temp_reg, Address(temp_reg, table_offset)); | 1303 ldr(temp_reg, Address(temp_reg, table_offset)); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 add(base, array, Operand(index, LSL, shift)); | 1476 add(base, array, Operand(index, LSL, shift)); |
1429 } | 1477 } |
1430 const OperandSize size = Address::OperandSizeFor(cid); | 1478 const OperandSize size = Address::OperandSizeFor(cid); |
1431 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1479 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1432 return Address(base, offset, Address::Offset, size); | 1480 return Address(base, offset, Address::Offset, size); |
1433 } | 1481 } |
1434 | 1482 |
1435 } // namespace dart | 1483 } // namespace dart |
1436 | 1484 |
1437 #endif // defined TARGET_ARCH_ARM64 | 1485 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |