@@ -240,7 +240,9 @@ bool ConnectionGraph::compute_escape() {
240
240
// 3. Adjust scalar_replaceable state of nonescaping objects and push
241
241
// scalar replaceable allocations on alloc_worklist for processing
242
242
// in split_unique_types().
243
+ GrowableArray<JavaObjectNode*> jobj_worklist;
243
244
int non_escaped_length = non_escaped_allocs_worklist.length ();
245
+ bool found_nsr_alloc = false ;
244
246
for (int next = 0 ; next < non_escaped_length; next++) {
245
247
JavaObjectNode* ptn = non_escaped_allocs_worklist.at (next);
246
248
bool noescape = (ptn->escape_state () == PointsToNode::NoEscape);
@@ -251,11 +253,25 @@ bool ConnectionGraph::compute_escape() {
251
253
if (noescape && ptn->scalar_replaceable ()) {
252
254
adjust_scalar_replaceable_state (ptn);
253
255
if (ptn->scalar_replaceable ()) {
254
- alloc_worklist.append (ptn->ideal_node ());
256
+ jobj_worklist.push (ptn);
257
+ } else {
258
+ found_nsr_alloc = true ;
255
259
}
256
260
}
257
261
}
258
262
263
+ // Propagate NSR (Not Scalar Replaceable) state.
264
+ if (found_nsr_alloc) {
265
+ find_scalar_replaceable_allocs (jobj_worklist);
266
+ }
267
+
268
+ for (int next = 0 ; next < jobj_worklist.length (); ++next) {
269
+ JavaObjectNode* jobj = jobj_worklist.at (next);
270
+ if (jobj->scalar_replaceable ()) {
271
+ alloc_worklist.append (jobj->ideal_node ());
272
+ }
273
+ }
274
+
259
275
#ifdef ASSERT
260
276
if (VerifyConnectionGraph) {
261
277
// Verify that graph is complete - no new edges could be added or needed.
@@ -1840,15 +1856,19 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1840
1856
jobj->set_scalar_replaceable (false );
1841
1857
return ;
1842
1858
}
1843
- // 2. An object is not scalar replaceable if the field into which it is
1844
- // stored has multiple bases one of which is null.
1845
- if (field->base_count () > 1 ) {
1846
- for (BaseIterator i (field); i.has_next (); i.next ()) {
1847
- PointsToNode* base = i.get ();
1848
- if (base == null_obj) {
1849
- jobj->set_scalar_replaceable (false );
1850
- return ;
1851
- }
1859
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
1860
+ PointsToNode* base = i.get ();
1861
+ // 2. An object is not scalar replaceable if the field into which it is
1862
+ // stored has multiple bases one of which is null.
1863
+ if ((base == null_obj) && (field->base_count () > 1 )) {
1864
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with potentially null base" ));
1865
+ return ;
1866
+ }
1867
+ // 2.5. An object is not scalar replaceable if the field into which it is
1868
+ // stored has NSR base.
1869
+ if (!base->scalar_replaceable ()) {
1870
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
1871
+ return ;
1852
1872
}
1853
1873
}
1854
1874
}
@@ -1938,6 +1958,36 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1938
1958
}
1939
1959
}
1940
1960
1961
+ // Propagate NSR (Not scalar replaceable) state.
1962
+ void ConnectionGraph::find_scalar_replaceable_allocs (GrowableArray<JavaObjectNode*>& jobj_worklist) {
1963
+ int jobj_length = jobj_worklist.length ();
1964
+ bool found_nsr_alloc = true ;
1965
+ while (found_nsr_alloc) {
1966
+ found_nsr_alloc = false ;
1967
+ for (int next = 0 ; next < jobj_length; ++next) {
1968
+ JavaObjectNode* jobj = jobj_worklist.at (next);
1969
+ for (UseIterator i (jobj); (jobj->scalar_replaceable () && i.has_next ()); i.next ()) {
1970
+ PointsToNode* use = i.get ();
1971
+ if (use->is_Field ()) {
1972
+ FieldNode* field = use->as_Field ();
1973
+ assert (field->is_oop () && field->scalar_replaceable (), " sanity" );
1974
+ assert (field->offset () != Type::OffsetBot, " sanity" );
1975
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
1976
+ PointsToNode* base = i.get ();
1977
+ // An object is not scalar replaceable if the field into which
1978
+ // it is stored has NSR base.
1979
+ if ((base != null_obj) && !base->scalar_replaceable ()) {
1980
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
1981
+ found_nsr_alloc = true ;
1982
+ break ;
1983
+ }
1984
+ }
1985
+ }
1986
+ }
1987
+ }
1988
+ }
1989
+ }
1990
+
1941
1991
#ifdef ASSERT
1942
1992
void ConnectionGraph::verify_connection_graph (
1943
1993
GrowableArray<PointsToNode*>& ptnodes_worklist,
0 commit comments