@@ -580,17 +580,16 @@ void InterpreterMacroAssembler::load_resolved_klass_at_index(Register klass,
580580// Rsub_klass: subklass
581581//
582582// Kills:
583- // rcx, rdi
583+ // rcx
584584void InterpreterMacroAssembler::gen_subtype_check (Register Rsub_klass,
585585 Label& ok_is_subtype) {
586586 assert (Rsub_klass != rax, " rax holds superklass" );
587587 assert (Rsub_klass != r14, " r14 holds locals" );
588588 assert (Rsub_klass != r13, " r13 holds bcp" );
589589 assert (Rsub_klass != rcx, " rcx holds 2ndary super array length" );
590- assert (Rsub_klass != rdi, " rdi holds 2ndary super array scan ptr" );
591590
592591 // Profile the not-null value's klass.
593- profile_typecheck (rcx, Rsub_klass, rdi ); // blows rcx, reloads rdi
592+ profile_typecheck (rcx, Rsub_klass); // blows rcx
594593
595594 // Do the check.
596595 check_klass_subtype (Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx
@@ -1394,7 +1393,6 @@ void InterpreterMacroAssembler::profile_final_call(Register mdp) {
13941393
13951394void InterpreterMacroAssembler::profile_virtual_call (Register receiver,
13961395 Register mdp,
1397- Register reg2,
13981396 bool receiver_can_be_null) {
13991397 if (ProfileInterpreter) {
14001398 Label profile_continue;
@@ -1414,7 +1412,7 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
14141412 }
14151413
14161414 // Record the receiver type.
1417- record_klass_in_profile (receiver, mdp, reg2, true );
1415+ profile_receiver_type (receiver, mdp, 0 );
14181416 bind (skip_receiver_profile);
14191417
14201418 // The method data pointer needs to be updated to reflect the new target.
@@ -1423,135 +1421,6 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
14231421 }
14241422}
14251423
1426- // This routine creates a state machine for updating the multi-row
1427- // type profile at a virtual call site (or other type-sensitive bytecode).
1428- // The machine visits each row (of receiver/count) until the receiver type
1429- // is found, or until it runs out of rows. At the same time, it remembers
1430- // the location of the first empty row. (An empty row records null for its
1431- // receiver, and can be allocated for a newly-observed receiver type.)
1432- // Because there are two degrees of freedom in the state, a simple linear
1433- // search will not work; it must be a decision tree. Hence this helper
1434- // function is recursive, to generate the required tree structured code.
1435- // It's the interpreter, so we are trading off code space for speed.
1436- // See below for example code.
1437- void InterpreterMacroAssembler::record_klass_in_profile_helper (
1438- Register receiver, Register mdp,
1439- Register reg2, int start_row,
1440- Label& done, bool is_virtual_call) {
1441- if (TypeProfileWidth == 0 ) {
1442- increment_mdp_data_at (mdp, in_bytes (CounterData::count_offset ()));
1443- } else {
1444- record_item_in_profile_helper (receiver, mdp, reg2, 0 , done, TypeProfileWidth,
1445- &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset);
1446- }
1447- }
1448-
1449- void InterpreterMacroAssembler::record_item_in_profile_helper (Register item, Register mdp, Register reg2, int start_row,
1450- Label& done, int total_rows,
1451- OffsetFunction item_offset_fn,
1452- OffsetFunction item_count_offset_fn) {
1453- int last_row = total_rows - 1 ;
1454- assert (start_row <= last_row, " must be work left to do" );
1455- // Test this row for both the item and for null.
1456- // Take any of three different outcomes:
1457- // 1. found item => increment count and goto done
1458- // 2. found null => keep looking for case 1, maybe allocate this cell
1459- // 3. found something else => keep looking for cases 1 and 2
1460- // Case 3 is handled by a recursive call.
1461- for (int row = start_row; row <= last_row; row++) {
1462- Label next_test;
1463- bool test_for_null_also = (row == start_row);
1464-
1465- // See if the item is item[n].
1466- int item_offset = in_bytes (item_offset_fn (row));
1467- test_mdp_data_at (mdp, item_offset, item,
1468- (test_for_null_also ? reg2 : noreg),
1469- next_test);
1470- // (Reg2 now contains the item from the CallData.)
1471-
1472- // The item is item[n]. Increment count[n].
1473- int count_offset = in_bytes (item_count_offset_fn (row));
1474- increment_mdp_data_at (mdp, count_offset);
1475- jmp (done);
1476- bind (next_test);
1477-
1478- if (test_for_null_also) {
1479- // Failed the equality check on item[n]... Test for null.
1480- testptr (reg2, reg2);
1481- if (start_row == last_row) {
1482- // The only thing left to do is handle the null case.
1483- Label found_null;
1484- jccb (Assembler::zero, found_null);
1485- // Item did not match any saved item and there is no empty row for it.
1486- // Increment total counter to indicate polymorphic case.
1487- increment_mdp_data_at (mdp, in_bytes (CounterData::count_offset ()));
1488- jmp (done);
1489- bind (found_null);
1490- break ;
1491- }
1492- Label found_null;
1493- // Since null is rare, make it be the branch-taken case.
1494- jcc (Assembler::zero, found_null);
1495-
1496- // Put all the "Case 3" tests here.
1497- record_item_in_profile_helper (item, mdp, reg2, start_row + 1 , done, total_rows,
1498- item_offset_fn, item_count_offset_fn);
1499-
1500- // Found a null. Keep searching for a matching item,
1501- // but remember that this is an empty (unused) slot.
1502- bind (found_null);
1503- }
1504- }
1505-
1506- // In the fall-through case, we found no matching item, but we
1507- // observed the item[start_row] is null.
1508-
1509- // Fill in the item field and increment the count.
1510- int item_offset = in_bytes (item_offset_fn (start_row));
1511- set_mdp_data_at (mdp, item_offset, item);
1512- int count_offset = in_bytes (item_count_offset_fn (start_row));
1513- movl (reg2, DataLayout::counter_increment);
1514- set_mdp_data_at (mdp, count_offset, reg2);
1515- if (start_row > 0 ) {
1516- jmp (done);
1517- }
1518- }
1519-
1520- // Example state machine code for three profile rows:
1521- // // main copy of decision tree, rooted at row[1]
1522- // if (row[0].rec == rec) { row[0].incr(); goto done; }
1523- // if (row[0].rec != nullptr) {
1524- // // inner copy of decision tree, rooted at row[1]
1525- // if (row[1].rec == rec) { row[1].incr(); goto done; }
1526- // if (row[1].rec != nullptr) {
1527- // // degenerate decision tree, rooted at row[2]
1528- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1529- // if (row[2].rec != nullptr) { count.incr(); goto done; } // overflow
1530- // row[2].init(rec); goto done;
1531- // } else {
1532- // // remember row[1] is empty
1533- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1534- // row[1].init(rec); goto done;
1535- // }
1536- // } else {
1537- // // remember row[0] is empty
1538- // if (row[1].rec == rec) { row[1].incr(); goto done; }
1539- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1540- // row[0].init(rec); goto done;
1541- // }
1542- // done:
1543-
1544- void InterpreterMacroAssembler::record_klass_in_profile (Register receiver,
1545- Register mdp, Register reg2,
1546- bool is_virtual_call) {
1547- assert (ProfileInterpreter, " must be profiling" );
1548- Label done;
1549-
1550- record_klass_in_profile_helper (receiver, mdp, reg2, 0 , done, is_virtual_call);
1551-
1552- bind (done);
1553- }
1554-
15551424void InterpreterMacroAssembler::profile_ret (Register return_bci,
15561425 Register mdp) {
15571426 if (ProfileInterpreter) {
@@ -1611,7 +1480,7 @@ void InterpreterMacroAssembler::profile_null_seen(Register mdp) {
16111480}
16121481
16131482
1614- void InterpreterMacroAssembler::profile_typecheck (Register mdp, Register klass, Register reg2 ) {
1483+ void InterpreterMacroAssembler::profile_typecheck (Register mdp, Register klass) {
16151484 if (ProfileInterpreter) {
16161485 Label profile_continue;
16171486
@@ -1624,7 +1493,7 @@ void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass,
16241493 mdp_delta = in_bytes (VirtualCallData::virtual_call_data_size ());
16251494
16261495 // Record the object type.
1627- record_klass_in_profile (klass, mdp, reg2, false );
1496+ profile_receiver_type (klass, mdp, 0 );
16281497 }
16291498 update_mdp_by_constant (mdp, mdp_delta);
16301499
0 commit comments