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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 | 511 |
512 private: | 512 private: |
513 Register ra_; // base | 513 Register ra_; // base |
514 int32_t offset_; // offset | 514 int32_t offset_; // offset |
515 Register rb_; // index | 515 Register rb_; // index |
516 | 516 |
517 friend class Assembler; | 517 friend class Assembler; |
518 }; | 518 }; |
519 | 519 |
520 | 520 |
| 521 class DeferredRelocInfo { |
| 522 public: |
| 523 DeferredRelocInfo() {} |
| 524 DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data) |
| 525 : position_(position), rmode_(rmode), data_(data) {} |
| 526 |
| 527 int position() const { return position_; } |
| 528 RelocInfo::Mode rmode() const { return rmode_; } |
| 529 intptr_t data() const { return data_; } |
| 530 |
| 531 private: |
| 532 int position_; |
| 533 RelocInfo::Mode rmode_; |
| 534 intptr_t data_; |
| 535 }; |
| 536 |
| 537 |
521 class Assembler : public AssemblerBase { | 538 class Assembler : public AssemblerBase { |
522 public: | 539 public: |
523 // Create an assembler. Instructions and relocation information are emitted | 540 // Create an assembler. Instructions and relocation information are emitted |
524 // into a buffer, with the instructions starting from the beginning and the | 541 // into a buffer, with the instructions starting from the beginning and the |
525 // relocation information starting from the end of the buffer. See CodeDesc | 542 // relocation information starting from the end of the buffer. See CodeDesc |
526 // for a detailed comment on the layout (globals.h). | 543 // for a detailed comment on the layout (globals.h). |
527 // | 544 // |
528 // If the provided buffer is NULL, the assembler allocates and grows its own | 545 // If the provided buffer is NULL, the assembler allocates and grows its own |
529 // buffer, and buffer_size determines the initial buffer size. The buffer is | 546 // buffer, and buffer_size determines the initial buffer size. The buffer is |
530 // owned by the assembler and deallocated upon destruction of the assembler. | 547 // owned by the assembler and deallocated upon destruction of the assembler. |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 void subi(Register dst, Register src1, const Operand& src2); | 1000 void subi(Register dst, Register src1, const Operand& src2); |
984 | 1001 |
985 void cmp(Register src1, Register src2, CRegister cr = cr7); | 1002 void cmp(Register src1, Register src2, CRegister cr = cr7); |
986 void cmpl(Register src1, Register src2, CRegister cr = cr7); | 1003 void cmpl(Register src1, Register src2, CRegister cr = cr7); |
987 void cmpw(Register src1, Register src2, CRegister cr = cr7); | 1004 void cmpw(Register src1, Register src2, CRegister cr = cr7); |
988 void cmplw(Register src1, Register src2, CRegister cr = cr7); | 1005 void cmplw(Register src1, Register src2, CRegister cr = cr7); |
989 | 1006 |
990 void mov(Register dst, const Operand& src); | 1007 void mov(Register dst, const Operand& src); |
991 void bitwise_mov(Register dst, intptr_t value); | 1008 void bitwise_mov(Register dst, intptr_t value); |
992 void bitwise_mov32(Register dst, int32_t value); | 1009 void bitwise_mov32(Register dst, int32_t value); |
| 1010 void bitwise_add32(Register dst, Register src, int32_t value); |
993 | 1011 |
994 // Load the position of the label relative to the generated code object | 1012 // Load the position of the label relative to the generated code object |
995 // pointer in a register. | 1013 // pointer in a register. |
996 void mov_label_offset(Register dst, Label* label); | 1014 void mov_label_offset(Register dst, Label* label); |
997 | 1015 |
| 1016 // dst = base + label position + delta |
| 1017 void add_label_offset(Register dst, Register base, Label* label, |
| 1018 int delta = 0); |
| 1019 |
998 // Load the address of the label in a register and associate with an | 1020 // Load the address of the label in a register and associate with an |
999 // internal reference relocation. | 1021 // internal reference relocation. |
1000 void mov_label_addr(Register dst, Label* label); | 1022 void mov_label_addr(Register dst, Label* label); |
1001 | 1023 |
1002 // Emit the address of the label (i.e. a jump table entry) and associate with | 1024 // Emit the address of the label (i.e. a jump table entry) and associate with |
1003 // an internal reference relocation. | 1025 // an internal reference relocation. |
1004 void emit_label_addr(Label* label); | 1026 void emit_label_addr(Label* label); |
1005 | 1027 |
1006 // Multiply instructions | 1028 // Multiply instructions |
1007 void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE, | 1029 void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 | 1227 |
1206 // Record a deoptimization reason that can be used by a log or cpu profiler. | 1228 // Record a deoptimization reason that can be used by a log or cpu profiler. |
1207 // Use --trace-deopt to enable. | 1229 // Use --trace-deopt to enable. |
1208 void RecordDeoptReason(const int reason, const SourcePosition position); | 1230 void RecordDeoptReason(const int reason, const SourcePosition position); |
1209 | 1231 |
1210 // Writes a single byte or word of data in the code stream. Used | 1232 // Writes a single byte or word of data in the code stream. Used |
1211 // for inline tables, e.g., jump-tables. | 1233 // for inline tables, e.g., jump-tables. |
1212 void db(uint8_t data); | 1234 void db(uint8_t data); |
1213 void dd(uint32_t data); | 1235 void dd(uint32_t data); |
1214 void emit_ptr(intptr_t data); | 1236 void emit_ptr(intptr_t data); |
| 1237 void emit_double(double data); |
1215 | 1238 |
1216 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1239 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
1217 | 1240 |
1218 // Read/patch instructions | 1241 // Read/patch instructions |
1219 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1242 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
1220 void instr_at_put(int pos, Instr instr) { | 1243 void instr_at_put(int pos, Instr instr) { |
1221 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 1244 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
1222 } | 1245 } |
1223 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 1246 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
1224 static void instr_at_put(byte* pc, Instr instr) { | 1247 static void instr_at_put(byte* pc, Instr instr) { |
(...skipping 28 matching lines...) Expand all Loading... |
1253 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1276 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
1254 | 1277 |
1255 // Postpone the generation of the trampoline pool for the specified number of | 1278 // Postpone the generation of the trampoline pool for the specified number of |
1256 // instructions. | 1279 // instructions. |
1257 void BlockTrampolinePoolFor(int instructions); | 1280 void BlockTrampolinePoolFor(int instructions); |
1258 void CheckTrampolinePool(); | 1281 void CheckTrampolinePool(); |
1259 | 1282 |
1260 // The code currently calls CheckBuffer() too often. This has the side | 1283 // The code currently calls CheckBuffer() too often. This has the side |
1261 // effect of randomly growing the buffer in the middle of multi-instruction | 1284 // effect of randomly growing the buffer in the middle of multi-instruction |
1262 // sequences. | 1285 // sequences. |
1263 // MacroAssembler::LoadConstantPoolPointerRegister() includes a relocation | |
1264 // and multiple instructions. We cannot grow the buffer until the | |
1265 // relocation and all of the instructions are written. | |
1266 // | 1286 // |
1267 // This function allows outside callers to check and grow the buffer | 1287 // This function allows outside callers to check and grow the buffer |
1268 void EnsureSpaceFor(int space_needed); | 1288 void EnsureSpaceFor(int space_needed); |
1269 | 1289 |
1270 // Allocate a constant pool of the correct size for the generated code. | 1290 // Allocate a constant pool of the correct size for the generated code. |
1271 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | 1291 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
1272 | 1292 |
1273 // Generate the constant pool for the generated code. | 1293 // Generate the constant pool for the generated code. |
1274 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 1294 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
1275 | 1295 |
1276 static void RelocateInternalReference( | 1296 void EmitRelocations(); |
1277 Address pc, intptr_t delta, Address code_start, RelocInfo::Mode rmode, | |
1278 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); | |
1279 | |
1280 void AddBoundInternalReference(int position) { | |
1281 internal_reference_positions_.push_back(position); | |
1282 } | |
1283 | |
1284 void AddBoundInternalReferenceLoad(int position) { | |
1285 internal_reference_load_positions_.push_back(position); | |
1286 } | |
1287 | 1297 |
1288 protected: | 1298 protected: |
1289 // Relocation for a type-recording IC has the AST id added to it. This | 1299 // Relocation for a type-recording IC has the AST id added to it. This |
1290 // member variable is a way to pass the information from the call site to | 1300 // member variable is a way to pass the information from the call site to |
1291 // the relocation info. | 1301 // the relocation info. |
1292 TypeFeedbackId recorded_ast_id_; | 1302 TypeFeedbackId recorded_ast_id_; |
1293 | 1303 |
1294 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1304 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1295 | 1305 |
1296 // Decode branch instruction at pos and return branch target pos | 1306 // Decode branch instruction at pos and return branch target pos |
1297 int target_at(int pos); | 1307 int target_at(int pos); |
1298 | 1308 |
1299 // Patch branch instruction at pos to branch to given branch target pos | 1309 // Patch branch instruction at pos to branch to given branch target pos |
1300 void target_at_put(int pos, int target_pos); | 1310 void target_at_put(int pos, int target_pos); |
1301 | 1311 |
1302 // Record reloc info for current pc_ | 1312 // Record reloc info for current pc_ |
1303 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1313 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1304 void RecordRelocInfo(const RelocInfo& rinfo); | 1314 void RecordRelocInfo(const DeferredRelocInfo& rinfo); |
1305 | 1315 |
1306 // Block the emission of the trampoline pool before pc_offset. | 1316 // Block the emission of the trampoline pool before pc_offset. |
1307 void BlockTrampolinePoolBefore(int pc_offset) { | 1317 void BlockTrampolinePoolBefore(int pc_offset) { |
1308 if (no_trampoline_pool_before_ < pc_offset) | 1318 if (no_trampoline_pool_before_ < pc_offset) |
1309 no_trampoline_pool_before_ = pc_offset; | 1319 no_trampoline_pool_before_ = pc_offset; |
1310 } | 1320 } |
1311 | 1321 |
1312 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } | 1322 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } |
1313 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } | 1323 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } |
1314 bool is_trampoline_pool_blocked() const { | 1324 bool is_trampoline_pool_blocked() const { |
(...skipping 18 matching lines...) Expand all Loading... |
1333 int next_buffer_check_; // pc offset of next buffer check. | 1343 int next_buffer_check_; // pc offset of next buffer check. |
1334 | 1344 |
1335 // Emission of the trampoline pool may be blocked in some code sequences. | 1345 // Emission of the trampoline pool may be blocked in some code sequences. |
1336 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. | 1346 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. |
1337 int no_trampoline_pool_before_; // Block emission before this pc offset. | 1347 int no_trampoline_pool_before_; // Block emission before this pc offset. |
1338 | 1348 |
1339 // Relocation info generation | 1349 // Relocation info generation |
1340 // Each relocation is encoded as a variable size value | 1350 // Each relocation is encoded as a variable size value |
1341 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1351 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
1342 RelocInfoWriter reloc_info_writer; | 1352 RelocInfoWriter reloc_info_writer; |
1343 | 1353 std::vector<DeferredRelocInfo> relocations_; |
1344 // Internal reference positions, required for (potential) patching in | |
1345 // GrowBuffer(); contains only those internal references whose labels | |
1346 // are already bound. | |
1347 std::deque<int> internal_reference_positions_; | |
1348 std::deque<int> internal_reference_load_positions_; | |
1349 | 1354 |
1350 // The bound position, before this we cannot do instruction elimination. | 1355 // The bound position, before this we cannot do instruction elimination. |
1351 int last_bound_pos_; | 1356 int last_bound_pos_; |
1352 | 1357 |
1353 // Code emission | 1358 // Code emission |
1354 inline void CheckBuffer(); | 1359 inline void CheckBuffer(); |
1355 void GrowBuffer(int needed = 0); | 1360 void GrowBuffer(int needed = 0); |
1356 inline void emit(Instr x); | 1361 inline void emit(Instr x); |
1357 inline void CheckTrampolinePoolQuick(); | 1362 inline void CheckTrampolinePoolQuick(); |
1358 | 1363 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 | 1438 |
1434 | 1439 |
1435 class EnsureSpace BASE_EMBEDDED { | 1440 class EnsureSpace BASE_EMBEDDED { |
1436 public: | 1441 public: |
1437 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 1442 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
1438 }; | 1443 }; |
1439 } | 1444 } |
1440 } // namespace v8::internal | 1445 } // namespace v8::internal |
1441 | 1446 |
1442 #endif // V8_PPC_ASSEMBLER_PPC_H_ | 1447 #endif // V8_PPC_ASSEMBLER_PPC_H_ |
OLD | NEW |