# HG changeset patch # User Lukas Stadler # Date 1398694904 -7200 # Node ID 89ff116d89566adf348aa383738d01f353aa2908 # Parent 2a83d2482625b32f31d4075dc64e567e1f3171c5 PEA: only merge objects at phi if this phi is the only reference diff -r 2a83d2482625 -r 89ff116d8956 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Apr 29 00:05:30 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Apr 28 16:21:44 2014 +0200 @@ -579,15 +579,29 @@ } else { // all inputs are virtual: check if they're compatible and without identity boolean compatible = true; + boolean hasIdentity = false; ObjectState firstObj = objStates[0]; for (int i = 0; i < objStates.length; i++) { ObjectState obj = objStates[i]; - boolean hasIdentity = obj.virtual.hasIdentity() && mergedVirtualObjects.contains(obj.virtual); - if (hasIdentity || !firstObj.virtual.type().equals(obj.virtual.type()) || firstObj.virtual.entryCount() != obj.virtual.entryCount() || !firstObj.locksEqual(obj)) { + hasIdentity |= obj.virtual.hasIdentity(); + boolean identitySurvives = obj.virtual.hasIdentity() && mergedVirtualObjects.contains(obj.virtual); + if (identitySurvives || !firstObj.virtual.type().equals(obj.virtual.type()) || firstObj.virtual.entryCount() != obj.virtual.entryCount() || !firstObj.locksEqual(obj)) { compatible = false; break; } } + if (compatible && hasIdentity) { + // we still need to check whether this value is referenced by any other phi + outer: for (PhiNode otherPhi : merge.phis().filter(otherPhi -> otherPhi != phi)) { + for (int i = 0; i < objStates.length; i++) { + ObjectState otherPhiValueState = getObjectState(states.get(i), otherPhi.valueAt(i)); + if (Arrays.asList(objStates).contains(otherPhiValueState)) { + compatible = false; + break outer; + } + } + } + } if (compatible) { VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual);