< prev index next >

src/hotspot/share/c1/c1_Instruction.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1999, 2017, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 1999, 2019, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 27,36 **** --- 27,38 ---- #include "c1/c1_Instruction.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_ValueStack.hpp" #include "ci/ciObjArrayKlass.hpp" #include "ci/ciTypeArrayKlass.hpp" + #include "ci/ciValueArrayKlass.hpp" + #include "ci/ciValueKlass.hpp" // Implementation of Instruction
*** 110,119 **** --- 112,202 ---- return t->as_klass()->exact_klass(); } return NULL; } + ciKlass* Instruction::as_loaded_klass_or_null() const { + ciType* type = declared_type(); + if (type != NULL && type->is_klass()) { + ciKlass* klass = type->as_klass(); + if (klass->is_loaded()) { + return klass; + } + } + return NULL; + } + + bool Instruction::is_loaded_flattened_array() const { + if (ValueArrayFlatten) { + ciType* type = declared_type(); + if (type != NULL && type->is_value_array_klass()) { + ciValueArrayKlass* vak = type->as_value_array_klass(); + ArrayStorageProperties props = vak->storage_properties(); + return (!props.is_empty() && props.is_null_free() && props.is_flattened()); + } + } + + return false; + } + + bool Instruction::maybe_flattened_array() { + if (ValueArrayFlatten) { + ciType* type = declared_type(); + if (type != NULL) { + if (type->is_obj_array_klass()) { + // Check for array covariance. One of the following declared types may be a flattened array: + ciKlass* element_klass = type->as_obj_array_klass()->element_klass(); + if (!element_klass->is_loaded() || + element_klass->is_java_lang_Object() || // (ValueType[] <: Object[]) + element_klass->is_interface() || // (ValueType[] <: <any interface>[]) + (element_klass->is_valuetype() && element_klass->as_value_klass()->flatten_array())) { // (ValueType[] <: ValueType?[]) + // We will add a runtime check for flat-ness. + return true; + } + } else if (type->is_value_array_klass()) { + ciKlass* element_klass = type->as_value_array_klass()->element_klass(); + if (!element_klass->is_loaded() || + (element_klass->is_valuetype() && element_klass->as_value_klass()->flatten_array())) { // (ValueType[] <: ValueType?[]) + // We will add a runtime check for flat-ness. + return true; + } + } else if (type->is_klass() && type->as_klass()->is_java_lang_Object()) { + // This can happen as a parameter to System.arraycopy() + return true; + } + } else { + // Type info gets lost during Phi merging (Phi, IfOp, etc), but we might be storing into a + // flattened array, so we should do a runtime check. + return true; + } + } + + return false; + } + + bool Instruction::maybe_null_free_array() { + ciType* type = declared_type(); + if (type != NULL) { + if (type->is_obj_array_klass()) { + // Check for array covariance. One of the following declared types may be a null-free array: + ciKlass* element_klass = type->as_obj_array_klass()->element_klass(); + if (!element_klass->is_loaded() || + element_klass->is_java_lang_Object() || // (ValueType[] <: Object[]) + element_klass->is_interface() || // (ValueType[] <: <any interface>[]) + element_klass->is_valuetype()) { // (ValueType[] <: ValueType?[]) + // We will add a runtime check for flat-ness. + return true; + } + } + } else { + // Type info gets lost during Phi merging (Phi, IfOp, etc), but we might be storing into a + // flattened array, so we should do a runtime check. + return true; + } + + return false; + } #ifndef PRODUCT void Instruction::check_state(ValueStack* state) { if (state != NULL) { state->verify();
*** 195,204 **** --- 278,301 ---- assert(array_type->is_array_klass(), "what else?"); ciArrayKlass* ak = (ciArrayKlass*)array_type; return ak->element_type(); } + bool StoreIndexed::is_exact_flattened_array_store() const { + if (array()->is_loaded_flattened_array() && value()->as_Constant() == NULL && value()->declared_type() != NULL) { + ciKlass* element_klass = array()->declared_type()->as_value_array_klass()->element_klass(); + ciKlass* actual_klass = value()->declared_type()->as_klass(); + + // The following check can fail with inlining: + // void test45_inline(Object[] oa, Object o, int index) { oa[index] = o; } + // void test45(MyValue1[] va, int index, MyValue2 v) { test45_inline(va, v, index); } + if (element_klass == actual_klass) { + return true; + } + } + return false; + } ciType* LoadField::declared_type() const { return field()->type(); }
*** 206,216 **** ciType* NewTypeArray::exact_type() const { return ciTypeArrayKlass::make(elt_type()); } ciType* NewObjectArray::exact_type() const { ! return ciObjArrayKlass::make(klass()); } ciType* NewArray::declared_type() const { return exact_type(); } --- 303,326 ---- ciType* NewTypeArray::exact_type() const { return ciTypeArrayKlass::make(elt_type()); } ciType* NewObjectArray::exact_type() const { ! ciKlass* element_klass = klass(); ! if (is_never_null() && element_klass->is_valuetype()) { ! if (element_klass->as_value_klass()->flatten_array()) { ! return ciValueArrayKlass::make(element_klass); ! } else { ! return ciObjArrayKlass::make(element_klass, /*never_null =*/true); ! } ! } else { ! return ciObjArrayKlass::make(element_klass); ! } ! } ! ! ciType* NewMultiArray::exact_type() const { ! return _klass; } ciType* NewArray::declared_type() const { return exact_type(); }
*** 221,230 **** --- 331,357 ---- ciType* NewInstance::declared_type() const { return exact_type(); } + Value NewValueTypeInstance::depends_on() { + if (_depends_on != this) { + if (_depends_on->as_NewValueTypeInstance() != NULL) { + return _depends_on->as_NewValueTypeInstance()->depends_on(); + } + } + return _depends_on; + } + + ciType* NewValueTypeInstance::exact_type() const { + return klass(); + } + + ciType* NewValueTypeInstance::declared_type() const { + return exact_type(); + } + ciType* CheckCast::declared_type() const { return klass(); } // Implementation of ArithmeticOp
*** 320,340 **** // Implementation of Invoke Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, ! int vtable_index, ciMethod* target, ValueStack* state_before) : StateSplit(result_type, state_before) , _code(code) , _recv(recv) , _args(args) , _vtable_index(vtable_index) , _target(target) { set_flag(TargetIsLoadedFlag, target->is_loaded()); set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict()); assert(args != NULL, "args must exist"); #ifdef ASSERT AssertValues assert_value; values_do(&assert_value); --- 447,468 ---- // Implementation of Invoke Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, ! int vtable_index, ciMethod* target, ValueStack* state_before, bool never_null) : StateSplit(result_type, state_before) , _code(code) , _recv(recv) , _args(args) , _vtable_index(vtable_index) , _target(target) { set_flag(TargetIsLoadedFlag, target->is_loaded()); set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict()); + set_never_null(never_null); assert(args != NULL, "args must exist"); #ifdef ASSERT AssertValues assert_value; values_do(&assert_value);
< prev index next >