comparison src/share/vm/opto/library_call.cpp @ 4763:1dc233a8c7fe

7121140: Allocation paths require explicit memory synchronization operations for RMO systems Summary: adds store store barrier after initialization of header and body of objects. Reviewed-by: never, kvn
author roland
date Tue, 20 Dec 2011 16:56:50 +0100
parents 069ab3f976d3
children 22cee0ee8927
comparison
equal deleted inserted replaced
4762:069ab3f976d3 4763:1dc233a8c7fe
4191 void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark) { 4191 void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark) {
4192 assert(obj_size != NULL, ""); 4192 assert(obj_size != NULL, "");
4193 Node* raw_obj = alloc_obj->in(1); 4193 Node* raw_obj = alloc_obj->in(1);
4194 assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); 4194 assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
4195 4195
4196 AllocateNode* alloc = NULL;
4196 if (ReduceBulkZeroing) { 4197 if (ReduceBulkZeroing) {
4197 // We will be completely responsible for initializing this object - 4198 // We will be completely responsible for initializing this object -
4198 // mark Initialize node as complete. 4199 // mark Initialize node as complete.
4199 AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); 4200 alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn);
4200 // The object was just allocated - there should be no any stores! 4201 // The object was just allocated - there should be no any stores!
4201 guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), ""); 4202 guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), "");
4203 // Mark as complete_with_arraycopy so that on AllocateNode
4204 // expansion, we know this AllocateNode is initialized by an array
4205 // copy and a StoreStore barrier exists after the array copy.
4206 alloc->initialization()->set_complete_with_arraycopy();
4202 } 4207 }
4203 4208
4204 // Copy the fastest available way. 4209 // Copy the fastest available way.
4205 // TODO: generate fields copies for small objects instead. 4210 // TODO: generate fields copies for small objects instead.
4206 Node* src = obj; 4211 Node* src = obj;
4258 T_OBJECT, 4263 T_OBJECT,
4259 false); 4264 false);
4260 } 4265 }
4261 4266
4262 // Do not let reads from the cloned object float above the arraycopy. 4267 // Do not let reads from the cloned object float above the arraycopy.
4263 insert_mem_bar(Op_MemBarCPUOrder); 4268 if (alloc != NULL) {
4269 // Do not let stores that initialize this object be reordered with
4270 // a subsequent store that would make this object accessible by
4271 // other threads.
4272 // Record what AllocateNode this StoreStore protects so that
4273 // escape analysis can go from the MemBarStoreStoreNode to the
4274 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
4275 // based on the escape status of the AllocateNode.
4276 insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
4277 } else {
4278 insert_mem_bar(Op_MemBarCPUOrder);
4279 }
4264 } 4280 }
4265 4281
4266 //------------------------inline_native_clone---------------------------- 4282 //------------------------inline_native_clone----------------------------
4267 // Here are the simple edge cases: 4283 // Here are the simple edge cases:
4268 // null receiver => normal trap 4284 // null receiver => normal trap
5001 // The next memory barrier is added to avoid it. If the arraycopy can be 5017 // The next memory barrier is added to avoid it. If the arraycopy can be
5002 // optimized away (which it can, sometimes) then we can manually remove 5018 // optimized away (which it can, sometimes) then we can manually remove
5003 // the membar also. 5019 // the membar also.
5004 // 5020 //
5005 // Do not let reads from the cloned object float above the arraycopy. 5021 // Do not let reads from the cloned object float above the arraycopy.
5006 if (InsertMemBarAfterArraycopy || alloc != NULL) 5022 if (alloc != NULL) {
5023 // Do not let stores that initialize this object be reordered with
5024 // a subsequent store that would make this object accessible by
5025 // other threads.
5026 // Record what AllocateNode this StoreStore protects so that
5027 // escape analysis can go from the MemBarStoreStoreNode to the
5028 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
5029 // based on the escape status of the AllocateNode.
5030 insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
5031 } else if (InsertMemBarAfterArraycopy)
5007 insert_mem_bar(Op_MemBarCPUOrder); 5032 insert_mem_bar(Op_MemBarCPUOrder);
5008 } 5033 }
5009 5034
5010 5035
5011 // Helper function which determines if an arraycopy immediately follows 5036 // Helper function which determines if an arraycopy immediately follows