< 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
*** 111,120 **** --- 113,187 ---- } return NULL; } + // FIXME -- this is used by ValueStack::merge_types only. We should remove this function + // and use a better way for handling phi nodes. + bool Instruction::is_flattened_array() const { + if (ValueArrayFlatten) { + ciType* type = declared_type(); + if (type != NULL && type->is_value_array_klass()) { + ciValueKlass* element_klass = type->as_value_array_klass()->element_klass()->as_value_klass(); + assert(element_klass->is_loaded(), "ciValueKlasses are always loaded"); + if (element_klass->flatten_array()) { + return true; + } + } + } + + return false; + } + + bool Instruction::is_loaded_flattened_array() const { + if (ValueArrayFlatten) { + ciType* type = declared_type(); + if (type != NULL && type->is_value_array_klass()) { + ciValueKlass* element_klass = type->as_value_array_klass()->element_klass()->as_value_klass(); + assert(element_klass->is_loaded(), "ciValueKlasses are always loaded"); + if (element_klass->flatten_array()) { + return true; + } + } + } + + return false; + } + + bool Instruction::maybe_flattened_array() { + if (ValueArrayFlatten) { + ciType* type = declared_type(); + if (type != NULL) { + if (type->is_value_array_klass()) { + ciValueKlass* element_klass = type->as_value_array_klass()->element_klass()->as_value_klass(); + assert(element_klass->is_loaded(), "ciValueKlasses are always loaded"); + if (element_klass->flatten_array()) { + return true; + } + } else if (type->is_obj_array_klass()) { + ciKlass* element_klass = type->as_obj_array_klass()->element_klass(); + if (!element_klass->is_loaded() || element_klass->is_java_lang_Object() || element_klass->is_interface()) { + // Array covariance: + // (ValueType[] <: Object[]) + // (ValueType[] <: <any interface>[]) + // 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 if (as_Phi() != NULL) { + // Type info gets lost during Phi merging, 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 **** --- 262,281 ---- 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) { + ciKlass* element_klass = array()->declared_type()->as_value_array_klass()->element_klass(); + ciKlass* actual_klass = value()->declared_type()->as_klass(); + 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(); } --- 283,302 ---- ciType* NewTypeArray::exact_type() const { return ciTypeArrayKlass::make(elt_type()); } ciType* NewObjectArray::exact_type() const { ! ciKlass* element_klass = klass(); ! if (element_klass->is_valuetype()) { ! return ciValueArrayKlass::make(element_klass); ! } else { ! return ciObjArrayKlass::make(element_klass); ! } ! } ! ! ciType* NewMultiArray::exact_type() const { ! return _klass; } ciType* NewArray::declared_type() const { return exact_type(); }
*** 221,230 **** --- 307,333 ---- 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); --- 423,444 ---- // 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);
*** 789,808 **** if (is_set(BlockBegin::parser_loop_header_flag)) { TRACE_PHI(tty->print_cr("loop header block, initializing phi functions")); for_each_stack_value(new_state, index, new_value) { ! new_state->setup_phi_for_stack(this, index); TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", new_state->stack_at(index)->type()->tchar(), new_state->stack_at(index)->id(), index)); } BitMap& requires_phi_function = new_state->scope()->requires_phi_function(); for_each_local_value(new_state, index, new_value) { bool requires_phi = requires_phi_function.at(index) || (new_value->type()->is_double_word() && requires_phi_function.at(index + 1)); if (requires_phi || !SelectivePhiFunctions) { ! new_state->setup_phi_for_local(this, index); TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", new_state->local_at(index)->type()->tchar(), new_state->local_at(index)->id(), index)); } } } --- 893,912 ---- if (is_set(BlockBegin::parser_loop_header_flag)) { TRACE_PHI(tty->print_cr("loop header block, initializing phi functions")); for_each_stack_value(new_state, index, new_value) { ! new_state->setup_phi_for_stack(this, index, NULL, new_value); TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", new_state->stack_at(index)->type()->tchar(), new_state->stack_at(index)->id(), index)); } BitMap& requires_phi_function = new_state->scope()->requires_phi_function(); for_each_local_value(new_state, index, new_value) { bool requires_phi = requires_phi_function.at(index) || (new_value->type()->is_double_word() && requires_phi_function.at(index + 1)); if (requires_phi || !SelectivePhiFunctions) { ! new_state->setup_phi_for_local(this, index, NULL, new_value); TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", new_state->local_at(index)->type()->tchar(), new_state->local_at(index)->id(), index)); } } }
*** 857,867 **** for_each_stack_value(existing_state, index, existing_value) { Value new_value = new_state->stack_at(index); Phi* existing_phi = existing_value->as_Phi(); if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { ! existing_state->setup_phi_for_stack(this, index); TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", existing_state->stack_at(index)->type()->tchar(), existing_state->stack_at(index)->id(), index)); } } // create necessary phi functions for locals --- 961,971 ---- for_each_stack_value(existing_state, index, existing_value) { Value new_value = new_state->stack_at(index); Phi* existing_phi = existing_value->as_Phi(); if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { ! existing_state->setup_phi_for_stack(this, index, existing_value, new_value); TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", existing_state->stack_at(index)->type()->tchar(), existing_state->stack_at(index)->id(), index)); } } // create necessary phi functions for locals
*** 871,881 **** if (new_value == NULL || new_value->type()->tag() != existing_value->type()->tag()) { existing_state->invalidate_local(index); TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index)); } else if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { ! existing_state->setup_phi_for_local(this, index); TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", existing_state->local_at(index)->type()->tchar(), existing_state->local_at(index)->id(), index)); } } } --- 975,985 ---- if (new_value == NULL || new_value->type()->tag() != existing_value->type()->tag()) { existing_state->invalidate_local(index); TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index)); } else if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { ! existing_state->setup_phi_for_local(this, index, existing_value, new_value); TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", existing_state->local_at(index)->type()->tchar(), existing_state->local_at(index)->id(), index)); } } }
< prev index next >