Mercurial > hg > graal-compiler
comparison src/share/vm/opto/macro.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 | d12a66fa3820 |
comparison
equal
deleted
inserted
replaced
4762:069ab3f976d3 | 4763:1dc233a8c7fe |
---|---|
1086 Node* i_o = alloc->in(TypeFunc::I_O); | 1086 Node* i_o = alloc->in(TypeFunc::I_O); |
1087 Node* size_in_bytes = alloc->in(AllocateNode::AllocSize); | 1087 Node* size_in_bytes = alloc->in(AllocateNode::AllocSize); |
1088 Node* klass_node = alloc->in(AllocateNode::KlassNode); | 1088 Node* klass_node = alloc->in(AllocateNode::KlassNode); |
1089 Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); | 1089 Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); |
1090 | 1090 |
1091 Node* storestore = alloc->storestore(); | |
1092 if (storestore != NULL) { | |
1093 // Break this link that is no longer useful and confuses register allocation | |
1094 storestore->set_req(MemBarNode::Precedent, top()); | |
1095 } | |
1096 | |
1091 assert(ctrl != NULL, "must have control"); | 1097 assert(ctrl != NULL, "must have control"); |
1092 // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. | 1098 // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. |
1093 // they will not be used if "always_slow" is set | 1099 // they will not be used if "always_slow" is set |
1094 enum { slow_result_path = 1, fast_result_path = 2 }; | 1100 enum { slow_result_path = 1, fast_result_path = 2 }; |
1095 Node *result_region; | 1101 Node *result_region; |
1287 transform_later(new_alloc_bytes); | 1293 transform_later(new_alloc_bytes); |
1288 fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, | 1294 fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, |
1289 0, new_alloc_bytes, T_LONG); | 1295 0, new_alloc_bytes, T_LONG); |
1290 } | 1296 } |
1291 | 1297 |
1298 InitializeNode* init = alloc->initialization(); | |
1292 fast_oop_rawmem = initialize_object(alloc, | 1299 fast_oop_rawmem = initialize_object(alloc, |
1293 fast_oop_ctrl, fast_oop_rawmem, fast_oop, | 1300 fast_oop_ctrl, fast_oop_rawmem, fast_oop, |
1294 klass_node, length, size_in_bytes); | 1301 klass_node, length, size_in_bytes); |
1302 | |
1303 // If initialization is performed by an array copy, any required | |
1304 // MemBarStoreStore was already added. If the object does not | |
1305 // escape no need for a MemBarStoreStore. Otherwise we need a | |
1306 // MemBarStoreStore so that stores that initialize this object | |
1307 // can't be reordered with a subsequent store that makes this | |
1308 // object accessible by other threads. | |
1309 if (init == NULL || (!init->is_complete_with_arraycopy() && !init->does_not_escape())) { | |
1310 if (init == NULL || init->req() < InitializeNode::RawStores) { | |
1311 // No InitializeNode or no stores captured by zeroing | |
1312 // elimination. Simply add the MemBarStoreStore after object | |
1313 // initialization. | |
1314 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot, fast_oop_rawmem); | |
1315 transform_later(mb); | |
1316 | |
1317 mb->init_req(TypeFunc::Memory, fast_oop_rawmem); | |
1318 mb->init_req(TypeFunc::Control, fast_oop_ctrl); | |
1319 fast_oop_ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control); | |
1320 transform_later(fast_oop_ctrl); | |
1321 fast_oop_rawmem = new (C, 1) ProjNode(mb,TypeFunc::Memory); | |
1322 transform_later(fast_oop_rawmem); | |
1323 } else { | |
1324 // Add the MemBarStoreStore after the InitializeNode so that | |
1325 // all stores performing the initialization that were moved | |
1326 // before the InitializeNode happen before the storestore | |
1327 // barrier. | |
1328 | |
1329 Node* init_ctrl = init->proj_out(TypeFunc::Control); | |
1330 Node* init_mem = init->proj_out(TypeFunc::Memory); | |
1331 | |
1332 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); | |
1333 transform_later(mb); | |
1334 | |
1335 Node* ctrl = new (C, 1) ProjNode(init,TypeFunc::Control); | |
1336 transform_later(ctrl); | |
1337 Node* mem = new (C, 1) ProjNode(init,TypeFunc::Memory); | |
1338 transform_later(mem); | |
1339 | |
1340 // The MemBarStoreStore depends on control and memory coming | |
1341 // from the InitializeNode | |
1342 mb->init_req(TypeFunc::Memory, mem); | |
1343 mb->init_req(TypeFunc::Control, ctrl); | |
1344 | |
1345 ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control); | |
1346 transform_later(ctrl); | |
1347 mem = new (C, 1) ProjNode(mb,TypeFunc::Memory); | |
1348 transform_later(mem); | |
1349 | |
1350 // All nodes that depended on the InitializeNode for control | |
1351 // and memory must now depend on the MemBarNode that itself | |
1352 // depends on the InitializeNode | |
1353 _igvn.replace_node(init_ctrl, ctrl); | |
1354 _igvn.replace_node(init_mem, mem); | |
1355 } | |
1356 } | |
1295 | 1357 |
1296 if (C->env()->dtrace_extended_probes()) { | 1358 if (C->env()->dtrace_extended_probes()) { |
1297 // Slow-path call | 1359 // Slow-path call |
1298 int size = TypeFunc::Parms + 2; | 1360 int size = TypeFunc::Parms + 2; |
1299 CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), | 1361 CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), |