Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(480)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 12260026: Add support for object pool (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 9
10 #include "vm/stub_code.h"
11
10 namespace dart { 12 namespace dart {
11 13
12 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented.
15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
13 16
14 17
15 // Instruction encoding bits. 18 // Instruction encoding bits.
16 enum { 19 enum {
17 H = 1 << 5, // halfword (or byte) 20 H = 1 << 5, // halfword (or byte)
18 L = 1 << 20, // load (or store) 21 L = 1 << 20, // load (or store)
19 S = 1 << 20, // set condition code (or leave unchanged) 22 S = 1 << 20, // set condition code (or leave unchanged)
20 W = 1 << 21, // writeback base register (or leave unchanged) 23 W = 1 << 21, // writeback base register (or leave unchanged)
21 A = 1 << 21, // accumulate in multiply instruction (or not) 24 A = 1 << 21, // accumulate in multiply instruction (or not)
22 B = 1 << 22, // unsigned byte (or word) 25 B = 1 << 22, // unsigned byte (or word)
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 Bind(&l); 1032 Bind(&l);
1030 } 1033 }
1031 1034
1032 1035
1033 void Assembler::LoadObject(Register rd, const Object& object) { 1036 void Assembler::LoadObject(Register rd, const Object& object) {
1034 // TODO(regis): If the object is never relocated (null, true, false, ...), 1037 // TODO(regis): If the object is never relocated (null, true, false, ...),
1035 // load as immediate. 1038 // load as immediate.
1036 const int32_t offset = 1039 const int32_t offset =
1037 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; 1040 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag;
1038 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { 1041 if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
1039 ldr(rd, Address(CP, offset)); 1042 ldr(rd, Address(PP, offset));
1040 } else { 1043 } else {
1041 int32_t offset12_hi = offset & ~kOffset12Mask; // signed 1044 int32_t offset12_hi = offset & ~kOffset12Mask; // signed
1042 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned 1045 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned
1043 AddConstant(rd, CP, offset12_hi); 1046 AddConstant(rd, PP, offset12_hi);
1044 ldr(rd, Address(rd, offset12_lo)); 1047 ldr(rd, Address(rd, offset12_lo));
1045 } 1048 }
1046 } 1049 }
1047 1050
1048 1051
1049 void Assembler::Bind(Label* label) { 1052 void Assembler::Bind(Label* label) {
1050 ASSERT(!label->IsBound()); 1053 ASSERT(!label->IsBound());
1051 int bound_pc = buffer_.Size(); 1054 int bound_pc = buffer_.Size();
1052 while (label->IsLinked()) { 1055 while (label->IsLinked()) {
1053 int32_t position = label->Position(); 1056 int32_t position = label->Position();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 } 1163 }
1161 1164
1162 1165
1163 void Assembler::Branch(const ExternalLabel* label) { 1166 void Assembler::Branch(const ExternalLabel* label) {
1164 LoadImmediate(IP, label->address()); // Target address is never patched. 1167 LoadImmediate(IP, label->address()); // Target address is never patched.
1165 mov(PC, ShifterOperand(IP)); 1168 mov(PC, ShifterOperand(IP));
1166 } 1169 }
1167 1170
1168 1171
1169 void Assembler::BranchLink(const ExternalLabel* label) { 1172 void Assembler::BranchLink(const ExternalLabel* label) {
1173 LoadImmediate(IP, label->address()); // Target address is never patched.
1174 blx(IP); // Use blx instruction so that the return branch prediction works.
1175 }
1176
1177
1178 void Assembler::BranchLinkPatchable(const ExternalLabel* label) {
1170 // TODO(regis): Make sure that CodePatcher is able to patch the label referred 1179 // TODO(regis): Make sure that CodePatcher is able to patch the label referred
1171 // to by this code sequence. 1180 // to by this code sequence.
1172 // For added code robustness, use 'blx lr' in a patchable sequence and 1181 // For added code robustness, use 'blx lr' in a patchable sequence and
1173 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 1182 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
1174 const int32_t offset = 1183 const int32_t offset =
1175 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; 1184 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
1176 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { 1185 if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
1177 ldr(LR, Address(CP, offset)); 1186 ldr(LR, Address(PP, offset));
1178 } else { 1187 } else {
1179 int32_t offset12_hi = offset & ~kOffset12Mask; // signed 1188 int32_t offset12_hi = offset & ~kOffset12Mask; // signed
1180 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned 1189 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned
1181 // Inline a simplified version of AddConstant(LR, CP, offset12_hi). 1190 // Inline a simplified version of AddConstant(LR, CP, offset12_hi).
1182 ShifterOperand shifter_op; 1191 ShifterOperand shifter_op;
1183 if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) { 1192 if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) {
1184 add(LR, CP, shifter_op); 1193 add(LR, PP, shifter_op);
1185 } else { 1194 } else {
1186 movw(LR, Utils::Low16Bits(offset12_hi)); 1195 movw(LR, Utils::Low16Bits(offset12_hi));
1187 const uint16_t value_high = Utils::High16Bits(offset12_hi); 1196 const uint16_t value_high = Utils::High16Bits(offset12_hi);
1188 if (value_high != 0) { 1197 if (value_high != 0) {
1189 movt(LR, value_high); 1198 movt(LR, value_high);
1190 } 1199 }
1191 add(LR, CP, ShifterOperand(LR)); 1200 add(LR, PP, ShifterOperand(LR));
1192 } 1201 }
1193 ldr(LR, Address(LR, offset12_lo)); 1202 ldr(LR, Address(LR, offset12_lo));
1194 } 1203 }
1195 blx(LR); // Use blx instruction so that the return branch prediction works. 1204 blx(LR); // Use blx instruction so that the return branch prediction works.
1196 } 1205 }
1197 1206
1198 1207
1199 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) { 1208 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) {
1200 // TODO(regis): Revisit this code sequence. 1209 // TODO(regis): Revisit this code sequence.
1201 LoadImmediate(IP, label->address()); // Target address is never patched. 1210 LoadImmediate(IP, label->address()); // Target address is never patched.
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 movt(IP, value_high, cond); 1502 movt(IP, value_high, cond);
1494 } 1503 }
1495 adc(rd, rn, ShifterOperand(IP), cond); 1504 adc(rd, rn, ShifterOperand(IP), cond);
1496 } 1505 }
1497 } 1506 }
1498 } 1507 }
1499 1508
1500 1509
1501 void Assembler::Stop(const char* message) { 1510 void Assembler::Stop(const char* message) {
1502 if (FLAG_print_stop_message) { 1511 if (FLAG_print_stop_message) {
1503 UNIMPLEMENTED(); // Emit call to StubCode::PrintStopMessage(). 1512 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR.
1513 LoadImmediate(R0, reinterpret_cast<int32_t>(message));
1514 // PrintStopMessage() preserves all registers.
1515 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0.
1516 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR.
1504 } 1517 }
1505 // Emit the message address before the svc instruction, so that we can 1518 // Emit the message address before the svc instruction, so that we can
1506 // 'unstop' and continue execution in the simulator or jump to the next 1519 // 'unstop' and continue execution in the simulator or jump to the next
1507 // instruction in gdb. 1520 // instruction in gdb.
1508 Label stop; 1521 Label stop;
1509 b(&stop); 1522 b(&stop);
1510 Emit(reinterpret_cast<int32_t>(message)); 1523 Emit(reinterpret_cast<int32_t>(message));
1511 Bind(&stop); 1524 Bind(&stop);
1512 svc(kStopMessageSvcCode); 1525 svc(kStopMessageSvcCode);
1513 } 1526 }
(...skipping 12 matching lines...) Expand all
1526 } 1539 }
1527 1540
1528 1541
1529 int Assembler::DecodeBranchOffset(int32_t inst) { 1542 int Assembler::DecodeBranchOffset(int32_t inst) {
1530 // Sign-extend, left-shift by 2, then add 8. 1543 // Sign-extend, left-shift by 2, then add 8.
1531 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1544 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1532 } 1545 }
1533 1546
1534 1547
1535 int32_t Assembler::AddObject(const Object& obj) { 1548 int32_t Assembler::AddObject(const Object& obj) {
1549 if (object_pool_.IsNull()) {
1550 // The object pool cannot be used in the vm isolate.
1551 ASSERT(Isolate::Current() != Dart::vm_isolate());
1552 object_pool_ = GrowableObjectArray::New();
1553 }
1536 for (int i = 0; i < object_pool_.Length(); i++) { 1554 for (int i = 0; i < object_pool_.Length(); i++) {
1537 if (object_pool_.At(i) == obj.raw()) { 1555 if (object_pool_.At(i) == obj.raw()) {
1538 return i; 1556 return i;
1539 } 1557 }
1540 } 1558 }
1541 object_pool_.Add(obj); 1559 object_pool_.Add(obj);
1542 return object_pool_.Length(); 1560 return object_pool_.Length();
1543 } 1561 }
1544 1562
1545 1563
1546 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { 1564 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) {
1547 const uword address = label->address(); 1565 if (object_pool_.IsNull()) {
1566 // The object pool cannot be used in the vm isolate.
1567 ASSERT(Isolate::Current() != Dart::vm_isolate());
1568 object_pool_ = GrowableObjectArray::New();
1569 }
1570 const word address = label->address();
1548 ASSERT(Utils::IsAligned(address, 4)); 1571 ASSERT(Utils::IsAligned(address, 4));
1549 // The address is stored in the object array as a RawSmi. 1572 // The address is stored in the object array as a RawSmi.
1550 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); 1573 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift));
1551 // Do not reuse an existing entry, since each reference may be patched 1574 // Do not reuse an existing entry, since each reference may be patched
1552 // independently. 1575 // independently.
1553 object_pool_.Add(smi); 1576 object_pool_.Add(smi);
1554 return object_pool_.Length(); 1577 return object_pool_.Length();
1555 } 1578 }
1556 1579
1557 } // namespace dart 1580 } // namespace dart
1558 1581
1559 #endif // defined TARGET_ARCH_ARM 1582 #endif // defined TARGET_ARCH_ARM
1560 1583
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698