Mercurial > hg > graal-jvmci-8
comparison src/cpu/sparc/vm/sharedRuntime_sparc.cpp @ 20764:271a32147391 jdk8u31-b06
8050022: linux-sparcv9: assert(SharedSkipVerify || obj->is_oop()) failed: sanity check
Summary: Provide promoted stack slots for floating-point registers in the SPARC c_calling_convention.
Reviewed-by: kvn, jrose, drchase
author | morris |
---|---|
date | Thu, 18 Sep 2014 11:46:33 -0700 |
parents | 0bf37f737702 |
children | 7848fc12602b 16aa1f621ec6 |
comparison
equal
deleted
inserted
replaced
20763:6b9488e6d7ee | 20764:271a32147391 |
---|---|
1126 #ifdef _LP64 | 1126 #ifdef _LP64 |
1127 // V9 convention: All things "as-if" on double-wide stack slots. | 1127 // V9 convention: All things "as-if" on double-wide stack slots. |
1128 // Hoist any int/ptr/long's in the first 6 to int regs. | 1128 // Hoist any int/ptr/long's in the first 6 to int regs. |
1129 // Hoist any flt/dbl's in the first 16 dbl regs. | 1129 // Hoist any flt/dbl's in the first 16 dbl regs. |
1130 int j = 0; // Count of actual args, not HALVES | 1130 int j = 0; // Count of actual args, not HALVES |
1131 for( int i=0; i<total_args_passed; i++, j++ ) { | 1131 VMRegPair param_array_reg; // location of the argument in the parameter array |
1132 switch( sig_bt[i] ) { | 1132 for (int i = 0; i < total_args_passed; i++, j++) { |
1133 param_array_reg.set_bad(); | |
1134 switch (sig_bt[i]) { | |
1133 case T_BOOLEAN: | 1135 case T_BOOLEAN: |
1134 case T_BYTE: | 1136 case T_BYTE: |
1135 case T_CHAR: | 1137 case T_CHAR: |
1136 case T_INT: | 1138 case T_INT: |
1137 case T_SHORT: | 1139 case T_SHORT: |
1138 regs[i].set1( int_stk_helper( j ) ); break; | 1140 regs[i].set1(int_stk_helper(j)); |
1141 break; | |
1139 case T_LONG: | 1142 case T_LONG: |
1140 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1143 assert(sig_bt[i+1] == T_VOID, "expecting half"); |
1141 case T_ADDRESS: // raw pointers, like current thread, for VM calls | 1144 case T_ADDRESS: // raw pointers, like current thread, for VM calls |
1142 case T_ARRAY: | 1145 case T_ARRAY: |
1143 case T_OBJECT: | 1146 case T_OBJECT: |
1144 case T_METADATA: | 1147 case T_METADATA: |
1145 regs[i].set2( int_stk_helper( j ) ); | 1148 regs[i].set2(int_stk_helper(j)); |
1146 break; | 1149 break; |
1147 case T_FLOAT: | 1150 case T_FLOAT: |
1148 if ( j < 16 ) { | 1151 // Per SPARC Compliance Definition 2.4.1, page 3P-12 available here |
1149 // V9ism: floats go in ODD registers | 1152 // http://www.sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz |
1150 regs[i].set1(as_FloatRegister(1 + (j<<1))->as_VMReg()); | 1153 // |
1151 } else { | 1154 // "When a callee prototype exists, and does not indicate variable arguments, |
1152 // V9ism: floats go in ODD stack slot | 1155 // floating-point values assigned to locations %sp+BIAS+128 through %sp+BIAS+248 |
1153 regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1))); | 1156 // will be promoted to floating-point registers" |
1157 // | |
1158 // By "promoted" it means that the argument is located in two places, an unused | |
1159 // spill slot in the "parameter array" (starts at %sp+BIAS+128), and a live | |
1160 // float register. In most cases, there are 6 or fewer arguments of any type, | |
1161 // and the standard parameter array slots (%sp+BIAS+128 to %sp+BIAS+176 exclusive) | |
1162 // serve as shadow slots. Per the spec floating point registers %d6 to %d16 | |
1163 // require slots beyond that (up to %sp+BIAS+248). | |
1164 // | |
1165 { | |
1166 // V9ism: floats go in ODD registers and stack slots | |
1167 int float_index = 1 + (j << 1); | |
1168 param_array_reg.set1(VMRegImpl::stack2reg(float_index)); | |
1169 if (j < 16) { | |
1170 regs[i].set1(as_FloatRegister(float_index)->as_VMReg()); | |
1171 } else { | |
1172 regs[i] = param_array_reg; | |
1173 } | |
1154 } | 1174 } |
1155 break; | 1175 break; |
1156 case T_DOUBLE: | 1176 case T_DOUBLE: |
1157 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1177 { |
1158 if ( j < 16 ) { | 1178 assert(sig_bt[i + 1] == T_VOID, "expecting half"); |
1159 // V9ism: doubles go in EVEN/ODD regs | 1179 // V9ism: doubles go in EVEN/ODD regs and stack slots |
1160 regs[i].set2(as_FloatRegister(j<<1)->as_VMReg()); | 1180 int double_index = (j << 1); |
1161 } else { | 1181 param_array_reg.set2(VMRegImpl::stack2reg(double_index)); |
1162 // V9ism: doubles go in EVEN/ODD stack slots | 1182 if (j < 16) { |
1163 regs[i].set2(VMRegImpl::stack2reg(j<<1)); | 1183 regs[i].set2(as_FloatRegister(double_index)->as_VMReg()); |
1184 } else { | |
1185 // V9ism: doubles go in EVEN/ODD stack slots | |
1186 regs[i] = param_array_reg; | |
1187 } | |
1164 } | 1188 } |
1165 break; | 1189 break; |
1166 case T_VOID: regs[i].set_bad(); j--; break; // Do not count HALVES | 1190 case T_VOID: |
1191 regs[i].set_bad(); | |
1192 j--; | |
1193 break; // Do not count HALVES | |
1167 default: | 1194 default: |
1168 ShouldNotReachHere(); | 1195 ShouldNotReachHere(); |
1169 } | 1196 } |
1170 if (regs[i].first()->is_stack()) { | 1197 // Keep track of the deepest parameter array slot. |
1171 int off = regs[i].first()->reg2stack(); | 1198 if (!param_array_reg.first()->is_valid()) { |
1199 param_array_reg = regs[i]; | |
1200 } | |
1201 if (param_array_reg.first()->is_stack()) { | |
1202 int off = param_array_reg.first()->reg2stack(); | |
1172 if (off > max_stack_slots) max_stack_slots = off; | 1203 if (off > max_stack_slots) max_stack_slots = off; |
1173 } | 1204 } |
1174 if (regs[i].second()->is_stack()) { | 1205 if (param_array_reg.second()->is_stack()) { |
1175 int off = regs[i].second()->reg2stack(); | 1206 int off = param_array_reg.second()->reg2stack(); |
1176 if (off > max_stack_slots) max_stack_slots = off; | 1207 if (off > max_stack_slots) max_stack_slots = off; |
1177 } | 1208 } |
1178 } | 1209 } |
1179 | 1210 |
1180 #else // _LP64 | 1211 #else // _LP64 |
1181 // V8 convention: first 6 things in O-regs, rest on stack. | 1212 // V8 convention: first 6 things in O-regs, rest on stack. |
1182 // Alignment is willy-nilly. | 1213 // Alignment is willy-nilly. |
1183 for( int i=0; i<total_args_passed; i++ ) { | 1214 for (int i = 0; i < total_args_passed; i++) { |
1184 switch( sig_bt[i] ) { | 1215 switch (sig_bt[i]) { |
1185 case T_ADDRESS: // raw pointers, like current thread, for VM calls | 1216 case T_ADDRESS: // raw pointers, like current thread, for VM calls |
1186 case T_ARRAY: | 1217 case T_ARRAY: |
1187 case T_BOOLEAN: | 1218 case T_BOOLEAN: |
1188 case T_BYTE: | 1219 case T_BYTE: |
1189 case T_CHAR: | 1220 case T_CHAR: |
1190 case T_FLOAT: | 1221 case T_FLOAT: |
1191 case T_INT: | 1222 case T_INT: |
1192 case T_OBJECT: | 1223 case T_OBJECT: |
1193 case T_METADATA: | 1224 case T_METADATA: |
1194 case T_SHORT: | 1225 case T_SHORT: |
1195 regs[i].set1( int_stk_helper( i ) ); | 1226 regs[i].set1(int_stk_helper(i)); |
1196 break; | 1227 break; |
1197 case T_DOUBLE: | 1228 case T_DOUBLE: |
1198 case T_LONG: | 1229 case T_LONG: |
1199 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1230 assert(sig_bt[i + 1] == T_VOID, "expecting half"); |
1200 regs[i].set_pair( int_stk_helper( i+1 ), int_stk_helper( i ) ); | 1231 regs[i].set_pair(int_stk_helper(i + 1), int_stk_helper(i)); |
1201 break; | 1232 break; |
1202 case T_VOID: regs[i].set_bad(); break; | 1233 case T_VOID: regs[i].set_bad(); break; |
1203 default: | 1234 default: |
1204 ShouldNotReachHere(); | 1235 ShouldNotReachHere(); |
1205 } | 1236 } |
1206 if (regs[i].first()->is_stack()) { | 1237 if (regs[i].first()->is_stack()) { |
1207 int off = regs[i].first()->reg2stack(); | 1238 int off = regs[i].first()->reg2stack(); |
1208 if (off > max_stack_slots) max_stack_slots = off; | 1239 if (off > max_stack_slots) max_stack_slots = off; |
1209 } | 1240 } |
1210 if (regs[i].second()->is_stack()) { | 1241 if (regs[i].second()->is_stack()) { |
1211 int off = regs[i].second()->reg2stack(); | 1242 int off = regs[i].second()->reg2stack(); |
1212 if (off > max_stack_slots) max_stack_slots = off; | 1243 if (off > max_stack_slots) max_stack_slots = off; |
1213 } | 1244 } |
1214 } | 1245 } |
1215 #endif // _LP64 | 1246 #endif // _LP64 |
1216 | 1247 |
1355 } else { | 1386 } else { |
1356 // Oop is in an input register pass we must flush it to the stack | 1387 // Oop is in an input register pass we must flush it to the stack |
1357 const Register rOop = src.first()->as_Register(); | 1388 const Register rOop = src.first()->as_Register(); |
1358 const Register rHandle = L5; | 1389 const Register rHandle = L5; |
1359 int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset; | 1390 int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset; |
1360 int offset = oop_slot*VMRegImpl::stack_slot_size; | 1391 int offset = oop_slot * VMRegImpl::stack_slot_size; |
1361 Label skip; | |
1362 __ st_ptr(rOop, SP, offset + STACK_BIAS); | 1392 __ st_ptr(rOop, SP, offset + STACK_BIAS); |
1363 if (is_receiver) { | 1393 if (is_receiver) { |
1364 *receiver_offset = oop_slot * VMRegImpl::stack_slot_size; | 1394 *receiver_offset = offset; |
1365 } | 1395 } |
1366 map->set_oop(VMRegImpl::stack2reg(oop_slot)); | 1396 map->set_oop(VMRegImpl::stack2reg(oop_slot)); |
1367 __ add(SP, offset + STACK_BIAS, rHandle); | 1397 __ add(SP, offset + STACK_BIAS, rHandle); |
1368 #ifdef _LP64 | 1398 #ifdef _LP64 |
1369 __ movr( Assembler::rc_z, rOop, G0, rHandle ); | 1399 __ movr( Assembler::rc_z, rOop, G0, rHandle ); |