@@ -281,7 +281,9 @@ bool ConnectionGraph::compute_escape() {
281
281
// 3. Adjust scalar_replaceable state of nonescaping objects and push
282
282
// scalar replaceable allocations on alloc_worklist for processing
283
283
// in split_unique_types().
284
+ GrowableArray<JavaObjectNode*> jobj_worklist;
284
285
int non_escaped_length = non_escaped_allocs_worklist.length ();
286
+ bool found_nsr_alloc = false ;
285
287
for (int next = 0 ; next < non_escaped_length; next++) {
286
288
JavaObjectNode* ptn = non_escaped_allocs_worklist.at (next);
287
289
bool noescape = (ptn->escape_state () == PointsToNode::NoEscape);
@@ -292,11 +294,25 @@ bool ConnectionGraph::compute_escape() {
292
294
if (noescape && ptn->scalar_replaceable ()) {
293
295
adjust_scalar_replaceable_state (ptn);
294
296
if (ptn->scalar_replaceable ()) {
295
- alloc_worklist.append (ptn->ideal_node ());
297
+ jobj_worklist.push (ptn);
298
+ } else {
299
+ found_nsr_alloc = true ;
296
300
}
297
301
}
298
302
}
299
303
304
+ // Propagate NSR (Not Scalar Replaceable) state.
305
+ if (found_nsr_alloc) {
306
+ find_scalar_replaceable_allocs (jobj_worklist);
307
+ }
308
+
309
+ for (int next = 0 ; next < jobj_worklist.length (); ++next) {
310
+ JavaObjectNode* jobj = jobj_worklist.at (next);
311
+ if (jobj->scalar_replaceable ()) {
312
+ alloc_worklist.append (jobj->ideal_node ());
313
+ }
314
+ }
315
+
300
316
#ifdef ASSERT
301
317
if (VerifyConnectionGraph) {
302
318
// Verify that graph is complete - no new edges could be added or needed.
@@ -1865,15 +1881,19 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1865
1881
set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored at unknown offset" ));
1866
1882
return ;
1867
1883
}
1868
- // 2. An object is not scalar replaceable if the field into which it is
1869
- // stored has multiple bases one of which is null.
1870
- if (field->base_count () > 1 ) {
1871
- for (BaseIterator i (field); i.has_next (); i.next ()) {
1872
- PointsToNode* base = i.get ();
1873
- if (base == null_obj) {
1874
- set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with potentially null base" ));
1875
- return ;
1876
- }
1884
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
1885
+ PointsToNode* base = i.get ();
1886
+ // 2. An object is not scalar replaceable if the field into which it is
1887
+ // stored has multiple bases one of which is null.
1888
+ if ((base == null_obj) && (field->base_count () > 1 )) {
1889
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with potentially null base" ));
1890
+ return ;
1891
+ }
1892
+ // 2.5. An object is not scalar replaceable if the field into which it is
1893
+ // stored has NSR base.
1894
+ if (!base->scalar_replaceable ()) {
1895
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
1896
+ return ;
1877
1897
}
1878
1898
}
1879
1899
}
@@ -1963,6 +1983,36 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1963
1983
}
1964
1984
}
1965
1985
1986
+ // Propagate NSR (Not scalar replaceable) state.
1987
+ void ConnectionGraph::find_scalar_replaceable_allocs (GrowableArray<JavaObjectNode*>& jobj_worklist) {
1988
+ int jobj_length = jobj_worklist.length ();
1989
+ bool found_nsr_alloc = true ;
1990
+ while (found_nsr_alloc) {
1991
+ found_nsr_alloc = false ;
1992
+ for (int next = 0 ; next < jobj_length; ++next) {
1993
+ JavaObjectNode* jobj = jobj_worklist.at (next);
1994
+ for (UseIterator i (jobj); (jobj->scalar_replaceable () && i.has_next ()); i.next ()) {
1995
+ PointsToNode* use = i.get ();
1996
+ if (use->is_Field ()) {
1997
+ FieldNode* field = use->as_Field ();
1998
+ assert (field->is_oop () && field->scalar_replaceable (), " sanity" );
1999
+ assert (field->offset () != Type::OffsetBot, " sanity" );
2000
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
2001
+ PointsToNode* base = i.get ();
2002
+ // An object is not scalar replaceable if the field into which
2003
+ // it is stored has NSR base.
2004
+ if ((base != null_obj) && !base->scalar_replaceable ()) {
2005
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
2006
+ found_nsr_alloc = true ;
2007
+ break ;
2008
+ }
2009
+ }
2010
+ }
2011
+ }
2012
+ }
2013
+ }
2014
+ }
2015
+
1966
2016
#ifdef ASSERT
1967
2017
void ConnectionGraph::verify_connection_graph (
1968
2018
GrowableArray<PointsToNode*>& ptnodes_worklist,
0 commit comments