OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 | 87 |
88 // ----------------------------------------------------------------------------- | 88 // ----------------------------------------------------------------------------- |
89 // Implementation of RelocInfo | 89 // Implementation of RelocInfo |
90 | 90 |
91 const int RelocInfo::kApplyMask = 0; | 91 const int RelocInfo::kApplyMask = 0; |
92 | 92 |
93 | 93 |
94 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { | 94 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { |
95 // Patch the code at the current address with the supplied instructions. | 95 // Patch the code at the current address with the supplied instructions. |
96 UNIMPLEMENTED(); | 96 Instr* pc = reinterpret_cast<Instr*>(pc_); |
| 97 Instr* instr = reinterpret_cast<Instr*>(instructions); |
| 98 for (int i = 0; i < instruction_count; i++) { |
| 99 *(pc + i) = *(instr + i); |
| 100 } |
| 101 |
| 102 // Indicate that code has changed. |
| 103 CPU::FlushICache(pc_, instruction_count * Assembler::kInstrSize); |
97 } | 104 } |
98 | 105 |
99 | 106 |
100 // Patch the code at the current PC with a call to the target address. | 107 // Patch the code at the current PC with a call to the target address. |
101 // Additional guard instructions can be added if required. | 108 // Additional guard instructions can be added if required. |
102 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { | 109 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
103 // Patch the code at the current address with a call to the target. | 110 // Patch the code at the current address with a call to the target. |
104 UNIMPLEMENTED(); | 111 UNIMPLEMENTED(); |
105 } | 112 } |
106 | 113 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 static const Instr kPopInstruction = | 232 static const Instr kPopInstruction = |
226 al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12; | 233 al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12; |
227 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) | 234 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) |
228 // register r is not encoded. | 235 // register r is not encoded. |
229 static const Instr kPushRegPattern = | 236 static const Instr kPushRegPattern = |
230 al | B26 | 4 | NegPreIndex | sp.code() * B16; | 237 al | B26 | 4 | NegPreIndex | sp.code() * B16; |
231 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) | 238 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) |
232 // register r is not encoded. | 239 // register r is not encoded. |
233 static const Instr kPopRegPattern = | 240 static const Instr kPopRegPattern = |
234 al | B26 | L | 4 | PostIndex | sp.code() * B16; | 241 al | B26 | L | 4 | PostIndex | sp.code() * B16; |
| 242 // mov lr, pc |
| 243 const Instr kMovLrPc = al | 13*B21 | pc.code() | lr.code() * B12; |
| 244 // ldr pc, [pc, #XXX] |
| 245 const Instr kLdrPCPattern = al | B26 | L | pc.code() * B16; |
235 | 246 |
236 // spare_buffer_ | 247 // spare_buffer_ |
237 static const int kMinimalBufferSize = 4*KB; | 248 static const int kMinimalBufferSize = 4*KB; |
238 static byte* spare_buffer_ = NULL; | 249 static byte* spare_buffer_ = NULL; |
239 | 250 |
240 Assembler::Assembler(void* buffer, int buffer_size) { | 251 Assembler::Assembler(void* buffer, int buffer_size) { |
241 if (buffer == NULL) { | 252 if (buffer == NULL) { |
242 // do our own buffer management | 253 // do our own buffer management |
243 if (buffer_size <= kMinimalBufferSize) { | 254 if (buffer_size <= kMinimalBufferSize) { |
244 buffer_size = kMinimalBufferSize; | 255 buffer_size = kMinimalBufferSize; |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 mov(dst, Operand(x.rn_), s, cond); | 1305 mov(dst, Operand(x.rn_), s, cond); |
1295 else if ((am & U) == 0) // negative indexing | 1306 else if ((am & U) == 0) // negative indexing |
1296 sub(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); | 1307 sub(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); |
1297 else | 1308 else |
1298 add(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); | 1309 add(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond); |
1299 } | 1310 } |
1300 } | 1311 } |
1301 | 1312 |
1302 | 1313 |
1303 // Debugging | 1314 // Debugging |
| 1315 void Assembler::RecordJSReturn() { |
| 1316 WriteRecordedPositions(); |
| 1317 CheckBuffer(); |
| 1318 RecordRelocInfo(RelocInfo::JS_RETURN); |
| 1319 } |
| 1320 |
| 1321 |
1304 void Assembler::RecordComment(const char* msg) { | 1322 void Assembler::RecordComment(const char* msg) { |
1305 if (FLAG_debug_code) { | 1323 if (FLAG_debug_code) { |
1306 CheckBuffer(); | 1324 CheckBuffer(); |
1307 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); | 1325 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); |
1308 } | 1326 } |
1309 } | 1327 } |
1310 | 1328 |
1311 | 1329 |
1312 void Assembler::RecordPosition(int pos) { | 1330 void Assembler::RecordPosition(int pos) { |
1313 if (pos == RelocInfo::kNoPosition) return; | 1331 if (pos == RelocInfo::kNoPosition) return; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 | 1398 |
1381 // none of our relocation types are pc relative pointing outside the code | 1399 // none of our relocation types are pc relative pointing outside the code |
1382 // buffer nor pc absolute pointing inside the code buffer, so there is no need | 1400 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
1383 // to relocate any emitted relocation entries | 1401 // to relocate any emitted relocation entries |
1384 | 1402 |
1385 // relocate pending relocation entries | 1403 // relocate pending relocation entries |
1386 for (int i = 0; i < num_prinfo_; i++) { | 1404 for (int i = 0; i < num_prinfo_; i++) { |
1387 RelocInfo& rinfo = prinfo_[i]; | 1405 RelocInfo& rinfo = prinfo_[i]; |
1388 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && | 1406 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
1389 rinfo.rmode() != RelocInfo::POSITION); | 1407 rinfo.rmode() != RelocInfo::POSITION); |
1390 rinfo.set_pc(rinfo.pc() + pc_delta); | 1408 if (rinfo.rmode() != RelocInfo::JS_RETURN) { |
| 1409 rinfo.set_pc(rinfo.pc() + pc_delta); |
| 1410 } |
1391 } | 1411 } |
1392 } | 1412 } |
1393 | 1413 |
1394 | 1414 |
1395 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 1415 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
1396 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants | 1416 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants |
1397 if (rmode >= RelocInfo::COMMENT && rmode <= RelocInfo::STATEMENT_POSITION) { | 1417 if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::STATEMENT_POSITION) { |
1398 // adjust code for new modes | 1418 // Adjust code for new modes |
1399 ASSERT(RelocInfo::IsComment(rmode) || RelocInfo::IsPosition(rmode)); | 1419 ASSERT(RelocInfo::IsJSReturn(rmode) |
| 1420 || RelocInfo::IsComment(rmode) |
| 1421 || RelocInfo::IsPosition(rmode)); |
1400 // these modes do not need an entry in the constant pool | 1422 // these modes do not need an entry in the constant pool |
1401 } else { | 1423 } else { |
1402 ASSERT(num_prinfo_ < kMaxNumPRInfo); | 1424 ASSERT(num_prinfo_ < kMaxNumPRInfo); |
1403 prinfo_[num_prinfo_++] = rinfo; | 1425 prinfo_[num_prinfo_++] = rinfo; |
1404 // Make sure the constant pool is not emitted in place of the next | 1426 // Make sure the constant pool is not emitted in place of the next |
1405 // instruction for which we just recorded relocation info | 1427 // instruction for which we just recorded relocation info |
1406 BlockConstPoolBefore(pc_offset() + kInstrSize); | 1428 BlockConstPoolBefore(pc_offset() + kInstrSize); |
1407 } | 1429 } |
1408 if (rinfo.rmode() != RelocInfo::NONE) { | 1430 if (rinfo.rmode() != RelocInfo::NONE) { |
1409 // Don't record external references unless the heap will be serialized. | 1431 // Don't record external references unless the heap will be serialized. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 // "Undefined instruction" as specified by A3.1 Instruction set encoding | 1505 // "Undefined instruction" as specified by A3.1 Instruction set encoding |
1484 emit(0x03000000 | num_prinfo_); | 1506 emit(0x03000000 | num_prinfo_); |
1485 | 1507 |
1486 // Emit constant pool entries | 1508 // Emit constant pool entries |
1487 for (int i = 0; i < num_prinfo_; i++) { | 1509 for (int i = 0; i < num_prinfo_; i++) { |
1488 RelocInfo& rinfo = prinfo_[i]; | 1510 RelocInfo& rinfo = prinfo_[i]; |
1489 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && | 1511 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
1490 rinfo.rmode() != RelocInfo::POSITION && | 1512 rinfo.rmode() != RelocInfo::POSITION && |
1491 rinfo.rmode() != RelocInfo::STATEMENT_POSITION); | 1513 rinfo.rmode() != RelocInfo::STATEMENT_POSITION); |
1492 Instr instr = instr_at(rinfo.pc()); | 1514 Instr instr = instr_at(rinfo.pc()); |
| 1515 |
1493 // Instruction to patch must be a ldr/str [pc, #offset] | 1516 // Instruction to patch must be a ldr/str [pc, #offset] |
1494 // P and U set, B and W clear, Rn == pc, offset12 still 0 | 1517 // P and U set, B and W clear, Rn == pc, offset12 still 0 |
1495 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) == | 1518 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) == |
1496 (2*B25 | P | U | pc.code()*B16)); | 1519 (2*B25 | P | U | pc.code()*B16)); |
1497 int delta = pc_ - rinfo.pc() - 8; | 1520 int delta = pc_ - rinfo.pc() - 8; |
1498 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32 | 1521 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32 |
1499 if (delta < 0) { | 1522 if (delta < 0) { |
1500 instr &= ~U; | 1523 instr &= ~U; |
1501 delta = -delta; | 1524 delta = -delta; |
1502 } | 1525 } |
(...skipping 10 matching lines...) Expand all Loading... |
1513 bind(&after_pool); | 1536 bind(&after_pool); |
1514 } | 1537 } |
1515 | 1538 |
1516 // Since a constant pool was just emitted, move the check offset forward by | 1539 // Since a constant pool was just emitted, move the check offset forward by |
1517 // the standard interval. | 1540 // the standard interval. |
1518 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 1541 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
1519 } | 1542 } |
1520 | 1543 |
1521 | 1544 |
1522 } } // namespace v8::internal | 1545 } } // namespace v8::internal |
OLD | NEW |