| 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 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 ~BlockConstPoolScope() { | 1151 ~BlockConstPoolScope() { |
| 1152 assem_->EndBlockConstPool(); | 1152 assem_->EndBlockConstPool(); |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 private: | 1155 private: |
| 1156 Assembler* assem_; | 1156 Assembler* assem_; |
| 1157 | 1157 |
| 1158 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); | 1158 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); |
| 1159 }; | 1159 }; |
| 1160 | 1160 |
| 1161 // Postpone the generation of the constant pool for the specified number of | |
| 1162 // instructions. | |
| 1163 void BlockConstPoolFor(int instructions); | |
| 1164 | |
| 1165 // Debugging | 1161 // Debugging |
| 1166 | 1162 |
| 1167 // Mark address of the ExitJSFrame code. | 1163 // Mark address of the ExitJSFrame code. |
| 1168 void RecordJSReturn(); | 1164 void RecordJSReturn(); |
| 1169 | 1165 |
| 1170 // Mark address of a debug break slot. | 1166 // Mark address of a debug break slot. |
| 1171 void RecordDebugBreakSlot(); | 1167 void RecordDebugBreakSlot(); |
| 1172 | 1168 |
| 1173 // Record the AST id of the CallIC being compiled, so that it can be placed | 1169 // Record the AST id of the CallIC being compiled, so that it can be placed |
| 1174 // in the relocation information. | 1170 // in the relocation information. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 static bool IsStrRegFpNegOffset(Instr instr); | 1210 static bool IsStrRegFpNegOffset(Instr instr); |
| 1215 static bool IsLdrRegFpNegOffset(Instr instr); | 1211 static bool IsLdrRegFpNegOffset(Instr instr); |
| 1216 static bool IsLdrPcImmediateOffset(Instr instr); | 1212 static bool IsLdrPcImmediateOffset(Instr instr); |
| 1217 static bool IsTstImmediate(Instr instr); | 1213 static bool IsTstImmediate(Instr instr); |
| 1218 static bool IsCmpRegister(Instr instr); | 1214 static bool IsCmpRegister(Instr instr); |
| 1219 static bool IsCmpImmediate(Instr instr); | 1215 static bool IsCmpImmediate(Instr instr); |
| 1220 static Register GetCmpImmediateRegister(Instr instr); | 1216 static Register GetCmpImmediateRegister(Instr instr); |
| 1221 static int GetCmpImmediateRawImmediate(Instr instr); | 1217 static int GetCmpImmediateRawImmediate(Instr instr); |
| 1222 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1218 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
| 1223 | 1219 |
| 1224 // Buffer size and constant pool distance are checked together at regular | |
| 1225 // intervals of kBufferCheckInterval emitted bytes | |
| 1226 static const int kBufferCheckInterval = 1*KB/2; | |
| 1227 // Constants in pools are accessed via pc relative addressing, which can | 1220 // Constants in pools are accessed via pc relative addressing, which can |
| 1228 // reach +/-4KB thereby defining a maximum distance between the instruction | 1221 // reach +/-4KB thereby defining a maximum distance between the instruction |
| 1229 // and the accessed constant. We satisfy this constraint by limiting the | 1222 // and the accessed constant. |
| 1230 // distance between pools. | 1223 static const int kMaxDistToPool = 4*KB; |
| 1231 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval; | 1224 static const int kMaxNumPRInfo = kMaxDistToPool/kInstrSize; |
| 1232 static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize; | |
| 1233 | 1225 |
| 1234 // Check if is time to emit a constant pool for pending reloc info entries | 1226 // Postpone the generation of the constant pool for the specified number of |
| 1227 // instructions. |
| 1228 void BlockConstPoolFor(int instructions); |
| 1229 |
| 1230 // Check if is time to emit a constant pool. |
| 1235 void CheckConstPool(bool force_emit, bool require_jump); | 1231 void CheckConstPool(bool force_emit, bool require_jump); |
| 1236 | 1232 |
| 1237 protected: | 1233 protected: |
| 1238 // Relocation for a type-recording IC has the AST id added to it. This | 1234 // Relocation for a type-recording IC has the AST id added to it. This |
| 1239 // member variable is a way to pass the information from the call site to | 1235 // member variable is a way to pass the information from the call site to |
| 1240 // the relocation info. | 1236 // the relocation info. |
| 1241 unsigned ast_id_for_reloc_info_; | 1237 unsigned ast_id_for_reloc_info_; |
| 1242 | 1238 |
| 1243 bool emit_debug_code() const { return emit_debug_code_; } | 1239 bool emit_debug_code() const { return emit_debug_code_; } |
| 1244 | 1240 |
| 1245 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1241 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
| 1246 | 1242 |
| 1247 // Read/patch instructions | 1243 // Read/patch instructions |
| 1248 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1244 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
| 1249 void instr_at_put(int pos, Instr instr) { | 1245 void instr_at_put(int pos, Instr instr) { |
| 1250 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 1246 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
| 1251 } | 1247 } |
| 1252 | 1248 |
| 1253 // Decode branch instruction at pos and return branch target pos | 1249 // Decode branch instruction at pos and return branch target pos |
| 1254 int target_at(int pos); | 1250 int target_at(int pos); |
| 1255 | 1251 |
| 1256 // Patch branch instruction at pos to branch to given branch target pos | 1252 // Patch branch instruction at pos to branch to given branch target pos |
| 1257 void target_at_put(int pos, int target_pos); | 1253 void target_at_put(int pos, int target_pos); |
| 1258 | 1254 |
| 1259 // Block the emission of the constant pool before pc_offset | 1255 // Prevent contant pool emission until EndBlockConstPool is called. |
| 1260 void BlockConstPoolBefore(int pc_offset) { | 1256 // Call to this function can be nested but must be followed by an equal |
| 1261 if (no_const_pool_before_ < pc_offset) no_const_pool_before_ = pc_offset; | 1257 // number of call to EndBlockConstpool. |
| 1258 void StartBlockConstPool() { |
| 1259 if (const_pool_blocked_nesting_++ == 0) { |
| 1260 // Prevent constant pool checks happening by setting the next check to |
| 1261 // the biggest possible offset. |
| 1262 next_buffer_check_ = kMaxInt; |
| 1263 } |
| 1262 } | 1264 } |
| 1263 | 1265 |
| 1264 void StartBlockConstPool() { | 1266 // Resume constant pool emission. Need to be called as many time as |
| 1265 const_pool_blocked_nesting_++; | 1267 // StartBlockConstPool to have an effect. |
| 1268 void EndBlockConstPool() { |
| 1269 if (--const_pool_blocked_nesting_ == 0) { |
| 1270 // Check the constant pool hasn't been blocked for too long. |
| 1271 ASSERT((num_prinfo_ == 0) || |
| 1272 (pc_offset() < (first_const_pool_use_ + kMaxDistToPool))); |
| 1273 // Two cases: |
| 1274 // * no_const_pool_before_ >= next_buffer_check_ and the emission is |
| 1275 // still blocked |
| 1276 // * no_const_pool_before_ < next_buffer_check_ and the next emit will |
| 1277 // trigger a check. |
| 1278 next_buffer_check_ = no_const_pool_before_; |
| 1279 } |
| 1266 } | 1280 } |
| 1267 void EndBlockConstPool() { | 1281 |
| 1268 const_pool_blocked_nesting_--; | 1282 bool is_const_pool_blocked() const { |
| 1283 return (const_pool_blocked_nesting_ > 0) || |
| 1284 (pc_offset() < no_const_pool_before_); |
| 1269 } | 1285 } |
| 1270 bool is_const_pool_blocked() const { return const_pool_blocked_nesting_ > 0; } | |
| 1271 | 1286 |
| 1272 private: | 1287 private: |
| 1273 // Code buffer: | 1288 // Code buffer: |
| 1274 // The buffer into which code and relocation info are generated. | 1289 // The buffer into which code and relocation info are generated. |
| 1275 byte* buffer_; | 1290 byte* buffer_; |
| 1276 int buffer_size_; | 1291 int buffer_size_; |
| 1277 // True if the assembler owns the buffer, false if buffer is external. | 1292 // True if the assembler owns the buffer, false if buffer is external. |
| 1278 bool own_buffer_; | 1293 bool own_buffer_; |
| 1279 | 1294 |
| 1280 int next_buffer_check_; // pc offset of next buffer check | 1295 int next_buffer_check_; // pc offset of next buffer check |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1294 // necessary to emit the constant pool before the pool gets too far from the | 1309 // necessary to emit the constant pool before the pool gets too far from the |
| 1295 // location it is accessed from. In this case, we emit a jump over the emitted | 1310 // location it is accessed from. In this case, we emit a jump over the emitted |
| 1296 // constant pool. | 1311 // constant pool. |
| 1297 // Constants in the pool may be addresses of functions that gets relocated; | 1312 // Constants in the pool may be addresses of functions that gets relocated; |
| 1298 // if so, a relocation info entry is associated to the constant pool entry. | 1313 // if so, a relocation info entry is associated to the constant pool entry. |
| 1299 | 1314 |
| 1300 // Repeated checking whether the constant pool should be emitted is rather | 1315 // Repeated checking whether the constant pool should be emitted is rather |
| 1301 // expensive. By default we only check again once a number of instructions | 1316 // expensive. By default we only check again once a number of instructions |
| 1302 // has been generated. That also means that the sizing of the buffers is not | 1317 // has been generated. That also means that the sizing of the buffers is not |
| 1303 // an exact science, and that we rely on some slop to not overrun buffers. | 1318 // an exact science, and that we rely on some slop to not overrun buffers. |
| 1304 static const int kCheckConstIntervalInst = 32; | 1319 static const int kCheckPoolIntervalInst = 32; |
| 1305 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; | 1320 static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; |
| 1306 | 1321 |
| 1307 | 1322 |
| 1308 // Pools are emitted after function return and in dead code at (more or less) | 1323 // Average distance beetween a constant pool and the first instruction |
| 1309 // regular intervals of kDistBetweenPools bytes | 1324 // accessing the constant pool. Longer distance should result in less I-cache |
| 1310 static const int kDistBetweenPools = 1*KB; | 1325 // pollution. |
| 1326 // In practice the distance will be smaller since constant pool emission is |
| 1327 // forced after function return and sometimes after unconditional branches. |
| 1328 static const int kAvgDistToPool = kMaxDistToPool - kCheckPoolInterval; |
| 1311 | 1329 |
| 1312 // Emission of the constant pool may be blocked in some code sequences. | 1330 // Emission of the constant pool may be blocked in some code sequences. |
| 1313 int const_pool_blocked_nesting_; // Block emission if this is not zero. | 1331 int const_pool_blocked_nesting_; // Block emission if this is not zero. |
| 1314 int no_const_pool_before_; // Block emission before this pc offset. | 1332 int no_const_pool_before_; // Block emission before this pc offset. |
| 1315 | 1333 |
| 1316 // Keep track of the last emitted pool to guarantee a maximal distance | 1334 // Keep track of the first instruction requiring a constant pool entry |
| 1317 int last_const_pool_end_; // pc offset following the last constant pool | 1335 // since the previous constant pool was emitted. |
| 1336 int first_const_pool_use_; |
| 1318 | 1337 |
| 1319 // Relocation info generation | 1338 // Relocation info generation |
| 1320 // Each relocation is encoded as a variable size value | 1339 // Each relocation is encoded as a variable size value |
| 1321 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1340 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1322 RelocInfoWriter reloc_info_writer; | 1341 RelocInfoWriter reloc_info_writer; |
| 1323 // Relocation info records are also used during code generation as temporary | 1342 // Relocation info records are also used during code generation as temporary |
| 1324 // containers for constants and code target addresses until they are emitted | 1343 // containers for constants and code target addresses until they are emitted |
| 1325 // to the constant pool. These pending relocation info records are temporarily | 1344 // to the constant pool. These pending relocation info records are temporarily |
| 1326 // stored in a separate buffer until a constant pool is emitted. | 1345 // stored in a separate buffer until a constant pool is emitted. |
| 1327 // If every instruction in a long sequence is accessing the pool, we need one | 1346 // If every instruction in a long sequence is accessing the pool, we need one |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 public: | 1388 public: |
| 1370 explicit EnsureSpace(Assembler* assembler) { | 1389 explicit EnsureSpace(Assembler* assembler) { |
| 1371 assembler->CheckBuffer(); | 1390 assembler->CheckBuffer(); |
| 1372 } | 1391 } |
| 1373 }; | 1392 }; |
| 1374 | 1393 |
| 1375 | 1394 |
| 1376 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
| 1377 | 1396 |
| 1378 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1397 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |