mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
6614597: Performance variability in jvm2008 xml.validation
Fix incorrect marking of methods as not compilable. Reviewed-by: never
This commit is contained in:
parent
4e8608a124
commit
0c27c5537e
18 changed files with 213 additions and 133 deletions
|
@ -1262,17 +1262,19 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
|||
// If no method data exists, go to profile_continue.
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
// We are making a call. Increment the count.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
|
||||
Label skip_receiver_profile;
|
||||
if (receiver_can_be_null) {
|
||||
Label not_null;
|
||||
testptr(receiver, receiver);
|
||||
jcc(Assembler::zero, skip_receiver_profile);
|
||||
jccb(Assembler::notZero, not_null);
|
||||
// We are making a call. Increment the count for null receiver.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
jmp(skip_receiver_profile);
|
||||
bind(not_null);
|
||||
}
|
||||
|
||||
// Record the receiver type.
|
||||
record_klass_in_profile(receiver, mdp, reg2);
|
||||
record_klass_in_profile(receiver, mdp, reg2, true);
|
||||
bind(skip_receiver_profile);
|
||||
|
||||
// The method data pointer needs to be updated to reflect the new target.
|
||||
|
@ -1296,10 +1298,14 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
|||
// See below for example code.
|
||||
void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
||||
Register receiver, Register mdp,
|
||||
Register reg2,
|
||||
int start_row, Label& done) {
|
||||
if (TypeProfileWidth == 0)
|
||||
Register reg2, int start_row,
|
||||
Label& done, bool is_virtual_call) {
|
||||
if (TypeProfileWidth == 0) {
|
||||
if (is_virtual_call) {
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int last_row = VirtualCallData::row_limit() - 1;
|
||||
assert(start_row <= last_row, "must be work left to do");
|
||||
|
@ -1327,19 +1333,28 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
|||
bind(next_test);
|
||||
|
||||
if (test_for_null_also) {
|
||||
Label found_null;
|
||||
// Failed the equality check on receiver[n]... Test for null.
|
||||
testptr(reg2, reg2);
|
||||
if (start_row == last_row) {
|
||||
// The only thing left to do is handle the null case.
|
||||
jcc(Assembler::notZero, done);
|
||||
if (is_virtual_call) {
|
||||
jccb(Assembler::zero, found_null);
|
||||
// Receiver did not match any saved receiver and there is no empty row for it.
|
||||
// Increment total counter to indicate polimorphic case.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
jmp(done);
|
||||
bind(found_null);
|
||||
} else {
|
||||
jcc(Assembler::notZero, done);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Since null is rare, make it be the branch-taken case.
|
||||
Label found_null;
|
||||
jcc(Assembler::zero, found_null);
|
||||
|
||||
// Put all the "Case 3" tests here.
|
||||
record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);
|
||||
record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
|
||||
|
||||
// Found a null. Keep searching for a matching receiver,
|
||||
// but remember that this is an empty (unused) slot.
|
||||
|
@ -1356,7 +1371,9 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
|||
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
|
||||
movl(reg2, DataLayout::counter_increment);
|
||||
set_mdp_data_at(mdp, count_offset, reg2);
|
||||
jmp(done);
|
||||
if (start_row > 0) {
|
||||
jmp(done);
|
||||
}
|
||||
}
|
||||
|
||||
// Example state machine code for three profile rows:
|
||||
|
@ -1368,7 +1385,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
|||
// if (row[1].rec != NULL) {
|
||||
// // degenerate decision tree, rooted at row[2]
|
||||
// if (row[2].rec == rec) { row[2].incr(); goto done; }
|
||||
// if (row[2].rec != NULL) { goto done; } // overflow
|
||||
// if (row[2].rec != NULL) { count.incr(); goto done; } // overflow
|
||||
// row[2].init(rec); goto done;
|
||||
// } else {
|
||||
// // remember row[1] is empty
|
||||
|
@ -1381,14 +1398,15 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
|||
// if (row[2].rec == rec) { row[2].incr(); goto done; }
|
||||
// row[0].init(rec); goto done;
|
||||
// }
|
||||
// done:
|
||||
|
||||
void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
|
||||
Register mdp,
|
||||
Register reg2) {
|
||||
Register mdp, Register reg2,
|
||||
bool is_virtual_call) {
|
||||
assert(ProfileInterpreter, "must be profiling");
|
||||
Label done;
|
||||
|
||||
record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
|
||||
record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
|
||||
|
||||
bind (done);
|
||||
}
|
||||
|
@ -1484,7 +1502,7 @@ void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass,
|
|||
mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
|
||||
|
||||
// Record the object type.
|
||||
record_klass_in_profile(klass, mdp, reg2);
|
||||
record_klass_in_profile(klass, mdp, reg2, false);
|
||||
}
|
||||
update_mdp_by_constant(mdp, mdp_delta);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue