< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page

        

*** 1395,1404 **** --- 1395,1405 ---- //------------------------------cast_not_null---------------------------------- // Cast obj to not-null on this path Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) { + assert(!obj->is_ValueType(), "should not cast value type"); const Type *t = _gvn.type(obj); const Type *t_not_null = t->join_speculative(TypePtr::NOTNULL); // Object is already not-null? if( t == t_not_null ) return obj;
*** 1770,1787 **** } else { // Pass value type argument via oop to callee arg = vt->allocate(this)->get_oop(); } } else if (t->is_valuetypeptr()) { // Constant null passed for a value type argument assert(arg->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?"); - ciMethod* declared_method = method()->get_method_at_bci(bci()); int arg_size = declared_method->signature()->arg_size_for_bc(java_bc()); inc_sp(arg_size); // restore arguments uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); return; } call->init_req(idx, arg); idx++; } } --- 1771,1796 ---- } else { // Pass value type argument via oop to callee arg = vt->allocate(this)->get_oop(); } } else if (t->is_valuetypeptr()) { + ciMethod* declared_method = method()->get_method_at_bci(bci()); + if (arg->is_ValueTypePtr()) { + // We are calling an Object method with a value type receiver + ValueTypePtrNode* vt = arg->isa_ValueTypePtr(); + assert(i == TypeFunc::Parms && !declared_method->is_static(), "argument must be receiver"); + assert(vt->is_allocated(&gvn()), "argument must be allocated"); + arg = vt->get_oop(); + } else { // Constant null passed for a value type argument assert(arg->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?"); int arg_size = declared_method->signature()->arg_size_for_bc(java_bc()); inc_sp(arg_size); // restore arguments uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); return; } + } call->init_req(idx, arg); idx++; } }
*** 3272,3288 **** res = ValueTypeNode::make_from_oop(this, res, toop->value_klass(), /* buffer_check */ false, /* null2default */ false); } return res; } // Deoptimize if 'ary' is flattened or if 'obj' is null and 'ary' is a value type array void GraphKit::gen_value_type_array_guard(Node* ary, Node* obj, Node* elem_klass) { assert(EnableValhalla, "should only be used if value types are enabled"); if (elem_klass == NULL) { // Load array element klass Node* kls = load_object_klass(ary); ! Node* k_adr = basic_plus_adr(kls, kls, in_bytes(ArrayKlass::element_klass_offset())); elem_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS)); } // Check if element is a value type Node* flags_addr = basic_plus_adr(elem_klass, in_bytes(Klass::access_flags_offset())); Node* flags = make_load(NULL, flags_addr, TypeInt::INT, T_INT, MemNode::unordered); --- 3281,3318 ---- res = ValueTypeNode::make_from_oop(this, res, toop->value_klass(), /* buffer_check */ false, /* null2default */ false); } return res; } + // Deoptimize if 'obj' is a value type + void GraphKit::gen_value_type_guard(Node* obj, int nargs) { + assert(EnableValhalla, "should only be used if value types are enabled"); + Node* bol = NULL; + if (obj->is_ValueTypeBase()) { + bol = intcon(0); + } else { + Node* kls = load_object_klass(obj); + Node* flags_addr = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); + Node* flags = make_load(NULL, flags_addr, TypeInt::INT, T_INT, MemNode::unordered); + Node* is_value = _gvn.transform(new AndINode(flags, intcon(JVM_ACC_VALUE))); + Node* cmp = _gvn.transform(new CmpINode(is_value, intcon(0))); + bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq)); + } + { BuildCutout unless(this, bol, PROB_MAX); + inc_sp(nargs); + uncommon_trap(Deoptimization::Reason_class_check, + Deoptimization::Action_none); + } + } + // Deoptimize if 'ary' is flattened or if 'obj' is null and 'ary' is a value type array void GraphKit::gen_value_type_array_guard(Node* ary, Node* obj, Node* elem_klass) { assert(EnableValhalla, "should only be used if value types are enabled"); if (elem_klass == NULL) { // Load array element klass Node* kls = load_object_klass(ary); ! Node* k_adr = basic_plus_adr(kls, in_bytes(ArrayKlass::element_klass_offset())); elem_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS)); } // Check if element is a value type Node* flags_addr = basic_plus_adr(elem_klass, in_bytes(Klass::access_flags_offset())); Node* flags = make_load(NULL, flags_addr, TypeInt::INT, T_INT, MemNode::unordered);
*** 3324,3334 **** void GraphKit::gen_flattened_array_guard(Node* ary, int nargs) { assert(EnableValhalla, "should only be used if value types are enabled"); if (ValueArrayFlatten) { // Cannot statically determine if array is flattened, emit runtime check Node* kls = load_object_klass(ary); ! Node* lhp = basic_plus_adr(kls, kls, in_bytes(Klass::layout_helper_offset())); Node* layout_val = make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered); layout_val = _gvn.transform(new RShiftINode(layout_val, intcon(Klass::_lh_array_tag_shift))); Node* cmp = _gvn.transform(new CmpINode(layout_val, intcon(Klass::_lh_array_tag_vt_value))); Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne)); --- 3354,3364 ---- void GraphKit::gen_flattened_array_guard(Node* ary, int nargs) { assert(EnableValhalla, "should only be used if value types are enabled"); if (ValueArrayFlatten) { // Cannot statically determine if array is flattened, emit runtime check Node* kls = load_object_klass(ary); ! Node* lhp = basic_plus_adr(kls, in_bytes(Klass::layout_helper_offset())); Node* layout_val = make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered); layout_val = _gvn.transform(new RShiftINode(layout_val, intcon(Klass::_lh_array_tag_shift))); Node* cmp = _gvn.transform(new CmpINode(layout_val, intcon(Klass::_lh_array_tag_vt_value))); Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne));
*** 3404,3413 **** --- 3434,3450 ---- // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces assert(SynchronizationEntryBCI == InvocationEntryBci, ""); if( !GenerateSynchronizationCode ) return NULL; // Not locking things? + + // We cannot lock on a value type + const TypeOopPtr* objptr = _gvn.type(obj)->make_oopptr(); + if (objptr->can_be_value_type()) { + gen_value_type_guard(obj, 1); + } + if (stopped()) // Dead monitor? return NULL; assert(dead_locals_are_killed(), "should kill locals before sync. point");
*** 3476,3485 **** --- 3513,3523 ---- return; if (stopped()) { // Dead monitor? map()->pop_monitor(); // Kill monitor from debug info return; } + assert(!obj->is_ValueTypeBase(), "should not unlock on value type"); // Memory barrier to avoid floating things down past the locked region insert_mem_bar(Op_MemBarReleaseLock); const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
< prev index next >