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); // 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); } else { store = store_to_memory( control(), adr, val, bt, adr_type, is_vol ); } // If reference is volatile, prevent following volatiles ops from // floating up before the volatile write. if (is_vol) { // First place the specific membar for THIS volatile index. This first // membar is dependent on the store, keeping any other membars generated // below from floating up past the store. int adr_idx = C->get_alias_index(adr_type); insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store); // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed // volatile alias indices. Skip this if the membar is redundant. if (adr_idx != Compile::AliasIdxBot) { insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store); } // Finally, place alias-index-specific membars for each volatile index // that isn't the adr_idx membar. Typically there's only 1 or 2. for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) { if (i != adr_idx && C->alias_type(i)->is_volatile()) { insert_mem_bar_volatile(Op_MemBarVolatile, i, store); } } } // 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. if (is_field && field->is_final()) { set_wrote_final(true); } }
Node* pop_node(BasicType n_type) { int n_size = type2size[n_type]; if (n_size == 1) return pop(); else if (n_size == 2) return pop_pair(); else return NULL; }