OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/simulator.h" | 9 #include "vm/simulator.h" |
10 #include "vm/runtime_entry.h" | 10 #include "vm/runtime_entry.h" |
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1289 } | 1289 } |
1290 | 1290 |
1291 | 1291 |
1292 void Assembler::CompareObject(Register rn, const Object& object) { | 1292 void Assembler::CompareObject(Register rn, const Object& object) { |
1293 ASSERT(rn != IP); | 1293 ASSERT(rn != IP); |
1294 LoadObject(IP, object); | 1294 LoadObject(IP, object); |
1295 cmp(rn, ShifterOperand(IP)); | 1295 cmp(rn, ShifterOperand(IP)); |
1296 } | 1296 } |
1297 | 1297 |
1298 | 1298 |
1299 // Preserves object and value registers. | |
1300 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | |
1301 Register value, | |
1302 Label* no_update) { | |
1303 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && | |
1304 (kOldObjectAlignmentOffset == 0), young_alignment); | |
1305 | |
1306 // Write-barrier triggers if the value is in the new space (has bit set) and | |
1307 // the object is in the old space (has bit cleared). | |
1308 // To check that, we compute value & ~object and skip the write barrier | |
1309 // if the bit is not set. We can't destroy the object. | |
1310 bic(IP, value, ShifterOperand(object)); | |
1311 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); | |
1312 b(no_update, EQ); | |
1313 } | |
1314 | |
1315 | |
1316 // Preserves object and value registers. | |
1317 void Assembler::StoreIntoObjectFilter(Register object, | |
1318 Register value, | |
1319 Label* no_update) { | |
1320 // For the value we are only interested in the new/old bit and the tag bit. | |
1321 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. | |
1322 and_(IP, value, ShifterOperand(value, LSL, kObjectAlignmentLog2 - 1)); | |
1323 // And the result with the negated space bit of the object. | |
1324 bic(IP, IP, ShifterOperand(object)); | |
1325 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); | |
1326 b(no_update, EQ); | |
1327 } | |
1328 | |
1329 | |
1330 void Assembler::StoreIntoObject(Register object, | |
1331 const Address& dest, | |
1332 Register value, | |
1333 bool can_value_be_smi) { | |
1334 ASSERT(object != value); | |
1335 str(value, dest); | |
1336 Label done; | |
1337 if (can_value_be_smi) { | |
1338 StoreIntoObjectFilter(object, value, &done); | |
1339 } else { | |
1340 StoreIntoObjectFilterNoSmi(object, value, &done); | |
1341 } | |
1342 // A store buffer update is required. | |
1343 if (value != R0) Push(R0); // Preserve R0. | |
1344 if (object != R0) { | |
1345 mov(R0, ShifterOperand(object)); | |
1346 } | |
1347 BranchLink(&StubCode::UpdateStoreBufferLabel()); | |
1348 if (value != R0) Pop(R0); // Restore R0. | |
1349 Bind(&done); | |
1350 } | |
1351 | |
1352 | |
1353 void Assembler::StoreIntoObjectNoBarrier(Register object, | |
zra
2013/04/08 15:59:37
The NoBarrier functions look find to me, but I cou
regis
2013/04/08 16:44:08
We have not yet implemented the graph instructions
| |
1354 const Address& dest, | |
1355 Register value) { | |
1356 str(value, dest); | |
1357 #if defined(DEBUG) | |
1358 Label done; | |
1359 StoreIntoObjectFilter(object, value, &done); | |
1360 Stop("Store buffer update is required"); | |
1361 Bind(&done); | |
1362 #endif // defined(DEBUG) | |
1363 // No store buffer update. | |
1364 } | |
1365 | |
1366 | |
1367 void Assembler::StoreIntoObjectNoBarrier(Register object, | |
1368 const Address& dest, | |
1369 const Object& value) { | |
1370 ASSERT(value.IsSmi() || value.InVMHeap() || | |
1371 (value.IsOld() && value.IsNotTemporaryScopedHandle())); | |
1372 // No store buffer update. | |
1373 LoadObject(IP, value); | |
1374 str(IP, dest); | |
1375 } | |
1376 | |
1377 | |
1299 void Assembler::LoadClassId(Register result, Register object) { | 1378 void Assembler::LoadClassId(Register result, Register object) { |
1300 ASSERT(RawObject::kClassIdTagBit == 16); | 1379 ASSERT(RawObject::kClassIdTagBit == 16); |
1301 ASSERT(RawObject::kClassIdTagSize == 16); | 1380 ASSERT(RawObject::kClassIdTagSize == 16); |
1302 const intptr_t class_id_offset = Object::tags_offset() + | 1381 const intptr_t class_id_offset = Object::tags_offset() + |
1303 RawObject::kClassIdTagBit / kBitsPerByte; | 1382 RawObject::kClassIdTagBit / kBitsPerByte; |
1304 ldrh(result, FieldAddress(object, class_id_offset)); | 1383 ldrh(result, FieldAddress(object, class_id_offset)); |
1305 } | 1384 } |
1306 | 1385 |
1307 | 1386 |
1308 void Assembler::LoadClassById(Register result, Register class_id) { | 1387 void Assembler::LoadClassById(Register result, Register class_id) { |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2045 | 2124 |
2046 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2125 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
2047 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 2126 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
2048 return fpu_reg_names[reg]; | 2127 return fpu_reg_names[reg]; |
2049 } | 2128 } |
2050 | 2129 |
2051 } // namespace dart | 2130 } // namespace dart |
2052 | 2131 |
2053 #endif // defined TARGET_ARCH_ARM | 2132 #endif // defined TARGET_ARCH_ARM |
2054 | 2133 |
OLD | NEW |