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

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

Issue 17116006: Fix a crash when generating forward jumps to labels at very high assembly offsets (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 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
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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 679
680 // Labels refer to positions in the (to be) generated code. 680 // Labels refer to positions in the (to be) generated code.
681 // There are bound, linked, and unused labels. 681 // There are bound, linked, and unused labels.
682 // 682 //
683 // Bound labels refer to known positions in the already 683 // Bound labels refer to known positions in the already
684 // generated code. pos() is the position the label refers to. 684 // generated code. pos() is the position the label refers to.
685 // 685 //
686 // Linked labels refer to unknown positions in the code 686 // Linked labels refer to unknown positions in the code
687 // to be generated; pos() is the position of the last 687 // to be generated; pos() is the position of the last
688 // instruction using the label. 688 // instruction using the label.
689 689 //
690 690 // The linked labels form a link chain by making the branch offset
691 // The link chain is terminated by a negative code position (must be aligned) 691 // in the instruction steam to point to the previous branch
692 const int kEndOfChain = -4; 692 // instruction using the same label.
693 //
694 // The link chain is terminated by a branch offset pointing to the
695 // same position.
693 696
694 697
695 int Assembler::target_at(int pos) { 698 int Assembler::target_at(int pos) {
696 Instr instr = instr_at(pos); 699 Instr instr = instr_at(pos);
697 if ((instr & ~kImm24Mask) == 0) { 700 if ((instr & ~kImm24Mask) == 0) {
698 // Emitted label constant, not part of a branch. 701 // Emitted label constant, not part of a branch.
699 return instr - (Code::kHeaderSize - kHeapObjectTag); 702 return instr - (Code::kHeaderSize - kHeapObjectTag);
700 } 703 }
701 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 704 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
702 int imm26 = ((instr & kImm24Mask) << 8) >> 6; 705 int imm26 = ((instr & kImm24Mask) << 8) >> 6;
703 if ((Instruction::ConditionField(instr) == kSpecialCondition) && 706 if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
704 ((instr & B24) != 0)) { 707 ((instr & B24) != 0)) {
705 // blx uses bit 24 to encode bit 2 of imm26 708 // blx uses bit 24 to encode bit 2 of imm26
706 imm26 += 2; 709 imm26 += 2;
707 } 710 }
708 return pos + kPcLoadDelta + imm26; 711 return pos + kPcLoadDelta + imm26;
709 } 712 }
710 713
711 714
712 void Assembler::target_at_put(int pos, int target_pos) { 715 void Assembler::target_at_put(int pos, int target_pos) {
713 Instr instr = instr_at(pos); 716 Instr instr = instr_at(pos);
714 if ((instr & ~kImm24Mask) == 0) { 717 if ((instr & ~kImm24Mask) == 0) {
715 ASSERT(target_pos == kEndOfChain || target_pos >= 0); 718 ASSERT(target_pos == pos || target_pos >= 0);
716 // Emitted label constant, not part of a branch. 719 // Emitted label constant, not part of a branch.
717 // Make label relative to Code* of generated Code object. 720 // Make label relative to Code* of generated Code object.
718 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 721 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
719 return; 722 return;
720 } 723 }
721 int imm26 = target_pos - (pos + kPcLoadDelta); 724 int imm26 = target_pos - (pos + kPcLoadDelta);
722 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 725 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
723 if (Instruction::ConditionField(instr) == kSpecialCondition) { 726 if (Instruction::ConditionField(instr) == kSpecialCondition) {
724 // blx uses bit 24 to encode bit 2 of imm26 727 // blx uses bit 24 to encode bit 2 of imm26
725 ASSERT((imm26 & 1) == 0); 728 ASSERT((imm26 & 1) == 0);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 } 804 }
802 L->bind_to(pos); 805 L->bind_to(pos);
803 806
804 // Keep track of the last bound label so we don't eliminate any instructions 807 // Keep track of the last bound label so we don't eliminate any instructions
805 // before a bound label. 808 // before a bound label.
806 if (pos > last_bound_pos_) 809 if (pos > last_bound_pos_)
807 last_bound_pos_ = pos; 810 last_bound_pos_ = pos;
808 } 811 }
809 812
810 813
811 void Assembler::link_to(Label* L, Label* appendix) {
812 if (appendix->is_linked()) {
813 if (L->is_linked()) {
814 // Append appendix to L's list.
815 int fixup_pos;
816 int link = L->pos();
817 do {
818 fixup_pos = link;
819 link = target_at(fixup_pos);
820 } while (link > 0);
821 ASSERT(link == kEndOfChain);
822 target_at_put(fixup_pos, appendix->pos());
823 } else {
824 // L is empty, simply use appendix.
825 *L = *appendix;
826 }
827 }
828 appendix->Unuse(); // appendix should not be used anymore
829 }
830
831
832 void Assembler::bind(Label* L) { 814 void Assembler::bind(Label* L) {
833 ASSERT(!L->is_bound()); // label can only be bound once 815 ASSERT(!L->is_bound()); // label can only be bound once
834 bind_to(L, pc_offset()); 816 bind_to(L, pc_offset());
835 } 817 }
836 818
837 819
838 void Assembler::next(Label* L) { 820 void Assembler::next(Label* L) {
839 ASSERT(L->is_linked()); 821 ASSERT(L->is_linked());
840 int link = target_at(L->pos()); 822 int link = target_at(L->pos());
841 if (link == kEndOfChain) { 823 if (link == L->pos()) {
824 // Branch target points to the same instuction. This is the end of the link
825 // chain.
842 L->Unuse(); 826 L->Unuse();
843 } else { 827 } else {
844 ASSERT(link >= 0); 828 ASSERT(link >= 0);
845 L->link_to(link); 829 L->link_to(link);
846 } 830 }
847 } 831 }
848 832
849 833
850 // Low-level code emission routines depending on the addressing mode. 834 // Low-level code emission routines depending on the addressing mode.
851 // If this returns true then you have to use the rotate_imm and immed_8 835 // If this returns true then you have to use the rotate_imm and immed_8
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8); 1128 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
1145 } 1129 }
1146 1130
1147 1131
1148 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { 1132 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
1149 int target_pos; 1133 int target_pos;
1150 if (L->is_bound()) { 1134 if (L->is_bound()) {
1151 target_pos = L->pos(); 1135 target_pos = L->pos();
1152 } else { 1136 } else {
1153 if (L->is_linked()) { 1137 if (L->is_linked()) {
1154 target_pos = L->pos(); // L's link 1138 // Point to previous instruction that uses the link.
1139 target_pos = L->pos();
1155 } else { 1140 } else {
1156 target_pos = kEndOfChain; 1141 // First entry of the link chain points to itself.
1142 target_pos = pc_offset();
1157 } 1143 }
1158 L->link_to(pc_offset()); 1144 L->link_to(pc_offset());
1159 } 1145 }
1160 1146
1161 // Block the emission of the constant pool, since the branch instruction must 1147 // Block the emission of the constant pool, since the branch instruction must
1162 // be emitted at the pc offset recorded by the label. 1148 // be emitted at the pc offset recorded by the label.
1163 BlockConstPoolFor(1); 1149 BlockConstPoolFor(1);
1164 return target_pos - (pc_offset() + kPcLoadDelta); 1150 return target_pos - (pc_offset() + kPcLoadDelta);
1165 } 1151 }
1166 1152
1167 1153
1168 void Assembler::label_at_put(Label* L, int at_offset) { 1154 void Assembler::label_at_put(Label* L, int at_offset) {
1169 int target_pos; 1155 int target_pos;
1170 if (L->is_bound()) { 1156 ASSERT(!L->is_bound());
1157 if (L->is_linked()) {
1158 // Point to previous instruction that uses the link.
1171 target_pos = L->pos(); 1159 target_pos = L->pos();
1172 } else { 1160 } else {
1173 if (L->is_linked()) { 1161 // First entry of the link chain points to itself.
1174 target_pos = L->pos(); // L's link 1162 target_pos = at_offset;
1175 } else {
1176 target_pos = kEndOfChain;
1177 }
1178 L->link_to(at_offset);
1179 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1180 } 1163 }
1164 L->link_to(at_offset);
1165 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1181 } 1166 }
1182 1167
1183 1168
1184 // Branch instructions. 1169 // Branch instructions.
1185 void Assembler::b(int branch_offset, Condition cond) { 1170 void Assembler::b(int branch_offset, Condition cond) {
1186 ASSERT((branch_offset & 3) == 0); 1171 ASSERT((branch_offset & 3) == 0);
1187 int imm24 = branch_offset >> 2; 1172 int imm24 = branch_offset >> 2;
1188 ASSERT(is_int24(imm24)); 1173 ASSERT(is_int24(imm24));
1189 emit(cond | B27 | B25 | (imm24 & kImm24Mask)); 1174 emit(cond | B27 | B25 | (imm24 & kImm24Mask));
1190 1175
(...skipping 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 3087
3103 // Since a constant pool was just emitted, move the check offset forward by 3088 // Since a constant pool was just emitted, move the check offset forward by
3104 // the standard interval. 3089 // the standard interval.
3105 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3090 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3106 } 3091 }
3107 3092
3108 3093
3109 } } // namespace v8::internal 3094 } } // namespace v8::internal
3110 3095
3111 #endif // V8_TARGET_ARCH_ARM 3096 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698