--- old/src/hotspot/share/ci/ciTypeFlow.cpp 2019-03-11 14:25:31.258355638 +0100 +++ new/src/hotspot/share/ci/ciTypeFlow.cpp 2019-03-11 14:25:31.038355641 +0100 @@ -31,6 +31,7 @@ #include "ci/ciStreams.hpp" #include "ci/ciTypeArrayKlass.hpp" #include "ci/ciTypeFlow.hpp" +#include "ci/ciValueKlass.hpp" #include "compiler/compileLog.hpp" #include "interpreter/bytecode.hpp" #include "interpreter/bytecodes.hpp" @@ -271,6 +272,7 @@ // different kinds is always java.lang.Object. ciType* ciTypeFlow::StateVector::type_meet_internal(ciType* t1, ciType* t2, ciTypeFlow* analyzer) { assert(t1 != t2, "checked in caller"); + if (t1->equals(top_type())) { return t2; } else if (t2->equals(top_type())) { @@ -291,50 +293,66 @@ // At least one of the two types is a non-top primitive type. // The other type is not equal to it. Fall to bottom. return bottom_type(); - } else { - // Both types are non-top non-primitive types. That is, - // both types are either instanceKlasses or arrayKlasses. - ciKlass* object_klass = analyzer->env()->Object_klass(); - ciKlass* k1 = t1->as_klass(); - ciKlass* k2 = t2->as_klass(); - if (k1->equals(object_klass) || k2->equals(object_klass)) { - return object_klass; - } else if (!k1->is_loaded() || !k2->is_loaded()) { - // Unloaded classes fall to java.lang.Object at a merge. - return object_klass; - } else if (k1->is_interface() != k2->is_interface()) { - // When an interface meets a non-interface, we get Object; - // This is what the verifier does. - return object_klass; - } else if (k1->is_array_klass() || k2->is_array_klass()) { - // When an array meets a non-array, we get Object. - // When objArray meets typeArray, we also get Object. - // And when typeArray meets different typeArray, we again get Object. - // But when objArray meets objArray, we look carefully at element types. - if (k1->is_obj_array_klass() && k2->is_obj_array_klass()) { - // Meet the element types, then construct the corresponding array type. - ciKlass* elem1 = k1->as_obj_array_klass()->element_klass(); - ciKlass* elem2 = k2->as_obj_array_klass()->element_klass(); - ciKlass* elem = type_meet_internal(elem1, elem2, analyzer)->as_klass(); - // Do an easy shortcut if one type is a super of the other. - if (elem == elem1) { - assert(k1 == ciObjArrayKlass::make(elem), "shortcut is OK"); - return k1; - } else if (elem == elem2) { - assert(k2 == ciObjArrayKlass::make(elem), "shortcut is OK"); - return k2; - } else { - return ciObjArrayKlass::make(elem); - } + } + + // Unwrap the types after gathering nullness information + bool never_null1 = t1->is_never_null(); + bool never_null2 = t2->is_never_null(); + t1 = t1->unwrap(); + t2 = t2->unwrap(); + + // Both types are non-top non-primitive types. That is, + // both types are either instanceKlasses or arrayKlasses. + ciKlass* object_klass = analyzer->env()->Object_klass(); + ciKlass* k1 = t1->as_klass(); + ciKlass* k2 = t2->as_klass(); + if (k1->equals(object_klass) || k2->equals(object_klass)) { + return object_klass; + } else if (!k1->is_loaded() || !k2->is_loaded()) { + // Unloaded classes fall to java.lang.Object at a merge. + return object_klass; + } else if (k1->is_interface() != k2->is_interface()) { + // When an interface meets a non-interface, we get Object; + // This is what the verifier does. + return object_klass; + } else if (k1->is_array_klass() || k2->is_array_klass()) { + // When an array meets a non-array, we get Object. + // When objArray meets typeArray, we also get Object. + // And when typeArray meets different typeArray, we again get Object. + // But when objArray meets objArray, we look carefully at element types. + if (k1->is_obj_array_klass() && k2->is_obj_array_klass()) { + // Meet the element types, then construct the corresponding array type. + ciKlass* elem1 = k1->as_obj_array_klass()->element_klass(); + ciKlass* elem2 = k2->as_obj_array_klass()->element_klass(); + ciKlass* elem = type_meet_internal(elem1, elem2, analyzer)->as_klass(); + // Do an easy shortcut if one type is a super of the other. + if (elem == elem1) { + assert(k1 == ciObjArrayKlass::make(elem), "shortcut is OK"); + return k1; + } else if (elem == elem2) { + assert(k2 == ciObjArrayKlass::make(elem), "shortcut is OK"); + return k2; } else { - return object_klass; + return ciObjArrayKlass::make(elem); } + } else if (k1->is_value_array_klass() || k2->is_value_array_klass()) { + ciKlass* elem1 = k1->as_array_klass()->element_klass(); + ciKlass* elem2 = k2->as_array_klass()->element_klass(); + ciKlass* elem = type_meet_internal(elem1, elem2, analyzer)->as_klass(); + return ciArrayKlass::make(elem); } else { - // Must be two plain old instance klasses. - assert(k1->is_instance_klass(), "previous cases handle non-instances"); - assert(k2->is_instance_klass(), "previous cases handle non-instances"); - return k1->least_common_ancestor(k2); + return object_klass; + } + } else { + // Must be two plain old instance klasses. + assert(k1->is_instance_klass(), "previous cases handle non-instances"); + assert(k2->is_instance_klass(), "previous cases handle non-instances"); + ciType* result = k1->least_common_ancestor(k2); + if (never_null1 && never_null2 && result->is_valuetype()) { + // Both value types are never null, mark the result as never null + result = analyzer->mark_as_never_null(result); } + return result; } } @@ -396,13 +414,22 @@ // "Push" the method signature into the first few locals. state->set_stack_size(-max_locals()); if (!method()->is_static()) { - state->push(method()->holder()); + ciType* holder = method()->holder(); + if (holder->is_valuetype()) { + // The receiver is never null + holder = mark_as_never_null(holder); + } + state->push(holder); assert(state->tos() == state->local(0), ""); } for (ciSignatureStream str(method()->signature()); !str.at_return_type(); str.next()) { - state->push_translate(str.type()); + ciType* arg = str.type(); + if (str.is_never_null()) { + arg = mark_as_never_null(arg); + } + state->push_translate(arg); } // Set the rest of the locals to bottom. Cell cell = state->next_cell(state->tos()); @@ -548,12 +575,12 @@ } // ------------------------------------------------------------------ -// ciTypeFlow::StateVector::do_aaload -void ciTypeFlow::StateVector::do_aaload(ciBytecodeStream* str) { +// ciTypeFlow::StateVector::do_aload +void ciTypeFlow::StateVector::do_aload(ciBytecodeStream* str) { pop_int(); - ciObjArrayKlass* array_klass = pop_objArray(); + ciArrayKlass* array_klass = pop_objOrValueArray(); if (array_klass == NULL) { - // Did aaload on a null reference; push a null and ignore the exception. + // Did aload on a null reference; push a null and ignore the exception. // This instruction will never continue normally. All we have to do // is report a value that will meet correctly with any downstream // reference types on paths that will truly be executed. This null type @@ -578,7 +605,12 @@ (Deoptimization::Reason_unloaded, Deoptimization::Action_reinterpret)); } else { - push_object(element_klass); + if (element_klass->is_valuetype()) { + // Value type array elements are never null + push(outer()->mark_as_never_null(element_klass)); + } else { + push_object(element_klass); + } } } @@ -597,7 +629,13 @@ do_null_assert(klass); } else { pop_object(); - push_object(klass); + if (str->is_klass_never_null()) { + // Casting to a Q-Type contains a NULL check + assert(klass->is_valuetype(), "must be a value type"); + push(outer()->mark_as_never_null(klass)); + } else { + push_object(klass); + } } } @@ -639,6 +677,10 @@ // (See bug 4379915.) do_null_assert(field_type->as_klass()); } else { + if (field->is_flattenable()) { + // A flattenable field is never null + field_type = outer()->mark_as_never_null(field_type); + } push_translate(field_type); } } @@ -706,6 +748,9 @@ // See do_getstatic() for similar explanation, as well as bug 4684993. do_null_assert(return_type->as_klass()); } else { + if (sigstr.is_never_null()) { + return_type = outer()->mark_as_never_null(return_type); + } push_translate(return_type); } } @@ -729,13 +774,17 @@ outer()->record_failure("ldc did not link"); return; } - if (basic_type == T_OBJECT || basic_type == T_ARRAY) { + if (basic_type == T_OBJECT || basic_type == T_VALUETYPE || basic_type == T_ARRAY) { ciObject* obj = con.as_object(); if (obj->is_null_object()) { push_null(); } else { assert(obj->is_instance() || obj->is_array(), "must be java_mirror of klass"); - push_object(obj->klass()); + ciType* type = obj->klass(); + if (type->is_valuetype()) { + type = outer()->mark_as_never_null(type); + } + push(type); } } else { push_translate(ciType::make(basic_type)); @@ -771,6 +820,42 @@ } // ------------------------------------------------------------------ +// ciTypeFlow::StateVector::do_defaultvalue +void ciTypeFlow::StateVector::do_defaultvalue(ciBytecodeStream* str) { + bool will_link; + ciKlass* klass = str->get_klass(will_link); + if (!will_link) { + trap(str, klass, str->get_klass_index()); + } else { + // The default value type is never null + push(outer()->mark_as_never_null(klass)); + } +} + +// ------------------------------------------------------------------ +// ciTypeFlow::StateVector::do_withfield +void ciTypeFlow::StateVector::do_withfield(ciBytecodeStream* str) { + bool will_link; + ciField* field = str->get_field(will_link); + ciKlass* klass = field->holder(); + if (!will_link) { + trap(str, klass, str->get_field_holder_index()); + } else { + ciType* type = pop_value(); + ciType* field_type = field->type(); + assert(field_type->is_loaded(), "field type must be loaded"); + if (field_type->is_two_word()) { + ciType* type2 = pop_value(); + assert(type2->is_two_word(), "must be 2nd half"); + assert(type == half_type(type2), "must be 2nd half"); + } + pop_object(); + // The newly created value type can never be null + push(outer()->mark_as_never_null(klass)); + } +} + +// ------------------------------------------------------------------ // ciTypeFlow::StateVector::do_newarray void ciTypeFlow::StateVector::do_newarray(ciBytecodeStream* str) { pop_int(); @@ -875,13 +960,13 @@ } switch(str->cur_bc()) { - case Bytecodes::_aaload: do_aaload(str); break; + case Bytecodes::_aaload: do_aload(str); break; case Bytecodes::_aastore: { pop_object(); pop_int(); - pop_objArray(); + pop_objOrValueArray(); break; } case Bytecodes::_aconst_null: @@ -903,7 +988,7 @@ if (!will_link) { trap(str, element_klass, str->get_klass_index()); } else { - push_object(ciObjArrayKlass::make(element_klass)); + push_object(ciArrayKlass::make(element_klass)); } break; } @@ -1435,6 +1520,9 @@ case Bytecodes::_new: do_new(str); break; + case Bytecodes::_defaultvalue: do_defaultvalue(str); break; + case Bytecodes::_withfield: do_withfield(str); break; + case Bytecodes::_newarray: do_newarray(str); break; case Bytecodes::_pop: @@ -1462,6 +1550,7 @@ push(value2); break; } + case Bytecodes::_wide: default: { @@ -1745,9 +1834,12 @@ break; } - case Bytecodes::_athrow: case Bytecodes::_ireturn: - case Bytecodes::_lreturn: case Bytecodes::_freturn: - case Bytecodes::_dreturn: case Bytecodes::_areturn: + case Bytecodes::_athrow: + case Bytecodes::_ireturn: + case Bytecodes::_lreturn: + case Bytecodes::_freturn: + case Bytecodes::_dreturn: + case Bytecodes::_areturn: case Bytecodes::_return: _successors = new (arena) GrowableArray(arena, 1, 0, NULL); @@ -2978,6 +3070,11 @@ } } +ciType* ciTypeFlow::mark_as_never_null(ciType* type) { + // Wrap the type to carry the information that it is never null + return env()->make_never_null_wrapper(type); +} + #ifndef PRODUCT // ------------------------------------------------------------------ // ciTypeFlow::print_on