@@ -242,7 +242,9 @@ bool ConnectionGraph::compute_escape() {
242
242
// 3. Adjust scalar_replaceable state of nonescaping objects and push
243
243
// scalar replaceable allocations on alloc_worklist for processing
244
244
// in split_unique_types().
245
+ GrowableArray<JavaObjectNode*> jobj_worklist;
245
246
int non_escaped_length = non_escaped_worklist.length ();
247
+ bool found_nsr_alloc = false ;
246
248
for (int next = 0 ; next < non_escaped_length; next++) {
247
249
JavaObjectNode* ptn = non_escaped_worklist.at (next);
248
250
bool noescape = (ptn->escape_state () == PointsToNode::NoEscape);
@@ -256,11 +258,25 @@ bool ConnectionGraph::compute_escape() {
256
258
if (noescape && ptn->scalar_replaceable ()) {
257
259
adjust_scalar_replaceable_state (ptn);
258
260
if (ptn->scalar_replaceable ()) {
259
- alloc_worklist.append (ptn->ideal_node ());
261
+ jobj_worklist.push (ptn);
262
+ } else {
263
+ found_nsr_alloc = true ;
260
264
}
261
265
}
262
266
}
263
267
268
+ // Propagate NSR (Not Scalar Replaceable) state.
269
+ if (found_nsr_alloc) {
270
+ find_scalar_replaceable_allocs (jobj_worklist);
271
+ }
272
+
273
+ for (int next = 0 ; next < jobj_worklist.length (); ++next) {
274
+ JavaObjectNode* jobj = jobj_worklist.at (next);
275
+ if (jobj->scalar_replaceable ()) {
276
+ alloc_worklist.append (jobj->ideal_node ());
277
+ }
278
+ }
279
+
264
280
#ifdef ASSERT
265
281
if (VerifyConnectionGraph) {
266
282
// Verify that graph is complete - no new edges could be added or needed.
@@ -1759,15 +1775,19 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1759
1775
jobj->set_scalar_replaceable (false );
1760
1776
return ;
1761
1777
}
1762
- // 2. An object is not scalar replaceable if the field into which it is
1763
- // stored has multiple bases one of which is null.
1764
- if (field->base_count () > 1 ) {
1765
- for (BaseIterator i (field); i.has_next (); i.next ()) {
1766
- PointsToNode* base = i.get ();
1767
- if (base == null_obj) {
1768
- jobj->set_scalar_replaceable (false );
1769
- return ;
1770
- }
1778
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
1779
+ PointsToNode* base = i.get ();
1780
+ // 2. An object is not scalar replaceable if the field into which it is
1781
+ // stored has multiple bases one of which is null.
1782
+ if ((base == null_obj) && (field->base_count () > 1 )) {
1783
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with potentially null base" ));
1784
+ return ;
1785
+ }
1786
+ // 2.5. An object is not scalar replaceable if the field into which it is
1787
+ // stored has NSR base.
1788
+ if (!base->scalar_replaceable ()) {
1789
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
1790
+ return ;
1771
1791
}
1772
1792
}
1773
1793
}
@@ -1857,6 +1877,36 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
1857
1877
}
1858
1878
}
1859
1879
1880
+ // Propagate NSR (Not scalar replaceable) state.
1881
+ void ConnectionGraph::find_scalar_replaceable_allocs (GrowableArray<JavaObjectNode*>& jobj_worklist) {
1882
+ int jobj_length = jobj_worklist.length ();
1883
+ bool found_nsr_alloc = true ;
1884
+ while (found_nsr_alloc) {
1885
+ found_nsr_alloc = false ;
1886
+ for (int next = 0 ; next < jobj_length; ++next) {
1887
+ JavaObjectNode* jobj = jobj_worklist.at (next);
1888
+ for (UseIterator i (jobj); (jobj->scalar_replaceable () && i.has_next ()); i.next ()) {
1889
+ PointsToNode* use = i.get ();
1890
+ if (use->is_Field ()) {
1891
+ FieldNode* field = use->as_Field ();
1892
+ assert (field->is_oop () && field->scalar_replaceable (), " sanity" );
1893
+ assert (field->offset () != Type::OffsetBot, " sanity" );
1894
+ for (BaseIterator i (field); i.has_next (); i.next ()) {
1895
+ PointsToNode* base = i.get ();
1896
+ // An object is not scalar replaceable if the field into which
1897
+ // it is stored has NSR base.
1898
+ if ((base != null_obj) && !base->scalar_replaceable ()) {
1899
+ set_not_scalar_replaceable (jobj NOT_PRODUCT (COMMA " is stored into field with NSR base" ));
1900
+ found_nsr_alloc = true ;
1901
+ break ;
1902
+ }
1903
+ }
1904
+ }
1905
+ }
1906
+ }
1907
+ }
1908
+ }
1909
+
1860
1910
#ifdef ASSERT
1861
1911
void ConnectionGraph::verify_connection_graph (
1862
1912
GrowableArray<PointsToNode*>& ptnodes_worklist,
0 commit comments