Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/interp_masm_x86_32.cpp @ 1206:87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
Summary: Fix incorrect marking of methods as not compilable.
Reviewed-by: never
author | kvn |
---|---|
date | Mon, 01 Feb 2010 16:49:49 -0800 |
parents | 85f13cdfbc1d |
children | 576e77447e3c |
comparison
equal
deleted
inserted
replaced
1205:5fcfaa1ad96f | 1206:87684f1a88b5 |
---|---|
1237 Label profile_continue; | 1237 Label profile_continue; |
1238 | 1238 |
1239 // If no method data exists, go to profile_continue. | 1239 // If no method data exists, go to profile_continue. |
1240 test_method_data_pointer(mdp, profile_continue); | 1240 test_method_data_pointer(mdp, profile_continue); |
1241 | 1241 |
1242 // We are making a call. Increment the count. | |
1243 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); | |
1244 | |
1245 Label skip_receiver_profile; | 1242 Label skip_receiver_profile; |
1246 if (receiver_can_be_null) { | 1243 if (receiver_can_be_null) { |
1244 Label not_null; | |
1247 testptr(receiver, receiver); | 1245 testptr(receiver, receiver); |
1248 jcc(Assembler::zero, skip_receiver_profile); | 1246 jccb(Assembler::notZero, not_null); |
1247 // We are making a call. Increment the count for null receiver. | |
1248 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); | |
1249 jmp(skip_receiver_profile); | |
1250 bind(not_null); | |
1249 } | 1251 } |
1250 | 1252 |
1251 // Record the receiver type. | 1253 // Record the receiver type. |
1252 record_klass_in_profile(receiver, mdp, reg2); | 1254 record_klass_in_profile(receiver, mdp, reg2, true); |
1253 bind(skip_receiver_profile); | 1255 bind(skip_receiver_profile); |
1254 | 1256 |
1255 // The method data pointer needs to be updated to reflect the new target. | 1257 // The method data pointer needs to be updated to reflect the new target. |
1256 update_mdp_by_constant(mdp, | 1258 update_mdp_by_constant(mdp, |
1257 in_bytes(VirtualCallData:: | 1259 in_bytes(VirtualCallData:: |
1261 } | 1263 } |
1262 | 1264 |
1263 | 1265 |
1264 void InterpreterMacroAssembler::record_klass_in_profile_helper( | 1266 void InterpreterMacroAssembler::record_klass_in_profile_helper( |
1265 Register receiver, Register mdp, | 1267 Register receiver, Register mdp, |
1266 Register reg2, | 1268 Register reg2, int start_row, |
1267 int start_row, Label& done) { | 1269 Label& done, bool is_virtual_call) { |
1268 if (TypeProfileWidth == 0) | 1270 if (TypeProfileWidth == 0) { |
1271 if (is_virtual_call) { | |
1272 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); | |
1273 } | |
1269 return; | 1274 return; |
1275 } | |
1270 | 1276 |
1271 int last_row = VirtualCallData::row_limit() - 1; | 1277 int last_row = VirtualCallData::row_limit() - 1; |
1272 assert(start_row <= last_row, "must be work left to do"); | 1278 assert(start_row <= last_row, "must be work left to do"); |
1273 // Test this row for both the receiver and for null. | 1279 // Test this row for both the receiver and for null. |
1274 // Take any of three different outcomes: | 1280 // Take any of three different outcomes: |
1292 increment_mdp_data_at(mdp, count_offset); | 1298 increment_mdp_data_at(mdp, count_offset); |
1293 jmp(done); | 1299 jmp(done); |
1294 bind(next_test); | 1300 bind(next_test); |
1295 | 1301 |
1296 if (row == start_row) { | 1302 if (row == start_row) { |
1303 Label found_null; | |
1297 // Failed the equality check on receiver[n]... Test for null. | 1304 // Failed the equality check on receiver[n]... Test for null. |
1298 testptr(reg2, reg2); | 1305 testptr(reg2, reg2); |
1299 if (start_row == last_row) { | 1306 if (start_row == last_row) { |
1300 // The only thing left to do is handle the null case. | 1307 // The only thing left to do is handle the null case. |
1301 jcc(Assembler::notZero, done); | 1308 if (is_virtual_call) { |
1309 jccb(Assembler::zero, found_null); | |
1310 // Receiver did not match any saved receiver and there is no empty row for it. | |
1311 // Increment total counter to indicate polimorphic case. | |
1312 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); | |
1313 jmp(done); | |
1314 bind(found_null); | |
1315 } else { | |
1316 jcc(Assembler::notZero, done); | |
1317 } | |
1302 break; | 1318 break; |
1303 } | 1319 } |
1304 // Since null is rare, make it be the branch-taken case. | 1320 // Since null is rare, make it be the branch-taken case. |
1305 Label found_null; | |
1306 jcc(Assembler::zero, found_null); | 1321 jcc(Assembler::zero, found_null); |
1307 | 1322 |
1308 // Put all the "Case 3" tests here. | 1323 // Put all the "Case 3" tests here. |
1309 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done); | 1324 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call); |
1310 | 1325 |
1311 // Found a null. Keep searching for a matching receiver, | 1326 // Found a null. Keep searching for a matching receiver, |
1312 // but remember that this is an empty (unused) slot. | 1327 // but remember that this is an empty (unused) slot. |
1313 bind(found_null); | 1328 bind(found_null); |
1314 } | 1329 } |
1321 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); | 1336 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); |
1322 set_mdp_data_at(mdp, recvr_offset, receiver); | 1337 set_mdp_data_at(mdp, recvr_offset, receiver); |
1323 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); | 1338 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); |
1324 movptr(reg2, (int32_t)DataLayout::counter_increment); | 1339 movptr(reg2, (int32_t)DataLayout::counter_increment); |
1325 set_mdp_data_at(mdp, count_offset, reg2); | 1340 set_mdp_data_at(mdp, count_offset, reg2); |
1326 jmp(done); | 1341 if (start_row > 0) { |
1342 jmp(done); | |
1343 } | |
1327 } | 1344 } |
1328 | 1345 |
1329 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, | 1346 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, |
1330 Register mdp, | 1347 Register mdp, Register reg2, |
1331 Register reg2) { | 1348 bool is_virtual_call) { |
1332 assert(ProfileInterpreter, "must be profiling"); | 1349 assert(ProfileInterpreter, "must be profiling"); |
1333 Label done; | 1350 Label done; |
1334 | 1351 |
1335 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done); | 1352 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call); |
1336 | 1353 |
1337 bind (done); | 1354 bind (done); |
1338 } | 1355 } |
1339 | 1356 |
1340 void InterpreterMacroAssembler::profile_ret(Register return_bci, Register mdp) { | 1357 void InterpreterMacroAssembler::profile_ret(Register return_bci, Register mdp) { |
1423 int mdp_delta = in_bytes(BitData::bit_data_size()); | 1440 int mdp_delta = in_bytes(BitData::bit_data_size()); |
1424 if (TypeProfileCasts) { | 1441 if (TypeProfileCasts) { |
1425 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); | 1442 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); |
1426 | 1443 |
1427 // Record the object type. | 1444 // Record the object type. |
1428 record_klass_in_profile(klass, mdp, reg2); | 1445 record_klass_in_profile(klass, mdp, reg2, false); |
1429 assert(reg2 == rdi, "we know how to fix this blown reg"); | 1446 assert(reg2 == rdi, "we know how to fix this blown reg"); |
1430 restore_locals(); // Restore EDI | 1447 restore_locals(); // Restore EDI |
1431 } | 1448 } |
1432 update_mdp_by_constant(mdp, mdp_delta); | 1449 update_mdp_by_constant(mdp, mdp_delta); |
1433 | 1450 |