< prev index next >

src/share/vm/opto/parse3.cpp

Print this page
rev 12906 : [mq]: gc_interface

*** 168,178 **** // Build the resultant type of the load const Type *type; bool must_assert_null = false; ! if( bt == T_OBJECT ) { if (!field->type()->is_loaded()) { type = TypeInstPtr::BOTTOM; must_assert_null = true; } else if (field->is_static_constant()) { // This can happen if the constant oop is non-perm. --- 168,183 ---- // Build the resultant type of the load const Type *type; bool must_assert_null = false; ! C2DecoratorSet decorators = C2_ACCESS_ON_HEAP | C2_ACCESS_FREE_CONTROL; ! decorators |= is_vol ? C2_MO_VOLATILE : C2_MO_RELAXED; ! ! bool is_obj = bt == T_OBJECT || bt == T_ARRAY; ! ! if (is_obj) { if (!field->type()->is_loaded()) { type = TypeInstPtr::BOTTOM; must_assert_null = true; } else if (field->is_static_constant()) { // This can happen if the constant oop is non-perm.
*** 189,206 **** type = TypeOopPtr::make_from_klass(field_klass->as_klass()); } } else { type = Type::get_const_basic_type(bt); } ! if (support_IRIW_for_not_multiple_copy_atomic_cpu && field->is_volatile()) { ! insert_mem_bar(Op_MemBarVolatile); // StoreLoad barrier ! } ! // Build the load. ! // ! MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered; ! bool needs_atomic_access = is_vol || AlwaysAtomicAccesses; ! Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, needs_atomic_access); // Adjust Java stack if (type2size[bt] == 1) push(ld); else --- 194,205 ---- type = TypeOopPtr::make_from_klass(field_klass->as_klass()); } } else { type = Type::get_const_basic_type(bt); } ! ! Node* ld = access_load_at(obj, adr, adr_type, type, bt, decorators); // Adjust Java stack if (type2size[bt] == 1) push(ld); else
*** 227,327 **** // If there is going to be a trap, put it at the next bytecode: set_bci(iter().next_bci()); null_assert(peek()); set_bci(iter().cur_bci()); // put it back } - - // If reference is volatile, prevent following memory ops from - // floating up past the volatile read. Also prevents commoning - // another volatile read. - if (field->is_volatile()) { - // Memory barrier includes bogus read of value to force load BEFORE membar - insert_mem_bar(Op_MemBarAcquire, ld); - } } void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { bool is_vol = field->is_volatile(); - // If reference is volatile, prevent following memory ops from - // floating down past the volatile write. Also prevents commoning - // another volatile read. - if (is_vol) insert_mem_bar(Op_MemBarRelease); // Compute address and memory type. int offset = field->offset_in_bytes(); const TypePtr* adr_type = C->alias_type(field)->adr_type(); Node* adr = basic_plus_adr(obj, obj, offset); BasicType bt = field->layout_type(); // Value to be stored Node* val = type2size[bt] == 1 ? pop() : pop_pair(); - // Round doubles before storing - if (bt == T_DOUBLE) val = dstore_rounding(val); ! // Conservatively release stores of object references. ! const MemNode::MemOrd mo = ! is_vol ? ! // Volatile fields need releasing stores. ! MemNode::release : ! // Non-volatile fields also need releasing stores if they hold an ! // object reference, because the object reference might point to ! // a freshly created object. ! StoreNode::release_if_reference(bt); // Store the value. ! Node* store; ! if (bt == T_OBJECT) { ! const TypeOopPtr* field_type; if (!field->type()->is_loaded()) { field_type = TypeInstPtr::BOTTOM; } else { field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); - } - store = store_oop_to_object(control(), obj, adr, adr_type, val, field_type, bt, mo); } else { ! bool needs_atomic_access = is_vol || AlwaysAtomicAccesses; ! store = store_to_memory(control(), adr, val, bt, adr_type, mo, needs_atomic_access); } - - // If reference is volatile, prevent following volatiles ops from - // floating up before the volatile write. - if (is_vol) { - // If not multiple copy atomic, we do the MemBarVolatile before the load. - if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { - insert_mem_bar(Op_MemBarVolatile); // Use fat membar } // Remember we wrote a volatile field. // For not multiple copy atomic cpu (ppc64) a barrier should be issued // in constructors which have such stores. See do_exits() in parse1.cpp. ! if (is_field) { set_wrote_volatile(true); } - } - - if (is_field) { set_wrote_fields(true); - } // If the field is final, the rules of Java say we are in <init> or <clinit>. // Note the presence of writes to final non-static fields, so that we // can insert a memory barrier later on to keep the writes from floating // out of the constructor. // Any method can write a @Stable field; insert memory barriers after those also. - if (is_field && (field->is_final() || field->is_stable())) { if (field->is_final()) { set_wrote_final(true); ! } ! if (field->is_stable()) { ! set_wrote_stable(true); ! } ! // Preserve allocation ptr to create precedent edge to it in membar // generated on exit from constructor. // Can't bind stable with its allocation, only record allocation for final field. - if (field->is_final() && AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) { set_alloc_with_final(obj); } } } //============================================================================= void Parse::do_anewarray() { bool will_link; --- 226,293 ---- // If there is going to be a trap, put it at the next bytecode: set_bci(iter().next_bci()); null_assert(peek()); set_bci(iter().cur_bci()); // put it back } } void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { bool is_vol = field->is_volatile(); // Compute address and memory type. int offset = field->offset_in_bytes(); const TypePtr* adr_type = C->alias_type(field)->adr_type(); Node* adr = basic_plus_adr(obj, obj, offset); BasicType bt = field->layout_type(); // Value to be stored Node* val = type2size[bt] == 1 ? pop() : pop_pair(); ! C2DecoratorSet decorators = C2_ACCESS_ON_HEAP; ! decorators |= is_vol ? C2_MO_VOLATILE : C2_MO_RELAXED; ! ! bool is_obj = bt == T_OBJECT || bt == T_ARRAY; // Store the value. ! const Type* field_type; if (!field->type()->is_loaded()) { field_type = TypeInstPtr::BOTTOM; } else { + if (is_obj) { field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); } else { ! field_type = Type::BOTTOM; } } + access_store_at(control(), obj, adr, adr_type, val, field_type, bt, decorators); + + if (is_field) { // Remember we wrote a volatile field. // For not multiple copy atomic cpu (ppc64) a barrier should be issued // in constructors which have such stores. See do_exits() in parse1.cpp. ! if (is_vol) { set_wrote_volatile(true); } set_wrote_fields(true); // If the field is final, the rules of Java say we are in <init> or <clinit>. // Note the presence of writes to final non-static fields, so that we // can insert a memory barrier later on to keep the writes from floating // out of the constructor. // Any method can write a @Stable field; insert memory barriers after those also. if (field->is_final()) { set_wrote_final(true); ! if (AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) { // Preserve allocation ptr to create precedent edge to it in membar // generated on exit from constructor. // Can't bind stable with its allocation, only record allocation for final field. set_alloc_with_final(obj); } } + if (field->is_stable()) { + set_wrote_stable(true); + } + } } //============================================================================= void Parse::do_anewarray() { bool will_link;
*** 376,386 **** const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT); for (jint i = 0; i < length_con; i++) { Node* elem = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1, nargs); intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop); Node* eaddr = basic_plus_adr(array, offset); ! store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT, MemNode::unordered); } } return array; } --- 342,352 ---- const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT); for (jint i = 0; i < length_con; i++) { Node* elem = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1, nargs); intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop); Node* eaddr = basic_plus_adr(array, offset); ! access_store_at(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT, C2_ACCESS_ON_HEAP | C2_ACCESS_ON_ARRAY); } } return array; }
< prev index next >