| 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 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 ~BlockConstPoolScope() { | 1186 ~BlockConstPoolScope() { |
| 1187 assem_->EndBlockConstPool(); | 1187 assem_->EndBlockConstPool(); |
| 1188 } | 1188 } |
| 1189 | 1189 |
| 1190 private: | 1190 private: |
| 1191 Assembler* assem_; | 1191 Assembler* assem_; |
| 1192 | 1192 |
| 1193 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); | 1193 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); |
| 1194 }; | 1194 }; |
| 1195 | 1195 |
| 1196 // Postpone the generation of the constant pool for the specified number of |
| 1197 // instructions. |
| 1198 void BlockConstPoolFor(int instructions); |
| 1199 |
| 1196 // Debugging | 1200 // Debugging |
| 1197 | 1201 |
| 1198 // Mark address of the ExitJSFrame code. | 1202 // Mark address of the ExitJSFrame code. |
| 1199 void RecordJSReturn(); | 1203 void RecordJSReturn(); |
| 1200 | 1204 |
| 1201 // Mark address of a debug break slot. | 1205 // Mark address of a debug break slot. |
| 1202 void RecordDebugBreakSlot(); | 1206 void RecordDebugBreakSlot(); |
| 1203 | 1207 |
| 1204 // Record the AST id of the CallIC being compiled, so that it can be placed | 1208 // Record the AST id of the CallIC being compiled, so that it can be placed |
| 1205 // in the relocation information. | 1209 // in the relocation information. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1259 static bool IsStrRegFpNegOffset(Instr instr); | 1263 static bool IsStrRegFpNegOffset(Instr instr); |
| 1260 static bool IsLdrRegFpNegOffset(Instr instr); | 1264 static bool IsLdrRegFpNegOffset(Instr instr); |
| 1261 static bool IsLdrPcImmediateOffset(Instr instr); | 1265 static bool IsLdrPcImmediateOffset(Instr instr); |
| 1262 static bool IsTstImmediate(Instr instr); | 1266 static bool IsTstImmediate(Instr instr); |
| 1263 static bool IsCmpRegister(Instr instr); | 1267 static bool IsCmpRegister(Instr instr); |
| 1264 static bool IsCmpImmediate(Instr instr); | 1268 static bool IsCmpImmediate(Instr instr); |
| 1265 static Register GetCmpImmediateRegister(Instr instr); | 1269 static Register GetCmpImmediateRegister(Instr instr); |
| 1266 static int GetCmpImmediateRawImmediate(Instr instr); | 1270 static int GetCmpImmediateRawImmediate(Instr instr); |
| 1267 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1271 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
| 1268 | 1272 |
| 1273 // Buffer size and constant pool distance are checked together at regular |
| 1274 // intervals of kBufferCheckInterval emitted bytes |
| 1275 static const int kBufferCheckInterval = 1*KB/2; |
| 1269 // Constants in pools are accessed via pc relative addressing, which can | 1276 // Constants in pools are accessed via pc relative addressing, which can |
| 1270 // reach +/-4KB thereby defining a maximum distance between the instruction | 1277 // reach +/-4KB thereby defining a maximum distance between the instruction |
| 1271 // and the accessed constant. | 1278 // and the accessed constant. We satisfy this constraint by limiting the |
| 1272 static const int kMaxDistToPool = 4*KB; | 1279 // distance between pools. |
| 1273 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize; | 1280 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval; |
| 1281 static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize; |
| 1274 | 1282 |
| 1275 // Postpone the generation of the constant pool for the specified number of | 1283 // Check if is time to emit a constant pool for pending reloc info entries |
| 1276 // instructions. | |
| 1277 void BlockConstPoolFor(int instructions); | |
| 1278 | |
| 1279 // Check if is time to emit a constant pool. | |
| 1280 void CheckConstPool(bool force_emit, bool require_jump); | 1284 void CheckConstPool(bool force_emit, bool require_jump); |
| 1281 | 1285 |
| 1282 protected: | 1286 protected: |
| 1283 // Relocation for a type-recording IC has the AST id added to it. This | 1287 // Relocation for a type-recording IC has the AST id added to it. This |
| 1284 // member variable is a way to pass the information from the call site to | 1288 // member variable is a way to pass the information from the call site to |
| 1285 // the relocation info. | 1289 // the relocation info. |
| 1286 unsigned recorded_ast_id_; | 1290 unsigned recorded_ast_id_; |
| 1287 | 1291 |
| 1288 bool emit_debug_code() const { return emit_debug_code_; } | 1292 bool emit_debug_code() const { return emit_debug_code_; } |
| 1289 | 1293 |
| 1290 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1294 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
| 1291 | 1295 |
| 1292 // Decode branch instruction at pos and return branch target pos | 1296 // Decode branch instruction at pos and return branch target pos |
| 1293 int target_at(int pos); | 1297 int target_at(int pos); |
| 1294 | 1298 |
| 1295 // Patch branch instruction at pos to branch to given branch target pos | 1299 // Patch branch instruction at pos to branch to given branch target pos |
| 1296 void target_at_put(int pos, int target_pos); | 1300 void target_at_put(int pos, int target_pos); |
| 1297 | 1301 |
| 1298 // Prevent contant pool emission until EndBlockConstPool is called. | 1302 // Block the emission of the constant pool before pc_offset |
| 1299 // Call to this function can be nested but must be followed by an equal | 1303 void BlockConstPoolBefore(int pc_offset) { |
| 1300 // number of call to EndBlockConstpool. | 1304 if (no_const_pool_before_ < pc_offset) no_const_pool_before_ = pc_offset; |
| 1301 void StartBlockConstPool() { | |
| 1302 if (const_pool_blocked_nesting_++ == 0) { | |
| 1303 // Prevent constant pool checks happening by setting the next check to | |
| 1304 // the biggest possible offset. | |
| 1305 next_buffer_check_ = kMaxInt; | |
| 1306 } | |
| 1307 } | 1305 } |
| 1308 | 1306 |
| 1309 // Resume constant pool emission. Need to be called as many time as | 1307 void StartBlockConstPool() { |
| 1310 // StartBlockConstPool to have an effect. | 1308 const_pool_blocked_nesting_++; |
| 1309 } |
| 1311 void EndBlockConstPool() { | 1310 void EndBlockConstPool() { |
| 1312 if (--const_pool_blocked_nesting_ == 0) { | 1311 const_pool_blocked_nesting_--; |
| 1313 // Check the constant pool hasn't been blocked for too long. | |
| 1314 ASSERT((num_pending_reloc_info_ == 0) || | |
| 1315 (pc_offset() < (first_const_pool_use_ + kMaxDistToPool))); | |
| 1316 // Two cases: | |
| 1317 // * no_const_pool_before_ >= next_buffer_check_ and the emission is | |
| 1318 // still blocked | |
| 1319 // * no_const_pool_before_ < next_buffer_check_ and the next emit will | |
| 1320 // trigger a check. | |
| 1321 next_buffer_check_ = no_const_pool_before_; | |
| 1322 } | |
| 1323 } | 1312 } |
| 1324 | 1313 bool is_const_pool_blocked() const { return const_pool_blocked_nesting_ > 0; } |
| 1325 bool is_const_pool_blocked() const { | |
| 1326 return (const_pool_blocked_nesting_ > 0) || | |
| 1327 (pc_offset() < no_const_pool_before_); | |
| 1328 } | |
| 1329 | 1314 |
| 1330 private: | 1315 private: |
| 1331 // Code buffer: | 1316 // Code buffer: |
| 1332 // The buffer into which code and relocation info are generated. | 1317 // The buffer into which code and relocation info are generated. |
| 1333 byte* buffer_; | 1318 byte* buffer_; |
| 1334 int buffer_size_; | 1319 int buffer_size_; |
| 1335 // True if the assembler owns the buffer, false if buffer is external. | 1320 // True if the assembler owns the buffer, false if buffer is external. |
| 1336 bool own_buffer_; | 1321 bool own_buffer_; |
| 1337 | 1322 |
| 1338 int next_buffer_check_; // pc offset of next buffer check | 1323 int next_buffer_check_; // pc offset of next buffer check |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1352 // necessary to emit the constant pool before the pool gets too far from the | 1337 // necessary to emit the constant pool before the pool gets too far from the |
| 1353 // location it is accessed from. In this case, we emit a jump over the emitted | 1338 // location it is accessed from. In this case, we emit a jump over the emitted |
| 1354 // constant pool. | 1339 // constant pool. |
| 1355 // Constants in the pool may be addresses of functions that gets relocated; | 1340 // Constants in the pool may be addresses of functions that gets relocated; |
| 1356 // if so, a relocation info entry is associated to the constant pool entry. | 1341 // if so, a relocation info entry is associated to the constant pool entry. |
| 1357 | 1342 |
| 1358 // Repeated checking whether the constant pool should be emitted is rather | 1343 // Repeated checking whether the constant pool should be emitted is rather |
| 1359 // expensive. By default we only check again once a number of instructions | 1344 // expensive. By default we only check again once a number of instructions |
| 1360 // has been generated. That also means that the sizing of the buffers is not | 1345 // has been generated. That also means that the sizing of the buffers is not |
| 1361 // an exact science, and that we rely on some slop to not overrun buffers. | 1346 // an exact science, and that we rely on some slop to not overrun buffers. |
| 1362 static const int kCheckPoolIntervalInst = 32; | 1347 static const int kCheckConstIntervalInst = 32; |
| 1363 static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; | 1348 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; |
| 1364 | 1349 |
| 1365 | 1350 |
| 1366 // Average distance beetween a constant pool and the first instruction | 1351 // Pools are emitted after function return and in dead code at (more or less) |
| 1367 // accessing the constant pool. Longer distance should result in less I-cache | 1352 // regular intervals of kDistBetweenPools bytes |
| 1368 // pollution. | 1353 static const int kDistBetweenPools = 1*KB; |
| 1369 // In practice the distance will be smaller since constant pool emission is | |
| 1370 // forced after function return and sometimes after unconditional branches. | |
| 1371 static const int kAvgDistToPool = kMaxDistToPool - kCheckPoolInterval; | |
| 1372 | 1354 |
| 1373 // Emission of the constant pool may be blocked in some code sequences. | 1355 // Emission of the constant pool may be blocked in some code sequences. |
| 1374 int const_pool_blocked_nesting_; // Block emission if this is not zero. | 1356 int const_pool_blocked_nesting_; // Block emission if this is not zero. |
| 1375 int no_const_pool_before_; // Block emission before this pc offset. | 1357 int no_const_pool_before_; // Block emission before this pc offset. |
| 1376 | 1358 |
| 1377 // Keep track of the first instruction requiring a constant pool entry | 1359 // Keep track of the last emitted pool to guarantee a maximal distance |
| 1378 // since the previous constant pool was emitted. | 1360 int last_const_pool_end_; // pc offset following the last constant pool |
| 1379 int first_const_pool_use_; | |
| 1380 | 1361 |
| 1381 // Relocation info generation | 1362 // Relocation info generation |
| 1382 // Each relocation is encoded as a variable size value | 1363 // Each relocation is encoded as a variable size value |
| 1383 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1364 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1384 RelocInfoWriter reloc_info_writer; | 1365 RelocInfoWriter reloc_info_writer; |
| 1385 | |
| 1386 // Relocation info records are also used during code generation as temporary | 1366 // Relocation info records are also used during code generation as temporary |
| 1387 // containers for constants and code target addresses until they are emitted | 1367 // containers for constants and code target addresses until they are emitted |
| 1388 // to the constant pool. These pending relocation info records are temporarily | 1368 // to the constant pool. These pending relocation info records are temporarily |
| 1389 // stored in a separate buffer until a constant pool is emitted. | 1369 // stored in a separate buffer until a constant pool is emitted. |
| 1390 // If every instruction in a long sequence is accessing the pool, we need one | 1370 // If every instruction in a long sequence is accessing the pool, we need one |
| 1391 // pending relocation entry per instruction. | 1371 // pending relocation entry per instruction. |
| 1392 | 1372 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info |
| 1393 // the buffer of pending relocation info | 1373 int num_prinfo_; // number of pending reloc info entries in the buffer |
| 1394 RelocInfo pending_reloc_info_[kMaxNumPendingRelocInfo]; | |
| 1395 // number of pending reloc info entries in the buffer | |
| 1396 int num_pending_reloc_info_; | |
| 1397 | 1374 |
| 1398 // The bound position, before this we cannot do instruction elimination. | 1375 // The bound position, before this we cannot do instruction elimination. |
| 1399 int last_bound_pos_; | 1376 int last_bound_pos_; |
| 1400 | 1377 |
| 1401 // Code emission | 1378 // Code emission |
| 1402 inline void CheckBuffer(); | 1379 inline void CheckBuffer(); |
| 1403 void GrowBuffer(); | 1380 void GrowBuffer(); |
| 1404 inline void emit(Instr x); | 1381 inline void emit(Instr x); |
| 1405 | 1382 |
| 1406 // Instruction generation | 1383 // Instruction generation |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1435 public: | 1412 public: |
| 1436 explicit EnsureSpace(Assembler* assembler) { | 1413 explicit EnsureSpace(Assembler* assembler) { |
| 1437 assembler->CheckBuffer(); | 1414 assembler->CheckBuffer(); |
| 1438 } | 1415 } |
| 1439 }; | 1416 }; |
| 1440 | 1417 |
| 1441 | 1418 |
| 1442 } } // namespace v8::internal | 1419 } } // namespace v8::internal |
| 1443 | 1420 |
| 1444 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1421 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |