Skip to content
Permalink
Browse files
8263125: During deoptimization vectors should reassign scalarized pay…
…load after all objects are reallocated.

Reviewed-by: vlivanov, rrich
  • Loading branch information
Vladimir Kozlov committed Mar 12, 2021
1 parent 65421fa commit a6e056fd5192671a1eb82f67b95c53de15a74f1e
@@ -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 @@
* @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
*/

1 comment on commit a6e056f

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on a6e056f Mar 12, 2021

Please sign in to comment.