| 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 |