8263125: During deoptimization vectors should reassign scalarized payload after all objects are reallocated.
Reviewed-by: vlivanov, rrich
This commit is contained in:
parent
65421faec3
commit
a6e056fd51
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. 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
|
||||
@ -50,6 +50,7 @@ void Location::print_on(outputStream* st) const {
|
||||
case float_in_dbl: st->print(",float"); break;
|
||||
case dbl: st->print(",double"); break;
|
||||
case addr: st->print(",address"); break;
|
||||
case vector: st->print(",vector"); break;
|
||||
default: st->print("Wrong location type %d", type());
|
||||
}
|
||||
}
|
||||
|
@ -153,16 +153,27 @@ Handle VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, frame* f
|
||||
}
|
||||
|
||||
Handle VectorSupport::allocate_vector_payload(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ScopeValue* payload, TRAPS) {
|
||||
if (payload->is_location() &&
|
||||
payload->as_LocationValue()->location().type() == Location::vector) {
|
||||
// Vector value in an aligned adjacent tuple (1, 2, 4, 8, or 16 slots).
|
||||
if (payload->is_location()) {
|
||||
Location location = payload->as_LocationValue()->location();
|
||||
return allocate_vector_payload_helper(ik, fr, reg_map, location, THREAD); // safepoint
|
||||
} else {
|
||||
// Scalar-replaced boxed vector representation.
|
||||
StackValue* value = StackValue::create_stack_value(fr, reg_map, payload);
|
||||
return value->get_obj();
|
||||
if (location.type() == Location::vector) {
|
||||
// Vector value in an aligned adjacent tuple (1, 2, 4, 8, or 16 slots).
|
||||
return allocate_vector_payload_helper(ik, fr, reg_map, location, THREAD); // safepoint
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// Other payload values are: 'oop' type location and Scalar-replaced boxed vector representation.
|
||||
// They will be processed in Deoptimization::reassign_fields() after all objects are reallocated.
|
||||
else {
|
||||
Location::Type loc_type = location.type();
|
||||
assert(loc_type == Location::oop || loc_type == Location::narrowoop,
|
||||
"expected 'oop'(%d) or 'narrowoop'(%d) types location but got: %d", Location::oop, Location::narrowoop, loc_type);
|
||||
}
|
||||
} else if (!payload->is_object()) {
|
||||
stringStream ss;
|
||||
payload->print_on(&ss);
|
||||
assert(payload->is_object(), "expected 'object' value for scalar-replaced boxed vector but got: %s", ss.as_string());
|
||||
#endif
|
||||
}
|
||||
return Handle(THREAD, (oop)nullptr);
|
||||
}
|
||||
|
||||
instanceOop VectorSupport::allocate_vector(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ObjectValue* ov, TRAPS) {
|
||||
|
@ -178,7 +178,7 @@ JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(
|
||||
JRT_END
|
||||
|
||||
#if COMPILER2_OR_JVMCI
|
||||
static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMethod* compiled_method,
|
||||
static bool rematerialize_objects(JavaThread* thread, int exec_mode, CompiledMethod* compiled_method,
|
||||
frame& deoptee, RegisterMap& map, GrowableArray<compiledVFrame*>* chunk,
|
||||
bool& deoptimized_objects) {
|
||||
bool realloc_failures = false;
|
||||
@ -242,8 +242,8 @@ static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMet
|
||||
return realloc_failures;
|
||||
}
|
||||
|
||||
static void eliminate_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures,
|
||||
frame& deoptee, int exec_mode, bool& deoptimized_objects) {
|
||||
static void restore_eliminated_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures,
|
||||
frame& deoptee, int exec_mode, bool& deoptimized_objects) {
|
||||
JavaThread* deoptee_thread = chunk->at(0)->thread();
|
||||
assert(!EscapeBarrier::objs_are_deoptimized(deoptee_thread, deoptee.id()), "must relock just once");
|
||||
assert(thread == Thread::current(), "should be");
|
||||
@ -303,8 +303,9 @@ bool Deoptimization::deoptimize_objects_internal(JavaThread* thread, GrowableArr
|
||||
bool const jvmci_enabled = JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false);
|
||||
|
||||
// Reallocate the non-escaping objects and restore their fields.
|
||||
if (jvmci_enabled COMPILER2_PRESENT(|| (DoEscapeAnalysis && EliminateAllocations))) {
|
||||
realloc_failures = eliminate_allocations(thread, Unpack_none, cm, deoptee, map, chunk, deoptimized_objects);
|
||||
if (jvmci_enabled COMPILER2_PRESENT(|| (DoEscapeAnalysis && EliminateAllocations)
|
||||
|| EliminateAutoBox || EnableVectorAggressiveReboxing)) {
|
||||
realloc_failures = rematerialize_objects(thread, Unpack_none, cm, deoptee, map, chunk, deoptimized_objects);
|
||||
}
|
||||
|
||||
// Revoke biases of objects with eliminated locks in the given frame.
|
||||
@ -315,7 +316,7 @@ bool Deoptimization::deoptimize_objects_internal(JavaThread* thread, GrowableArr
|
||||
|
||||
// Now relock objects if synchronization on them was eliminated.
|
||||
if (jvmci_enabled COMPILER2_PRESENT(|| ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateLocks))) {
|
||||
eliminate_locks(thread, chunk, realloc_failures, deoptee, Unpack_none, deoptimized_objects);
|
||||
restore_eliminated_locks(thread, chunk, realloc_failures, deoptee, Unpack_none, deoptimized_objects);
|
||||
}
|
||||
return deoptimized_objects;
|
||||
}
|
||||
@ -368,17 +369,14 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
bool realloc_failures = false;
|
||||
|
||||
#if COMPILER2_OR_JVMCI
|
||||
#if INCLUDE_JVMCI
|
||||
bool jvmci_enabled = true;
|
||||
#else
|
||||
bool jvmci_enabled = false;
|
||||
#endif
|
||||
bool const jvmci_enabled = JVMCI_ONLY(EnableJVMCI) NOT_JVMCI(false);
|
||||
|
||||
// Reallocate the non-escaping objects and restore their fields. Then
|
||||
// relock objects if synchronization on them was eliminated.
|
||||
if (jvmci_enabled COMPILER2_PRESENT( || (DoEscapeAnalysis && EliminateAllocations) )) {
|
||||
if (jvmci_enabled COMPILER2_PRESENT( || (DoEscapeAnalysis && EliminateAllocations)
|
||||
|| EliminateAutoBox || EnableVectorAggressiveReboxing )) {
|
||||
bool unused;
|
||||
realloc_failures = eliminate_allocations(thread, exec_mode, cm, deoptee, map, chunk, unused);
|
||||
realloc_failures = rematerialize_objects(thread, exec_mode, cm, deoptee, map, chunk, unused);
|
||||
}
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
|
||||
@ -396,7 +394,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
if ((jvmci_enabled COMPILER2_PRESENT( || ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateLocks) ))
|
||||
&& !EscapeBarrier::objs_are_deoptimized(thread, deoptee.id())) {
|
||||
bool unused;
|
||||
eliminate_locks(thread, chunk, realloc_failures, deoptee, exec_mode, unused);
|
||||
restore_eliminated_locks(thread, chunk, realloc_failures, deoptee, exec_mode, unused);
|
||||
}
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
|
||||
@ -1406,7 +1404,21 @@ void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableAr
|
||||
#endif // INCLUDE_JVMCI || INCLUDE_AOT
|
||||
#ifdef COMPILER2
|
||||
if (EnableVectorSupport && VectorSupport::is_vector(k)) {
|
||||
continue; // skip field reassignment for vectors
|
||||
assert(sv->field_size() == 1, "%s not a vector", k->name()->as_C_string());
|
||||
ScopeValue* payload = sv->field_at(0);
|
||||
if (payload->is_location() &&
|
||||
payload->as_LocationValue()->location().type() == Location::vector) {
|
||||
if (PrintDeoptimizationDetails) {
|
||||
tty->print_cr("skip field reassignment for this vector - it should be assigned already");
|
||||
if (Verbose) {
|
||||
Handle obj = sv->value();
|
||||
k->oop_print_on(obj(), tty);
|
||||
}
|
||||
}
|
||||
continue; // Such vector's value was already restored in VectorSupport::allocate_vector().
|
||||
}
|
||||
// Else fall-through to do assignment for scalar-replaced boxed vector representation
|
||||
// which could be restored after vector object allocation.
|
||||
}
|
||||
#endif
|
||||
if (k->is_instance_klass()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. 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
|
||||
@ -141,6 +141,7 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
|
||||
return new StackValue(h);
|
||||
}
|
||||
case Location::addr: {
|
||||
loc.print_on(tty);
|
||||
ShouldNotReachHere(); // both C1 and C2 now inline jsrs
|
||||
}
|
||||
case Location::normal: {
|
||||
@ -154,9 +155,11 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
|
||||
return new StackValue();
|
||||
}
|
||||
case Location::vector: {
|
||||
ShouldNotReachHere(); // should be handled by Deoptimization::realloc_objects()
|
||||
loc.print_on(tty);
|
||||
ShouldNotReachHere(); // should be handled by VectorSupport::allocate_vector()
|
||||
}
|
||||
default:
|
||||
loc.print_on(tty);
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. 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
|
||||
@ -34,7 +34,7 @@ import java.util.function.IntFunction;
|
||||
* @requires (os.arch != "ppc64") & (os.arch != "ppc64le")
|
||||
* @modules jdk.incubator.vector
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @run testng/othervm -XX:-TieredCompilation --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
|
||||
* @run testng/othervm/timeout=300 -XX:-TieredCompilation --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
|
||||
* Vector64ConversionTests
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user