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

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, 4 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 | « src/arm/assembler-arm.h ('k') | test/cctest/test-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 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 757
758 // Labels refer to positions in the (to be) generated code. 758 // Labels refer to positions in the (to be) generated code.
759 // There are bound, linked, and unused labels. 759 // There are bound, linked, and unused labels.
760 // 760 //
761 // Bound labels refer to known positions in the already 761 // Bound labels refer to known positions in the already
762 // generated code. pos() is the position the label refers to. 762 // generated code. pos() is the position the label refers to.
763 // 763 //
764 // Linked labels refer to unknown positions in the code 764 // Linked labels refer to unknown positions in the code
765 // to be generated; pos() is the position of the last 765 // to be generated; pos() is the position of the last
766 // instruction using the label. 766 // instruction using the label.
767 767 //
768 768 // The linked labels form a link chain by making the branch offset
769 // The link chain is terminated by a negative code position (must be aligned) 769 // in the instruction steam to point to the previous branch
770 const int kEndOfChain = -4; 770 // instruction using the same label.
771 //
772 // The link chain is terminated by a branch offset pointing to the
773 // same position.
771 774
772 775
773 int Assembler::target_at(int pos) { 776 int Assembler::target_at(int pos) {
774 Instr instr = instr_at(pos); 777 Instr instr = instr_at(pos);
775 if ((instr & ~kImm24Mask) == 0) { 778 if ((instr & ~kImm24Mask) == 0) {
776 // Emitted label constant, not part of a branch. 779 // Emitted label constant, not part of a branch.
777 return instr - (Code::kHeaderSize - kHeapObjectTag); 780 return instr - (Code::kHeaderSize - kHeapObjectTag);
778 } 781 }
779 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 782 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
780 int imm26 = ((instr & kImm24Mask) << 8) >> 6; 783 int imm26 = ((instr & kImm24Mask) << 8) >> 6;
781 if ((Instruction::ConditionField(instr) == kSpecialCondition) && 784 if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
782 ((instr & B24) != 0)) { 785 ((instr & B24) != 0)) {
783 // blx uses bit 24 to encode bit 2 of imm26 786 // blx uses bit 24 to encode bit 2 of imm26
784 imm26 += 2; 787 imm26 += 2;
785 } 788 }
786 return pos + kPcLoadDelta + imm26; 789 return pos + kPcLoadDelta + imm26;
787 } 790 }
788 791
789 792
790 void Assembler::target_at_put(int pos, int target_pos) { 793 void Assembler::target_at_put(int pos, int target_pos) {
791 Instr instr = instr_at(pos); 794 Instr instr = instr_at(pos);
792 if ((instr & ~kImm24Mask) == 0) { 795 if ((instr & ~kImm24Mask) == 0) {
793 ASSERT(target_pos == kEndOfChain || target_pos >= 0); 796 ASSERT(target_pos == pos || target_pos >= 0);
794 // Emitted label constant, not part of a branch. 797 // Emitted label constant, not part of a branch.
795 // Make label relative to Code* of generated Code object. 798 // Make label relative to Code* of generated Code object.
796 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 799 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
797 return; 800 return;
798 } 801 }
799 int imm26 = target_pos - (pos + kPcLoadDelta); 802 int imm26 = target_pos - (pos + kPcLoadDelta);
800 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 803 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
801 if (Instruction::ConditionField(instr) == kSpecialCondition) { 804 if (Instruction::ConditionField(instr) == kSpecialCondition) {
802 // blx uses bit 24 to encode bit 2 of imm26 805 // blx uses bit 24 to encode bit 2 of imm26
803 ASSERT((imm26 & 1) == 0); 806 ASSERT((imm26 & 1) == 0);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 } 882 }
880 L->bind_to(pos); 883 L->bind_to(pos);
881 884
882 // Keep track of the last bound label so we don't eliminate any instructions 885 // Keep track of the last bound label so we don't eliminate any instructions
883 // before a bound label. 886 // before a bound label.
884 if (pos > last_bound_pos_) 887 if (pos > last_bound_pos_)
885 last_bound_pos_ = pos; 888 last_bound_pos_ = pos;
886 } 889 }
887 890
888 891
889 void Assembler::link_to(Label* L, Label* appendix) {
890 if (appendix->is_linked()) {
891 if (L->is_linked()) {
892 // Append appendix to L's list.
893 int fixup_pos;
894 int link = L->pos();
895 do {
896 fixup_pos = link;
897 link = target_at(fixup_pos);
898 } while (link > 0);
899 ASSERT(link == kEndOfChain);
900 target_at_put(fixup_pos, appendix->pos());
901 } else {
902 // L is empty, simply use appendix.
903 *L = *appendix;
904 }
905 }
906 appendix->Unuse(); // appendix should not be used anymore
907 }
908
909
910 void Assembler::bind(Label* L) { 892 void Assembler::bind(Label* L) {
911 ASSERT(!L->is_bound()); // label can only be bound once 893 ASSERT(!L->is_bound()); // label can only be bound once
912 bind_to(L, pc_offset()); 894 bind_to(L, pc_offset());
913 } 895 }
914 896
915 897
916 void Assembler::next(Label* L) { 898 void Assembler::next(Label* L) {
917 ASSERT(L->is_linked()); 899 ASSERT(L->is_linked());
918 int link = target_at(L->pos()); 900 int link = target_at(L->pos());
919 if (link == kEndOfChain) { 901 if (link == L->pos()) {
902 // Branch target points to the same instuction. This is the end of the link
903 // chain.
920 L->Unuse(); 904 L->Unuse();
921 } else { 905 } else {
922 ASSERT(link >= 0); 906 ASSERT(link >= 0);
923 L->link_to(link); 907 L->link_to(link);
924 } 908 }
925 } 909 }
926 910
927 911
928 // Low-level code emission routines depending on the addressing mode. 912 // Low-level code emission routines depending on the addressing mode.
929 // If this returns true then you have to use the rotate_imm and immed_8 913 // 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
1222 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8); 1206 emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
1223 } 1207 }
1224 1208
1225 1209
1226 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { 1210 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
1227 int target_pos; 1211 int target_pos;
1228 if (L->is_bound()) { 1212 if (L->is_bound()) {
1229 target_pos = L->pos(); 1213 target_pos = L->pos();
1230 } else { 1214 } else {
1231 if (L->is_linked()) { 1215 if (L->is_linked()) {
1232 target_pos = L->pos(); // L's link 1216 // Point to previous instruction that uses the link.
1217 target_pos = L->pos();
1233 } else { 1218 } else {
1234 target_pos = kEndOfChain; 1219 // First entry of the link chain points to itself.
1220 target_pos = pc_offset();
1235 } 1221 }
1236 L->link_to(pc_offset()); 1222 L->link_to(pc_offset());
1237 } 1223 }
1238 1224
1239 // Block the emission of the constant pool, since the branch instruction must 1225 // Block the emission of the constant pool, since the branch instruction must
1240 // be emitted at the pc offset recorded by the label. 1226 // be emitted at the pc offset recorded by the label.
1241 BlockConstPoolFor(1); 1227 BlockConstPoolFor(1);
1242 return target_pos - (pc_offset() + kPcLoadDelta); 1228 return target_pos - (pc_offset() + kPcLoadDelta);
1243 } 1229 }
1244 1230
1245 1231
1246 void Assembler::label_at_put(Label* L, int at_offset) { 1232 void Assembler::label_at_put(Label* L, int at_offset) {
1247 int target_pos; 1233 int target_pos;
1248 if (L->is_bound()) { 1234 ASSERT(!L->is_bound());
1235 if (L->is_linked()) {
1236 // Point to previous instruction that uses the link.
1249 target_pos = L->pos(); 1237 target_pos = L->pos();
1250 } else { 1238 } else {
1251 if (L->is_linked()) { 1239 // First entry of the link chain points to itself.
1252 target_pos = L->pos(); // L's link 1240 target_pos = at_offset;
1253 } else {
1254 target_pos = kEndOfChain;
1255 }
1256 L->link_to(at_offset);
1257 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1258 } 1241 }
1242 L->link_to(at_offset);
1243 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1259 } 1244 }
1260 1245
1261 1246
1262 // Branch instructions. 1247 // Branch instructions.
1263 void Assembler::b(int branch_offset, Condition cond) { 1248 void Assembler::b(int branch_offset, Condition cond) {
1264 ASSERT((branch_offset & 3) == 0); 1249 ASSERT((branch_offset & 3) == 0);
1265 int imm24 = branch_offset >> 2; 1250 int imm24 = branch_offset >> 2;
1266 ASSERT(is_int24(imm24)); 1251 ASSERT(is_int24(imm24));
1267 emit(cond | B27 | B25 | (imm24 & kImm24Mask)); 1252 emit(cond | B27 | B25 | (imm24 & kImm24Mask));
1268 1253
(...skipping 2097 matching lines...) Expand 10 before | Expand all | Expand 10 after
3366 3351
3367 // Since a constant pool was just emitted, move the check offset forward by 3352 // Since a constant pool was just emitted, move the check offset forward by
3368 // the standard interval. 3353 // the standard interval.
3369 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3354 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3370 } 3355 }
3371 3356
3372 3357
3373 } } // namespace v8::internal 3358 } } // namespace v8::internal
3374 3359
3375 #endif // V8_TARGET_ARCH_ARM 3360 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | test/cctest/test-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698