comparison src/cpu/x86/vm/interp_masm_x86_64.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
1260 Label profile_continue; 1260 Label profile_continue;
1261 1261
1262 // If no method data exists, go to profile_continue. 1262 // If no method data exists, go to profile_continue.
1263 test_method_data_pointer(mdp, profile_continue); 1263 test_method_data_pointer(mdp, profile_continue);
1264 1264
1265 // We are making a call. Increment the count.
1266 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1267
1268 Label skip_receiver_profile; 1265 Label skip_receiver_profile;
1269 if (receiver_can_be_null) { 1266 if (receiver_can_be_null) {
1267 Label not_null;
1270 testptr(receiver, receiver); 1268 testptr(receiver, receiver);
1271 jcc(Assembler::zero, skip_receiver_profile); 1269 jccb(Assembler::notZero, not_null);
1270 // We are making a call. Increment the count for null receiver.
1271 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1272 jmp(skip_receiver_profile);
1273 bind(not_null);
1272 } 1274 }
1273 1275
1274 // Record the receiver type. 1276 // Record the receiver type.
1275 record_klass_in_profile(receiver, mdp, reg2); 1277 record_klass_in_profile(receiver, mdp, reg2, true);
1276 bind(skip_receiver_profile); 1278 bind(skip_receiver_profile);
1277 1279
1278 // The method data pointer needs to be updated to reflect the new target. 1280 // The method data pointer needs to be updated to reflect the new target.
1279 update_mdp_by_constant(mdp, 1281 update_mdp_by_constant(mdp,
1280 in_bytes(VirtualCallData:: 1282 in_bytes(VirtualCallData::
1294 // function is recursive, to generate the required tree structured code. 1296 // function is recursive, to generate the required tree structured code.
1295 // It's the interpreter, so we are trading off code space for speed. 1297 // It's the interpreter, so we are trading off code space for speed.
1296 // See below for example code. 1298 // See below for example code.
1297 void InterpreterMacroAssembler::record_klass_in_profile_helper( 1299 void InterpreterMacroAssembler::record_klass_in_profile_helper(
1298 Register receiver, Register mdp, 1300 Register receiver, Register mdp,
1299 Register reg2, 1301 Register reg2, int start_row,
1300 int start_row, Label& done) { 1302 Label& done, bool is_virtual_call) {
1301 if (TypeProfileWidth == 0) 1303 if (TypeProfileWidth == 0) {
1304 if (is_virtual_call) {
1305 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1306 }
1302 return; 1307 return;
1308 }
1303 1309
1304 int last_row = VirtualCallData::row_limit() - 1; 1310 int last_row = VirtualCallData::row_limit() - 1;
1305 assert(start_row <= last_row, "must be work left to do"); 1311 assert(start_row <= last_row, "must be work left to do");
1306 // Test this row for both the receiver and for null. 1312 // Test this row for both the receiver and for null.
1307 // Take any of three different outcomes: 1313 // Take any of three different outcomes:
1325 increment_mdp_data_at(mdp, count_offset); 1331 increment_mdp_data_at(mdp, count_offset);
1326 jmp(done); 1332 jmp(done);
1327 bind(next_test); 1333 bind(next_test);
1328 1334
1329 if (test_for_null_also) { 1335 if (test_for_null_also) {
1336 Label found_null;
1330 // Failed the equality check on receiver[n]... Test for null. 1337 // Failed the equality check on receiver[n]... Test for null.
1331 testptr(reg2, reg2); 1338 testptr(reg2, reg2);
1332 if (start_row == last_row) { 1339 if (start_row == last_row) {
1333 // The only thing left to do is handle the null case. 1340 // The only thing left to do is handle the null case.
1334 jcc(Assembler::notZero, done); 1341 if (is_virtual_call) {
1342 jccb(Assembler::zero, found_null);
1343 // Receiver did not match any saved receiver and there is no empty row for it.
1344 // Increment total counter to indicate polimorphic case.
1345 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1346 jmp(done);
1347 bind(found_null);
1348 } else {
1349 jcc(Assembler::notZero, done);
1350 }
1335 break; 1351 break;
1336 } 1352 }
1337 // Since null is rare, make it be the branch-taken case. 1353 // Since null is rare, make it be the branch-taken case.
1338 Label found_null;
1339 jcc(Assembler::zero, found_null); 1354 jcc(Assembler::zero, found_null);
1340 1355
1341 // Put all the "Case 3" tests here. 1356 // Put all the "Case 3" tests here.
1342 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done); 1357 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
1343 1358
1344 // Found a null. Keep searching for a matching receiver, 1359 // Found a null. Keep searching for a matching receiver,
1345 // but remember that this is an empty (unused) slot. 1360 // but remember that this is an empty (unused) slot.
1346 bind(found_null); 1361 bind(found_null);
1347 } 1362 }
1354 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); 1369 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
1355 set_mdp_data_at(mdp, recvr_offset, receiver); 1370 set_mdp_data_at(mdp, recvr_offset, receiver);
1356 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); 1371 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
1357 movl(reg2, DataLayout::counter_increment); 1372 movl(reg2, DataLayout::counter_increment);
1358 set_mdp_data_at(mdp, count_offset, reg2); 1373 set_mdp_data_at(mdp, count_offset, reg2);
1359 jmp(done); 1374 if (start_row > 0) {
1375 jmp(done);
1376 }
1360 } 1377 }
1361 1378
1362 // Example state machine code for three profile rows: 1379 // Example state machine code for three profile rows:
1363 // // main copy of decision tree, rooted at row[1] 1380 // // main copy of decision tree, rooted at row[1]
1364 // if (row[0].rec == rec) { row[0].incr(); goto done; } 1381 // if (row[0].rec == rec) { row[0].incr(); goto done; }
1366 // // inner copy of decision tree, rooted at row[1] 1383 // // inner copy of decision tree, rooted at row[1]
1367 // if (row[1].rec == rec) { row[1].incr(); goto done; } 1384 // if (row[1].rec == rec) { row[1].incr(); goto done; }
1368 // if (row[1].rec != NULL) { 1385 // if (row[1].rec != NULL) {
1369 // // degenerate decision tree, rooted at row[2] 1386 // // degenerate decision tree, rooted at row[2]
1370 // if (row[2].rec == rec) { row[2].incr(); goto done; } 1387 // if (row[2].rec == rec) { row[2].incr(); goto done; }
1371 // if (row[2].rec != NULL) { goto done; } // overflow 1388 // if (row[2].rec != NULL) { count.incr(); goto done; } // overflow
1372 // row[2].init(rec); goto done; 1389 // row[2].init(rec); goto done;
1373 // } else { 1390 // } else {
1374 // // remember row[1] is empty 1391 // // remember row[1] is empty
1375 // if (row[2].rec == rec) { row[2].incr(); goto done; } 1392 // if (row[2].rec == rec) { row[2].incr(); goto done; }
1376 // row[1].init(rec); goto done; 1393 // row[1].init(rec); goto done;
1379 // // remember row[0] is empty 1396 // // remember row[0] is empty
1380 // if (row[1].rec == rec) { row[1].incr(); goto done; } 1397 // if (row[1].rec == rec) { row[1].incr(); goto done; }
1381 // if (row[2].rec == rec) { row[2].incr(); goto done; } 1398 // if (row[2].rec == rec) { row[2].incr(); goto done; }
1382 // row[0].init(rec); goto done; 1399 // row[0].init(rec); goto done;
1383 // } 1400 // }
1401 // done:
1384 1402
1385 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, 1403 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
1386 Register mdp, 1404 Register mdp, Register reg2,
1387 Register reg2) { 1405 bool is_virtual_call) {
1388 assert(ProfileInterpreter, "must be profiling"); 1406 assert(ProfileInterpreter, "must be profiling");
1389 Label done; 1407 Label done;
1390 1408
1391 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done); 1409 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
1392 1410
1393 bind (done); 1411 bind (done);
1394 } 1412 }
1395 1413
1396 void InterpreterMacroAssembler::profile_ret(Register return_bci, 1414 void InterpreterMacroAssembler::profile_ret(Register return_bci,
1482 int mdp_delta = in_bytes(BitData::bit_data_size()); 1500 int mdp_delta = in_bytes(BitData::bit_data_size());
1483 if (TypeProfileCasts) { 1501 if (TypeProfileCasts) {
1484 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); 1502 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
1485 1503
1486 // Record the object type. 1504 // Record the object type.
1487 record_klass_in_profile(klass, mdp, reg2); 1505 record_klass_in_profile(klass, mdp, reg2, false);
1488 } 1506 }
1489 update_mdp_by_constant(mdp, mdp_delta); 1507 update_mdp_by_constant(mdp, mdp_delta);
1490 1508
1491 bind(profile_continue); 1509 bind(profile_continue);
1492 } 1510 }