< prev index next >

src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp

Print this page
rev 11926 : 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
Reviewed-by:


 123     return v->type()->as_LongConstant()->value() == 0L;
 124   } else if (v->type()->as_ObjectConstant() != NULL) {
 125     return v->type()->as_ObjectConstant()->value()->is_null_object();
 126   } else {
 127     return false;
 128   }
 129 }
 130 
 131 
 132 bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { return false; }
 133 
 134 
 135 LIR_Opr LIRGenerator::safepoint_poll_register() {
 136   return LIR_OprFact::illegalOpr;
 137 }
 138 
 139 
 140 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
 141                                             int shift, int disp, BasicType type) {
 142   assert(base->is_register(), "must be");

 143 
 144   // accumulate fixed displacements
 145   if (index->is_constant()) {
 146     disp += index->as_constant_ptr()->as_jint() << shift;
 147     index = LIR_OprFact::illegalOpr;
 148   }
 149 
 150   if (index->is_register()) {
 151     // apply the shift and accumulate the displacement
 152     if (shift > 0) {
 153       LIR_Opr tmp = new_pointer_register();
 154       __ shift_left(index, shift, tmp);
 155       index = tmp;
 156     }
 157     if (disp != 0) {
 158       LIR_Opr tmp = new_pointer_register();
 159       if (Assembler::operand_valid_for_add_sub_immediate(disp)) {
 160         __ add(tmp, tmp, LIR_OprFact::intptrConst(disp));
 161         index = tmp;
 162       } else {
 163         __ move(tmp, LIR_OprFact::intptrConst(disp));
 164         __ add(tmp, index, tmp);
 165         index = tmp;
 166       }
 167       disp = 0;
 168     }
 169   } else if (disp != 0 && !Address::offset_ok_for_immed(disp, shift)) {
 170     // index is illegal so replace it with the displacement loaded into a register
 171     index = new_pointer_register();
 172     __ move(LIR_OprFact::intptrConst(disp), index);
 173     disp = 0;
 174   }
 175 
 176   // at this point we either have base + index or base + displacement
 177   if (disp == 0) {
 178     return new LIR_Address(base, index, type);
 179   } else {
 180     assert(Address::offset_ok_for_immed(disp, 0), "must be");
 181     return new LIR_Address(base, disp, type);
 182   }
 183 }
 184 
 185 
 186 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
 187                                               BasicType type, bool needs_card_mark) {
 188   int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
 189   int elem_size = type2aelembytes(type);
 190   int shift = exact_log2(elem_size);
 191 
 192   LIR_Address* addr;
 193   if (index_opr->is_constant()) {
 194     addr = new LIR_Address(array_opr,
 195                            offset_in_bytes + index_opr->as_jint() * elem_size, type);
 196   } else {
 197     if (offset_in_bytes) {
 198       LIR_Opr tmp = new_pointer_register();
 199       __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp);
 200       array_opr = tmp;
 201       offset_in_bytes = 0;




 123     return v->type()->as_LongConstant()->value() == 0L;
 124   } else if (v->type()->as_ObjectConstant() != NULL) {
 125     return v->type()->as_ObjectConstant()->value()->is_null_object();
 126   } else {
 127     return false;
 128   }
 129 }
 130 
 131 
 132 bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { return false; }
 133 
 134 
 135 LIR_Opr LIRGenerator::safepoint_poll_register() {
 136   return LIR_OprFact::illegalOpr;
 137 }
 138 
 139 
 140 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
 141                                             int shift, int disp, BasicType type) {
 142   assert(base->is_register(), "must be");
 143   intx large_disp = disp;
 144 
 145   // accumulate fixed displacements
 146   if (index->is_constant()) {
 147     large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift;
 148     index = LIR_OprFact::illegalOpr;
 149   }
 150 
 151   if (index->is_register()) {
 152     // apply the shift and accumulate the displacement
 153     if (shift > 0) {
 154       LIR_Opr tmp = new_pointer_register();
 155       __ shift_left(index, shift, tmp);
 156       index = tmp;
 157     }
 158     if (large_disp != 0) {
 159       LIR_Opr tmp = new_pointer_register();
 160       if (Assembler::operand_valid_for_add_sub_immediate(large_disp)) {
 161         __ add(tmp, tmp, LIR_OprFact::intptrConst(large_disp));
 162         index = tmp;
 163       } else {
 164         __ move(tmp, LIR_OprFact::intptrConst(large_disp));
 165         __ add(tmp, index, tmp);
 166         index = tmp;
 167       }
 168       large_disp = 0;
 169     }
 170   } else if (large_disp != 0 && !Address::offset_ok_for_immed(large_disp, shift)) {
 171     // index is illegal so replace it with the displacement loaded into a register
 172     index = new_pointer_register();
 173     __ move(LIR_OprFact::intptrConst(large_disp), index);
 174     large_disp = 0;
 175   }
 176 
 177   // at this point we either have base + index or base + displacement
 178   if (large_disp == 0) {
 179     return new LIR_Address(base, index, type);
 180   } else {
 181     assert(Address::offset_ok_for_immed(large_disp, 0), "must be");
 182     return new LIR_Address(base, large_disp, type);
 183   }
 184 }
 185 
 186 
 187 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
 188                                               BasicType type, bool needs_card_mark) {
 189   int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
 190   int elem_size = type2aelembytes(type);
 191   int shift = exact_log2(elem_size);
 192 
 193   LIR_Address* addr;
 194   if (index_opr->is_constant()) {
 195     addr = new LIR_Address(array_opr,
 196                            offset_in_bytes + index_opr->as_jint() * elem_size, type);
 197   } else {
 198     if (offset_in_bytes) {
 199       LIR_Opr tmp = new_pointer_register();
 200       __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp);
 201       array_opr = tmp;
 202       offset_in_bytes = 0;


< prev index next >