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

Side by Side Diff: src/assembler-ia32.cc

Issue 4321: Remove x86 jump elimination. (Closed)
Patch Set: Created 12 years, 2 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
« no previous file with comments | « src/assembler-ia32.h ('k') | no next file » | 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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 if (kDebug && own_buffer_) { 309 if (kDebug && own_buffer_) {
310 memset(buffer_, 0xCC, buffer_size); // int3 310 memset(buffer_, 0xCC, buffer_size); // int3
311 } 311 }
312 312
313 // setup buffer pointers 313 // setup buffer pointers
314 ASSERT(buffer_ != NULL); 314 ASSERT(buffer_ != NULL);
315 pc_ = buffer_; 315 pc_ = buffer_;
316 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); 316 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
317 317
318 last_pc_ = NULL; 318 last_pc_ = NULL;
319 last_bound_pos_ = 0;
320 last_position_ = RelocInfo::kNoPosition; 319 last_position_ = RelocInfo::kNoPosition;
321 last_statement_position_ = RelocInfo::kNoPosition; 320 last_statement_position_ = RelocInfo::kNoPosition;
322 } 321 }
323 322
324 323
325 Assembler::~Assembler() { 324 Assembler::~Assembler() {
326 if (own_buffer_) { 325 if (own_buffer_) {
327 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 326 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
328 spare_buffer_ = buffer_; 327 spare_buffer_ = buffer_;
329 } else { 328 } else {
330 DeleteArray(buffer_); 329 DeleteArray(buffer_);
331 } 330 }
332 } 331 }
333 } 332 }
334 333
335 334
336 void Assembler::GetCode(CodeDesc* desc) { 335 void Assembler::GetCode(CodeDesc* desc) {
337 // finalize code 336 // finalize code
338 if (unbound_label_.is_linked())
339 bind_to(&unbound_label_, binding_pos_);
340
341 // (at this point overflow() may be true, but the gap ensures that 337 // (at this point overflow() may be true, but the gap ensures that
342 // we are still not overlapping instructions and relocation info) 338 // we are still not overlapping instructions and relocation info)
343 ASSERT(pc_ <= reloc_info_writer.pos()); // no overlap 339 ASSERT(pc_ <= reloc_info_writer.pos()); // no overlap
344 // setup desc 340 // setup desc
345 desc->buffer = buffer_; 341 desc->buffer = buffer_;
346 desc->buffer_size = buffer_size_; 342 desc->buffer_size = buffer_size_;
347 desc->instr_size = pc_offset(); 343 desc->instr_size = pc_offset();
348 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 344 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
349 345
350 Counters::reloc_info_size.Increment(desc->reloc_size); 346 Counters::reloc_info_size.Increment(desc->reloc_size);
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
1222 int fixup_pos = L->pos(); 1218 int fixup_pos = L->pos();
1223 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1219 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1224 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1220 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
1225 } 1221 }
1226 // relative address, relative to point after address 1222 // relative address, relative to point after address
1227 int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1223 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1228 long_at_put(fixup_pos, imm32); 1224 long_at_put(fixup_pos, imm32);
1229 disp.next(L); 1225 disp.next(L);
1230 } 1226 }
1231 L->bind_to(pos); 1227 L->bind_to(pos);
1232
1233 // do not eliminate jump instructions before the last bound position
1234 if (pos > last_bound_pos_)
1235 last_bound_pos_ = pos;
1236 } 1228 }
1237 1229
1238 1230
1239 void Assembler::link_to(Label* L, Label* appendix) { 1231 void Assembler::link_to(Label* L, Label* appendix) {
1240 EnsureSpace ensure_space(this); 1232 EnsureSpace ensure_space(this);
1241 last_pc_ = NULL; 1233 last_pc_ = NULL;
1242 if (appendix->is_linked()) { 1234 if (appendix->is_linked()) {
1243 if (L->is_linked()) { 1235 if (L->is_linked()) {
1244 // append appendix to L's list 1236 // append appendix to L's list
1245 Label p; 1237 Label p;
(...skipping 13 matching lines...) Expand all
1259 } 1251 }
1260 } 1252 }
1261 appendix->Unuse(); // appendix should not be used anymore 1253 appendix->Unuse(); // appendix should not be used anymore
1262 } 1254 }
1263 1255
1264 1256
1265 void Assembler::bind(Label* L) { 1257 void Assembler::bind(Label* L) {
1266 EnsureSpace ensure_space(this); 1258 EnsureSpace ensure_space(this);
1267 last_pc_ = NULL; 1259 last_pc_ = NULL;
1268 ASSERT(!L->is_bound()); // label can only be bound once 1260 ASSERT(!L->is_bound()); // label can only be bound once
1269 if (FLAG_eliminate_jumps) {
1270 // Resolve unbound label.
1271 if (unbound_label_.is_linked()) {
1272 // Unbound label exists => link it with L if same binding
1273 // position, otherwise fix it.
1274 if (binding_pos_ == pc_offset()) {
1275 // Link it to L's list.
1276 link_to(L, &unbound_label_);
1277 } else {
1278 // Otherwise bind unbound label.
1279 ASSERT(binding_pos_ < pc_offset());
1280 bind_to(&unbound_label_, binding_pos_);
1281 }
1282 }
1283 ASSERT(!unbound_label_.is_linked());
1284 // try to eliminate jumps to next instruction
1285 const int absolute_jump_size = 5;
1286 // Do not remove an already bound jump target.
1287 while (last_bound_pos_ < pc_offset() &&
1288 reloc_info_writer.last_pc() <= pc_ - absolute_jump_size &&
1289 L->is_linked() &&
1290 (L->pos() + static_cast<int>(sizeof(int32_t)) == pc_offset()) &&
1291 (disp_at(L).type() == Displacement::UNCONDITIONAL_JUMP)) {
1292 // Previous instruction is jump jumping immediately after it =>
1293 // eliminate it.
1294 // jmp expected.
1295 ASSERT(byte_at(pc_offset() - absolute_jump_size) == 0xE9);
1296 if (FLAG_print_jump_elimination) {
1297 PrintF("@ %d jump to next eliminated\n", L->pos());
1298 }
1299 // Remove first entry from label list.
1300 Displacement disp = disp_at(L);
1301 disp.next(L);
1302 // Eliminate instruction (set code pointers back).
1303 pc_ -= absolute_jump_size;
1304 // Make sure not to skip relocation information when rewinding.
1305 ASSERT(reloc_info_writer.last_pc() <= pc_);
1306 }
1307 // Delay fixup of L => store it as unbound label.
1308 unbound_label_ = *L;
1309 binding_pos_ = pc_offset();
1310 L->Unuse();
1311 }
1312 bind_to(L, pc_offset()); 1261 bind_to(L, pc_offset());
1313 } 1262 }
1314 1263
1315 1264
1316 void Assembler::call(Label* L) { 1265 void Assembler::call(Label* L) {
1317 EnsureSpace ensure_space(this); 1266 EnsureSpace ensure_space(this);
1318 last_pc_ = pc_; 1267 last_pc_ = pc_;
1319 if (L->is_bound()) { 1268 if (L->is_bound()) {
1320 const int long_size = 5; 1269 const int long_size = 5;
1321 int offs = L->pos() - pc_offset(); 1270 int offs = L->pos() - pc_offset();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 if (is_int8(offs - short_size)) { 1318 if (is_int8(offs - short_size)) {
1370 // 1110 1011 #8-bit disp 1319 // 1110 1011 #8-bit disp
1371 EMIT(0xEB); 1320 EMIT(0xEB);
1372 EMIT((offs - short_size) & 0xFF); 1321 EMIT((offs - short_size) & 0xFF);
1373 } else { 1322 } else {
1374 // 1110 1001 #32-bit disp 1323 // 1110 1001 #32-bit disp
1375 EMIT(0xE9); 1324 EMIT(0xE9);
1376 emit(offs - long_size); 1325 emit(offs - long_size);
1377 } 1326 }
1378 } else { 1327 } else {
1379 if (FLAG_eliminate_jumps &&
1380 unbound_label_.is_linked() &&
1381 binding_pos_ == pc_offset()) {
1382 // Current position is target of jumps
1383 if (FLAG_print_jump_elimination) {
1384 PrintF("eliminated jumps/calls to %d from ", binding_pos_);
1385 print(&unbound_label_);
1386 }
1387 link_to(L, &unbound_label_);
1388 }
1389 // 1110 1001 #32-bit disp 1328 // 1110 1001 #32-bit disp
1390 EMIT(0xE9); 1329 EMIT(0xE9);
1391 emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1330 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1392 } 1331 }
1393 } 1332 }
1394 1333
1395 1334
1396 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1335 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1397 EnsureSpace ensure_space(this); 1336 EnsureSpace ensure_space(this);
1398 last_pc_ = pc_; 1337 last_pc_ = pc_;
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 ASSERT(bound_label.is_bound()); 2021 ASSERT(bound_label.is_bound());
2083 ASSERT(0 <= position); 2022 ASSERT(0 <= position);
2084 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); 2023 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset());
2085 ASSERT(long_at(position) == 0); // only initialize once! 2024 ASSERT(long_at(position) == 0); // only initialize once!
2086 2025
2087 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); 2026 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos()));
2088 long_at_put(position, label_loc); 2027 long_at_put(position, label_loc);
2089 } 2028 }
2090 2029
2091 } } // namespace v8::internal 2030 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698