< prev index next > src/hotspot/share/compiler/methodLiveness.cpp
Print this page
case Bytecodes::_multianewarray:
case Bytecodes::_lookupswitch:
// These bytecodes have no effect on the method's locals.
break;
! case Bytecodes::_return:
! if (instruction->method()->intrinsic_id() == vmIntrinsics::_Object_init) {
! // return from Object.init implicitly registers a finalizer
! // for the receiver if needed, so keep it alive.
load_one(0);
}
break;
!
-
case Bytecodes::_lload:
case Bytecodes::_dload:
load_two(instruction->get_index());
break;
case Bytecodes::_multianewarray:
case Bytecodes::_lookupswitch:
// These bytecodes have no effect on the method's locals.
break;
! case Bytecodes::_return: {
! ciMethod* method = instruction->method();
! ciInstanceKlass* holder = method->holder();
! const bool abstract_klass = holder->is_abstract();
+ const bool concrete_value_klass = !abstract_klass && holder->is_inlinetype();
+ if (method->intrinsic_id() == vmIntrinsics::_Object_init ||
+ (method->is_object_constructor() && (concrete_value_klass || abstract_klass))) {
+ // Returning from Object.<init> implicitly registers a finalizer for the receiver if needed, to keep it alive.
+ // Value class constructors update the scalarized receiver. We need to keep it live so that we can find it after
+ // (chained) constructor calls and propagate updates to the caller. If the holder of the constructor is abstract,
+ // we do not know if the constructor was called on a value class or not. We therefore keep the receiver of all
+ // abstract constructors live.
load_one(0);
}
break;
! }
case Bytecodes::_lload:
case Bytecodes::_dload:
load_two(instruction->get_index());
break;
< prev index next >