Skip to content

Commit

Permalink
8315762: Update subtype check profile collection on s390x following 8…
Browse files Browse the repository at this point in the history
…308869

Reviewed-by: mdoerr, lucy
  • Loading branch information
offamitkumar committed Feb 5, 2024
1 parent 80642dd commit 8796f43
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 96 deletions.
73 changes: 28 additions & 45 deletions src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -2480,23 +2480,30 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
assert_different_registers(obj, k_RInfo, klass_RInfo);

if (op->should_profile()) {
Register mdo = klass_RInfo;
metadata2reg(md->constant_encoding(), mdo);
NearLabel not_null;
__ compareU64_and_branch(obj, (intptr_t) 0, Assembler::bcondNotEqual, not_null);
// Object is null; update MDO and exit.
Register mdo = klass_RInfo;
metadata2reg(md->constant_encoding(), mdo);
Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
__ or2mem_8(data_addr, header_bits);
__ branch_optimized(Assembler::bcondAlways, *obj_is_null);
__ bind(not_null);

NearLabel update_done;
Register recv = k_RInfo;
__ load_klass(recv, obj);
type_profile_helper(mdo, md, data, recv, Rtmp1, &update_done);
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
__ add2mem_64(counter_addr, DataLayout::counter_increment, Rtmp1);
__ bind(update_done);
} else {
__ compareU64_and_branch(obj, (intptr_t) 0, Assembler::bcondEqual, *obj_is_null);
}

NearLabel profile_cast_failure, profile_cast_success;
Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
Label *success_target = op->should_profile() ? &profile_cast_success : success;
Label *failure_target = failure;
Label *success_target = success;

// Patching may screw with our temporaries,
// so let's do it before loading the class.
Expand Down Expand Up @@ -2536,28 +2543,12 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
store_parameter(klass_RInfo, 0); // sub
store_parameter(k_RInfo, 1); // super
emit_call_c(a); // Sets condition code 0 for match (2 otherwise).
CHECK_BAILOUT2(profile_cast_failure, profile_cast_success);
__ branch_optimized(Assembler::bcondNotEqual, *failure_target);
// Fall through to success case.
}
}

if (op->should_profile()) {
Register mdo = klass_RInfo, recv = k_RInfo;
assert_different_registers(obj, mdo, recv);
__ bind(profile_cast_success);
metadata2reg(md->constant_encoding(), mdo);
__ load_klass(recv, obj);
type_profile_helper(mdo, md, data, recv, Rtmp1, success);
__ branch_optimized(Assembler::bcondAlways, *success);

__ bind(profile_cast_failure);
metadata2reg(md->constant_encoding(), mdo);
__ add2mem_64(Address(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())), -(int)DataLayout::counter_increment, Rtmp1);
__ branch_optimized(Assembler::bcondAlways, *failure);
} else {
__ branch_optimized(Assembler::bcondAlways, *success);
}
__ branch_optimized(Assembler::bcondAlways, *success);
}

void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
Expand Down Expand Up @@ -2587,21 +2578,29 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
assert(data != nullptr, "need data for type check");
assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
}
NearLabel profile_cast_success, profile_cast_failure, done;
Label *success_target = op->should_profile() ? &profile_cast_success : &done;
Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
NearLabel done;
Label *success_target = &done;
Label *failure_target = stub->entry();

if (op->should_profile()) {
Register mdo = klass_RInfo;
metadata2reg(md->constant_encoding(), mdo);
NearLabel not_null;
__ compareU64_and_branch(value, (intptr_t) 0, Assembler::bcondNotEqual, not_null);
// Object is null; update MDO and exit.
Register mdo = klass_RInfo;
metadata2reg(md->constant_encoding(), mdo);
Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
__ or2mem_8(data_addr, header_bits);
__ branch_optimized(Assembler::bcondAlways, done);
__ bind(not_null);

NearLabel update_done;
Register recv = k_RInfo;
__ load_klass(recv, value);
type_profile_helper(mdo, md, data, recv, Rtmp1, &update_done);
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
__ add2mem_64(counter_addr, DataLayout::counter_increment, Rtmp1);
__ bind(update_done);
} else {
__ compareU64_and_branch(value, (intptr_t) 0, Assembler::bcondEqual, done);
}
Expand All @@ -2619,25 +2618,9 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
store_parameter(klass_RInfo, 0); // sub
store_parameter(k_RInfo, 1); // super
emit_call_c(a); // Sets condition code 0 for match (2 otherwise).
CHECK_BAILOUT3(profile_cast_success, profile_cast_failure, done);
__ branch_optimized(Assembler::bcondNotEqual, *failure_target);
// Fall through to success case.

if (op->should_profile()) {
Register mdo = klass_RInfo, recv = k_RInfo;
assert_different_registers(value, mdo, recv);
__ bind(profile_cast_success);
metadata2reg(md->constant_encoding(), mdo);
__ load_klass(recv, value);
type_profile_helper(mdo, md, data, recv, Rtmp1, &done);
__ branch_optimized(Assembler::bcondAlways, done);

__ bind(profile_cast_failure);
metadata2reg(md->constant_encoding(), mdo);
__ add2mem_64(Address(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())), -(int)DataLayout::counter_increment, Rtmp1);
__ branch_optimized(Assembler::bcondAlways, *stub->entry());
}

__ bind(done);
} else {
if (code == lir_checkcast) {
Expand Down
58 changes: 15 additions & 43 deletions src/hotspot/cpu/s390/interp_masm_s390.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -447,9 +447,6 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,

// Do the check.
check_klass_subtype(Rsub_klass, Rsuper_klass, Rtmp1, Rtmp2, ok_is_subtype);

// Profile the failure of the check.
profile_typecheck_failed(Rtmp1, Rtmp2);
}

// Pop topmost element from stack. It just disappears.
Expand Down Expand Up @@ -1425,7 +1422,7 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
}

// Record the receiver type.
record_klass_in_profile(receiver, mdp, reg2, true);
record_klass_in_profile(receiver, mdp, reg2);
bind(skip_receiver_profile);

// The method data pointer needs to be updated to reflect the new target.
Expand All @@ -1448,11 +1445,9 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
void InterpreterMacroAssembler::record_klass_in_profile_helper(
Register receiver, Register mdp,
Register reg2, int start_row,
Label& done, bool is_virtual_call) {
Label& done) {
if (TypeProfileWidth == 0) {
if (is_virtual_call) {
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
}
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
return;
}

Expand Down Expand Up @@ -1487,23 +1482,19 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
z_ltgr(reg2, reg2);
if (start_row == last_row) {
// The only thing left to do is handle the null case.
if (is_virtual_call) {
z_brz(found_null);
// Receiver did not match any saved receiver and there is no empty row for it.
// Increment total counter to indicate polymorphic case.
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
z_bru(done);
bind(found_null);
} else {
z_brnz(done);
}
z_brz(found_null);
// Receiver did not match any saved receiver and there is no empty row for it.
// Increment total counter to indicate polymorphic case.
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
z_bru(done);
bind(found_null);
break;
}
// Since null is rare, make it be the branch-taken case.
z_brz(found_null);

// Put all the "Case 3" tests here.
record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);

// Found a null. Keep searching for a matching receiver,
// but remember that this is an empty (unused) slot.
Expand Down Expand Up @@ -1550,12 +1541,11 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// done:

void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
Register mdp, Register reg2,
bool is_virtual_call) {
Register mdp, Register reg2) {
assert(ProfileInterpreter, "must be profiling");
Label done;

record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);

bind (done);
}
Expand Down Expand Up @@ -1615,24 +1605,6 @@ void InterpreterMacroAssembler::profile_null_seen(Register mdp) {
}
}

void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp, Register tmp) {
if (ProfileInterpreter && TypeProfileCasts) {
Label profile_continue;

// If no method data exists, go to profile_continue.
test_method_data_pointer(mdp, profile_continue);

int count_offset = in_bytes(CounterData::count_offset());
// Back up the address, since we have already bumped the mdp.
count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());

// *Decrement* the counter. We expect to see zero or small negatives.
increment_mdp_data_at(mdp, count_offset, tmp, true);

bind (profile_continue);
}
}

void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) {
if (ProfileInterpreter) {
Label profile_continue;
Expand All @@ -1646,7 +1618,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, false);
record_klass_in_profile(klass, mdp, reg2);
}
update_mdp_by_constant(mdp, mdp_delta);

Expand Down
9 changes: 4 additions & 5 deletions src/hotspot/cpu/s390/interp_masm_s390.hpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023 SAP SE. All rights reserved.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -281,10 +281,10 @@ class InterpreterMacroAssembler: public MacroAssembler {
Label& not_equal_continue);

void record_klass_in_profile(Register receiver, Register mdp,
Register reg2, bool is_virtual_call);
Register reg2);
void record_klass_in_profile_helper(Register receiver, Register mdp,
Register reg2, int start_row,
Label& done, bool is_virtual_call);
Label& done);

void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
void update_mdp_by_offset(Register mdp_in, Register dataidx, int offset_of_disp);
Expand All @@ -301,7 +301,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
void profile_ret(Register return_bci, Register mdp);
void profile_null_seen(Register mdp);
void profile_typecheck(Register mdp, Register klass, Register scratch);
void profile_typecheck_failed(Register mdp, Register tmp);
void profile_switch_default(Register mdp);
void profile_switch_case(Register index_in_scratch, Register mdp,
Register scratch1, Register scratch2);
Expand Down
5 changes: 2 additions & 3 deletions src/hotspot/cpu/s390/vm_version_s390.hpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022 SAP SE. All rights reserved.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -567,7 +567,6 @@ class VM_Version: public Abstract_VM_Version {
static unsigned long z_SIGSEGV();

static void initialize_cpu_information(void);
static bool profile_all_receivers_at_type_check() { return false; }
};

#endif // CPU_S390_VM_VERSION_S390_HPP

1 comment on commit 8796f43

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.