@@ -1267,133 +1267,14 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
12671267 test_method_data_pointer (mdp, profile_continue);
12681268
12691269 // Record the receiver type.
1270- record_klass_in_profile (receiver, mdp, reg2);
1270+ profile_receiver_type (receiver, mdp, 0 , reg2);
12711271
12721272 // The method data pointer needs to be updated to reflect the new target.
12731273 update_mdp_by_constant (mdp, in_bytes (VirtualCallData::virtual_call_data_size ()));
12741274 bind (profile_continue);
12751275 }
12761276}
12771277
1278- // This routine creates a state machine for updating the multi-row
1279- // type profile at a virtual call site (or other type-sensitive bytecode).
1280- // The machine visits each row (of receiver/count) until the receiver type
1281- // is found, or until it runs out of rows. At the same time, it remembers
1282- // the location of the first empty row. (An empty row records null for its
1283- // receiver, and can be allocated for a newly-observed receiver type.)
1284- // Because there are two degrees of freedom in the state, a simple linear
1285- // search will not work; it must be a decision tree. Hence this helper
1286- // function is recursive, to generate the required tree structured code.
1287- // It's the interpreter, so we are trading off code space for speed.
1288- // See below for example code.
1289- void InterpreterMacroAssembler::record_klass_in_profile_helper (
1290- Register receiver, Register mdp,
1291- Register reg2, int start_row,
1292- Label& done) {
1293- if (TypeProfileWidth == 0 ) {
1294- increment_mdp_data_at (mdp, in_bytes (CounterData::count_offset ()));
1295- return ;
1296- }
1297-
1298- int last_row = VirtualCallData::row_limit () - 1 ;
1299- assert (start_row <= last_row, " must be work left to do" );
1300- // Test this row for both the receiver and for null.
1301- // Take any of three different outcomes:
1302- // 1. found receiver => increment count and goto done
1303- // 2. found null => keep looking for case 1, maybe allocate this cell
1304- // 3. found something else => keep looking for cases 1 and 2
1305- // Case 3 is handled by a recursive call.
1306- for (int row = start_row; row <= last_row; row++) {
1307- NearLabel next_test;
1308- bool test_for_null_also = (row == start_row);
1309-
1310- // See if the receiver is receiver[n].
1311- int recvr_offset = in_bytes (VirtualCallData::receiver_offset (row));
1312- test_mdp_data_at (mdp, recvr_offset, receiver,
1313- (test_for_null_also ? reg2 : noreg),
1314- next_test);
1315- // (Reg2 now contains the receiver from the CallData.)
1316-
1317- // The receiver is receiver[n]. Increment count[n].
1318- int count_offset = in_bytes (VirtualCallData::receiver_count_offset (row));
1319- increment_mdp_data_at (mdp, count_offset);
1320- z_bru (done);
1321- bind (next_test);
1322-
1323- if (test_for_null_also) {
1324- Label found_null;
1325- // Failed the equality check on receiver[n]... Test for null.
1326- z_ltgr (reg2, reg2);
1327- if (start_row == last_row) {
1328- // The only thing left to do is handle the null case.
1329- z_brz (found_null);
1330- // Receiver did not match any saved receiver and there is no empty row for it.
1331- // Increment total counter to indicate polymorphic case.
1332- increment_mdp_data_at (mdp, in_bytes (CounterData::count_offset ()));
1333- z_bru (done);
1334- bind (found_null);
1335- break ;
1336- }
1337- // Since null is rare, make it be the branch-taken case.
1338- z_brz (found_null);
1339-
1340- // Put all the "Case 3" tests here.
1341- record_klass_in_profile_helper (receiver, mdp, reg2, start_row + 1 , done);
1342-
1343- // Found a null. Keep searching for a matching receiver,
1344- // but remember that this is an empty (unused) slot.
1345- bind (found_null);
1346- }
1347- }
1348-
1349- // In the fall-through case, we found no matching receiver, but we
1350- // observed the receiver[start_row] is null.
1351-
1352- // Fill in the receiver field and increment the count.
1353- int recvr_offset = in_bytes (VirtualCallData::receiver_offset (start_row));
1354- set_mdp_data_at (mdp, recvr_offset, receiver);
1355- int count_offset = in_bytes (VirtualCallData::receiver_count_offset (start_row));
1356- load_const_optimized (reg2, DataLayout::counter_increment);
1357- set_mdp_data_at (mdp, count_offset, reg2);
1358- if (start_row > 0 ) {
1359- z_bru (done);
1360- }
1361- }
1362-
1363- // Example state machine code for three profile rows:
1364- // // main copy of decision tree, rooted at row[1]
1365- // if (row[0].rec == rec) { row[0].incr(); goto done; }
1366- // if (row[0].rec != nullptr) {
1367- // // inner copy of decision tree, rooted at row[1]
1368- // if (row[1].rec == rec) { row[1].incr(); goto done; }
1369- // if (row[1].rec != nullptr) {
1370- // // degenerate decision tree, rooted at row[2]
1371- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1372- // if (row[2].rec != nullptr) { count.incr(); goto done; } // overflow
1373- // row[2].init(rec); goto done;
1374- // } else {
1375- // // remember row[1] is empty
1376- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1377- // row[1].init(rec); goto done;
1378- // }
1379- // } else {
1380- // // remember row[0] is empty
1381- // if (row[1].rec == rec) { row[1].incr(); goto done; }
1382- // if (row[2].rec == rec) { row[2].incr(); goto done; }
1383- // row[0].init(rec); goto done;
1384- // }
1385- // done:
1386-
1387- void InterpreterMacroAssembler::record_klass_in_profile (Register receiver,
1388- Register mdp, Register reg2) {
1389- assert (ProfileInterpreter, " must be profiling" );
1390- Label done;
1391-
1392- record_klass_in_profile_helper (receiver, mdp, reg2, 0 , done);
1393-
1394- bind (done);
1395- }
1396-
13971278void InterpreterMacroAssembler::profile_ret (Register return_bci, Register mdp) {
13981279 if (ProfileInterpreter) {
13991280 NearLabel profile_continue;
@@ -1462,7 +1343,7 @@ void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass,
14621343 mdp_delta = in_bytes (VirtualCallData::virtual_call_data_size ());
14631344
14641345 // Record the object type.
1465- record_klass_in_profile (klass, mdp, reg2);
1346+ profile_receiver_type (klass, mdp, 0 , reg2);
14661347 }
14671348 update_mdp_by_constant (mdp, mdp_delta);
14681349
0 commit comments