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

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

Issue 3807: Remove the ARM jump elimination. (Closed)
Patch Set: Blah 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-arm.h ('k') | src/flag-definitions.h » ('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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
331 spare_buffer_ = buffer_; 331 spare_buffer_ = buffer_;
332 } else { 332 } else {
333 DeleteArray(buffer_); 333 DeleteArray(buffer_);
334 } 334 }
335 } 335 }
336 } 336 }
337 337
338 338
339 void Assembler::GetCode(CodeDesc* desc) { 339 void Assembler::GetCode(CodeDesc* desc) {
340 // finalize code
341 if (unbound_label_.is_linked())
342 bind_to(&unbound_label_, binding_pos_);
343
344 // emit constant pool if necessary 340 // emit constant pool if necessary
345 CheckConstPool(true, false); 341 CheckConstPool(true, false);
346 ASSERT(num_prinfo_ == 0); 342 ASSERT(num_prinfo_ == 0);
347 343
348 // setup desc 344 // setup desc
349 desc->buffer = buffer_; 345 desc->buffer = buffer_;
350 desc->buffer_size = buffer_size_; 346 desc->buffer_size = buffer_size_;
351 desc->instr_size = pc_offset(); 347 desc->instr_size = pc_offset();
352 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 348 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
353 } 349 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 458
463 void Assembler::bind_to(Label* L, int pos) { 459 void Assembler::bind_to(Label* L, int pos) {
464 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 460 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
465 while (L->is_linked()) { 461 while (L->is_linked()) {
466 int fixup_pos = L->pos(); 462 int fixup_pos = L->pos();
467 next(L); // call next before overwriting link with target at fixup_pos 463 next(L); // call next before overwriting link with target at fixup_pos
468 target_at_put(fixup_pos, pos); 464 target_at_put(fixup_pos, pos);
469 } 465 }
470 L->bind_to(pos); 466 L->bind_to(pos);
471 467
472 // do not eliminate jump instructions before the last bound position 468 // Keep track of the last bound label so we don't eliminate any instructions
473 if (pos > last_bound_pos_) 469 // before a bound label.
470 if (pos > last_bound_pos_)
474 last_bound_pos_ = pos; 471 last_bound_pos_ = pos;
475 } 472 }
476 473
477 474
478 void Assembler::link_to(Label* L, Label* appendix) { 475 void Assembler::link_to(Label* L, Label* appendix) {
479 if (appendix->is_linked()) { 476 if (appendix->is_linked()) {
480 if (L->is_linked()) { 477 if (L->is_linked()) {
481 // append appendix to L's list 478 // append appendix to L's list
482 int fixup_pos; 479 int fixup_pos;
483 int link = L->pos(); 480 int link = L->pos();
484 do { 481 do {
485 fixup_pos = link; 482 fixup_pos = link;
486 link = target_at(fixup_pos); 483 link = target_at(fixup_pos);
487 } while (link > 0); 484 } while (link > 0);
488 ASSERT(link == kEndOfChain); 485 ASSERT(link == kEndOfChain);
489 target_at_put(fixup_pos, appendix->pos()); 486 target_at_put(fixup_pos, appendix->pos());
490 } else { 487 } else {
491 // L is empty, simply use appendix 488 // L is empty, simply use appendix
492 *L = *appendix; 489 *L = *appendix;
493 } 490 }
494 } 491 }
495 appendix->Unuse(); // appendix should not be used anymore 492 appendix->Unuse(); // appendix should not be used anymore
496 } 493 }
497 494
498 495
499 void Assembler::bind(Label* L) { 496 void Assembler::bind(Label* L) {
500 ASSERT(!L->is_bound()); // label can only be bound once 497 ASSERT(!L->is_bound()); // label can only be bound once
501 if (FLAG_eliminate_jumps) {
502 // Resolve unbound label.
503 if (unbound_label_.is_linked()) {
504 // Unbound label exists => link it with L if same binding
505 // position, otherwise fix it.
506 if (binding_pos_ == pc_offset()) {
507 // Link it to L's list.
508 link_to(L, &unbound_label_);
509 } else {
510 // Otherwise bind unbound label.
511 ASSERT(binding_pos_ < pc_offset());
512 bind_to(&unbound_label_, binding_pos_);
513 }
514 }
515 ASSERT(!unbound_label_.is_linked());
516 // Try to eliminate jumps to next instruction.
517 Instr instr;
518 // Do not remove an already bound jump target.
519 while (last_bound_pos_ < pc_offset() &&
520 reloc_info_writer.last_pc() <= pc_ - kInstrSize &&
521 L->is_linked() && L->pos() == pc_offset() - kInstrSize &&
522 (((instr = instr_at(L->pos())) & CondMask) != nv && // not blx
523 (instr & 15*B24) == 10*B24)) { // b<cond>, but not bl<cond>
524 // Previous instruction is b<cond> jumping immediately after it
525 // => eliminate it
526 if (FLAG_print_jump_elimination)
527 PrintF("@ %d jump to next eliminated\n", L->pos());
528 // Remove first entry from label list.
529 next(L);
530 // Eliminate instruction (set code pointers back).
531 pc_ -= kInstrSize;
532 // Make sure not to skip relocation information when rewinding.
533 ASSERT(reloc_info_writer.last_pc() <= pc_);
534 }
535 // delay fixup of L => store it as unbound label
536 unbound_label_ = *L;
537 binding_pos_ = pc_offset();
538 L->Unuse();
539 }
540 bind_to(L, pc_offset()); 498 bind_to(L, pc_offset());
541 } 499 }
542 500
543 501
544 void Assembler::next(Label* L) { 502 void Assembler::next(Label* L) {
545 ASSERT(L->is_linked()); 503 ASSERT(L->is_linked());
546 int link = target_at(L->pos()); 504 int link = target_at(L->pos());
547 if (link > 0) { 505 if (link > 0) {
548 L->link_to(link); 506 L->link_to(link);
549 } else { 507 } else {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 // post-indexed addressing requires W == 1; different than in addrmod2/3 679 // post-indexed addressing requires W == 1; different than in addrmod2/3
722 if ((am & P) == 0) 680 if ((am & P) == 0)
723 am |= W; 681 am |= W;
724 682
725 ASSERT(offset_8 >= 0); // no masking needed 683 ASSERT(offset_8 >= 0); // no masking needed
726 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8); 684 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
727 } 685 }
728 686
729 687
730 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { 688 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
731 // if we emit an unconditional jump/call and if the current position is the
732 // target of the unbound label, we can change the binding position of the
733 // unbound label, thereby eliminating an unnecessary jump
734 bool can_eliminate = false;
735 if (jump_elimination_allowed && FLAG_eliminate_jumps &&
736 unbound_label_.is_linked() && binding_pos_ == pc_offset()) {
737 can_eliminate = true;
738 if (FLAG_print_jump_elimination) {
739 PrintF("eliminated jumps/calls to %d from ", binding_pos_);
740 print(&unbound_label_);
741 }
742 }
743 int target_pos; 689 int target_pos;
744 if (L->is_bound()) { 690 if (L->is_bound()) {
745 target_pos = L->pos(); 691 target_pos = L->pos();
746 if (can_eliminate)
747 binding_pos_ = target_pos;
748 } else { 692 } else {
749 if (can_eliminate) 693 if (L->is_linked()) {
750 link_to(L, &unbound_label_); // may modify L's link
751 if (L->is_linked())
752 target_pos = L->pos(); // L's link 694 target_pos = L->pos(); // L's link
753 else 695 } else {
754 target_pos = kEndOfChain; 696 target_pos = kEndOfChain;
697 }
755 L->link_to(pc_offset()); 698 L->link_to(pc_offset());
756 } 699 }
757 700
758 // Block the emission of the constant pool, since the branch instruction must 701 // Block the emission of the constant pool, since the branch instruction must
759 // be emitted at the pc offset recorded by the label 702 // be emitted at the pc offset recorded by the label
760 BlockConstPoolBefore(pc_offset() + kInstrSize); 703 BlockConstPoolBefore(pc_offset() + kInstrSize);
761 704
762 return target_pos - pc_offset() - 8; 705 return target_pos - pc_offset() - 8;
763 } 706 }
764 707
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 bind(&after_pool); 1493 bind(&after_pool);
1551 } 1494 }
1552 1495
1553 // Since a constant pool was just emitted, move the check offset forward by 1496 // Since a constant pool was just emitted, move the check offset forward by
1554 // the standard interval. 1497 // the standard interval.
1555 next_buffer_check_ = pc_offset() + kCheckConstInterval; 1498 next_buffer_check_ = pc_offset() + kCheckConstInterval;
1556 } 1499 }
1557 1500
1558 1501
1559 } } // namespace v8::internal 1502 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler-arm.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698