Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(618)

Side by Side Diff: src/arm/assembler-arm.h

Issue 7108061: ARM: Clean up literal pool generation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 kMaxNumPendingRelocInfo = 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_pending_reloc_info_ == 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
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;
1342
1323 // Relocation info records are also used during code generation as temporary 1343 // Relocation info records are also used during code generation as temporary
1324 // containers for constants and code target addresses until they are emitted 1344 // containers for constants and code target addresses until they are emitted
1325 // to the constant pool. These pending relocation info records are temporarily 1345 // to the constant pool. These pending relocation info records are temporarily
1326 // stored in a separate buffer until a constant pool is emitted. 1346 // 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 1347 // If every instruction in a long sequence is accessing the pool, we need one
1328 // pending relocation entry per instruction. 1348 // pending relocation entry per instruction.
1329 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info 1349
1330 int num_prinfo_; // number of pending reloc info entries in the buffer 1350 // the buffer of pending relocation info
1351 RelocInfo pending_reloc_info_[kMaxNumPendingRelocInfo];
1352 // number of pending reloc info entries in the buffer
1353 int num_pending_reloc_info_;
1331 1354
1332 // The bound position, before this we cannot do instruction elimination. 1355 // The bound position, before this we cannot do instruction elimination.
1333 int last_bound_pos_; 1356 int last_bound_pos_;
1334 1357
1335 // Code emission 1358 // Code emission
1336 inline void CheckBuffer(); 1359 inline void CheckBuffer();
1337 void GrowBuffer(); 1360 void GrowBuffer();
1338 inline void emit(Instr x); 1361 inline void emit(Instr x);
1339 1362
1340 // Instruction generation 1363 // Instruction generation
(...skipping 28 matching lines...) Expand all
1369 public: 1392 public:
1370 explicit EnsureSpace(Assembler* assembler) { 1393 explicit EnsureSpace(Assembler* assembler) {
1371 assembler->CheckBuffer(); 1394 assembler->CheckBuffer();
1372 } 1395 }
1373 }; 1396 };
1374 1397
1375 1398
1376 } } // namespace v8::internal 1399 } } // namespace v8::internal
1377 1400
1378 #endif // V8_ARM_ASSEMBLER_ARM_H_ 1401 #endif // V8_ARM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698