9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.core.gen; 24 25 import java.util.ArrayDeque; 26 import java.util.Arrays; 27 import java.util.Queue; 28 29 import org.graalvm.compiler.debug.Debug; 30 import org.graalvm.compiler.debug.DebugCounter; 31 import org.graalvm.compiler.debug.GraalError; 32 import org.graalvm.compiler.lir.ConstantValue; 33 import org.graalvm.compiler.lir.LIRFrameState; 34 import org.graalvm.compiler.lir.LabelRef; 35 import org.graalvm.compiler.lir.Variable; 36 import org.graalvm.compiler.nodes.ConstantNode; 37 import org.graalvm.compiler.nodes.FrameState; 38 import org.graalvm.compiler.nodes.ValueNode; 39 import org.graalvm.compiler.nodes.spi.NodeValueMap; 40 import org.graalvm.compiler.nodes.util.GraphUtil; 41 import org.graalvm.compiler.nodes.virtual.EscapeObjectState; 42 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; 43 import org.graalvm.compiler.virtual.nodes.MaterializedObjectState; 44 import org.graalvm.compiler.virtual.nodes.VirtualObjectState; 45 import org.graalvm.util.Equivalence; 46 import org.graalvm.util.EconomicMap; 47 48 import jdk.vm.ci.code.BytecodeFrame; 49 import jdk.vm.ci.code.VirtualObject; 50 import jdk.vm.ci.meta.JavaConstant; 51 import jdk.vm.ci.meta.JavaKind; 52 import jdk.vm.ci.meta.JavaType; 53 import jdk.vm.ci.meta.JavaValue; 54 import jdk.vm.ci.meta.ResolvedJavaField; 55 import jdk.vm.ci.meta.ResolvedJavaType; 56 import jdk.vm.ci.meta.Value; 57 58 /** 59 * Builds {@link LIRFrameState}s from {@link FrameState}s. 60 */ 61 public class DebugInfoBuilder { 62 63 protected final NodeValueMap nodeValueMap; 64 65 public DebugInfoBuilder(NodeValueMap nodeValueMap) { 66 this.nodeValueMap = nodeValueMap; 67 } 68 69 private static final JavaValue[] NO_JAVA_VALUES = {}; 70 private static final JavaKind[] NO_JAVA_KINDS = {}; 71 72 protected final EconomicMap<VirtualObjectNode, VirtualObject> virtualObjects = EconomicMap.create(Equivalence.IDENTITY); 73 protected final EconomicMap<VirtualObjectNode, EscapeObjectState> objectStates = EconomicMap.create(Equivalence.IDENTITY); 74 75 protected final Queue<VirtualObjectNode> pendingVirtualObjects = new ArrayDeque<>(); 76 77 public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) { 78 assert virtualObjects.size() == 0; 79 assert objectStates.size() == 0; 80 assert pendingVirtualObjects.size() == 0; 81 82 // collect all VirtualObjectField instances: 83 FrameState current = topState; 84 do { 85 if (current.virtualObjectMappingCount() > 0) { 86 for (EscapeObjectState state : current.virtualObjectMappings()) { 259 } 260 261 protected void computeStack(FrameState state, int numLocals, int numStack, JavaValue[] values, JavaKind[] slotKinds) { 262 for (int i = 0; i < numStack; i++) { 263 ValueNode stack = state.stackAt(i); 264 values[numLocals + i] = toJavaValue(stack); 265 slotKinds[numLocals + i] = toSlotKind(stack); 266 } 267 } 268 269 protected void computeLocks(FrameState state, JavaValue[] values) { 270 for (int i = 0; i < state.locksSize(); i++) { 271 values[state.localsSize() + state.stackSize() + i] = computeLockValue(state, i); 272 } 273 } 274 275 protected JavaValue computeLockValue(FrameState state, int i) { 276 return toJavaValue(state.lockAt(i)); 277 } 278 279 private static final DebugCounter STATE_VIRTUAL_OBJECTS = Debug.counter("StateVirtualObjects"); 280 private static final DebugCounter STATE_ILLEGALS = Debug.counter("StateIllegals"); 281 private static final DebugCounter STATE_VARIABLES = Debug.counter("StateVariables"); 282 private static final DebugCounter STATE_CONSTANTS = Debug.counter("StateConstants"); 283 284 private static JavaKind toSlotKind(ValueNode value) { 285 if (value == null) { 286 return JavaKind.Illegal; 287 } else { 288 return value.getStackKind(); 289 } 290 } 291 292 protected JavaValue toJavaValue(ValueNode value) { 293 try { 294 if (value instanceof VirtualObjectNode) { 295 VirtualObjectNode obj = (VirtualObjectNode) value; 296 EscapeObjectState state = objectStates.get(obj); 297 if (state == null && obj.entryCount() > 0) { 298 // null states occur for objects with 0 fields 299 throw new GraalError("no mapping found for virtual object %s", obj); 300 } 301 if (state instanceof MaterializedObjectState) { 302 return toJavaValue(((MaterializedObjectState) state).materializedValue()); 303 } else { 304 assert obj.entryCount() == 0 || state instanceof VirtualObjectState; 305 VirtualObject vobject = virtualObjects.get(obj); 306 if (vobject == null) { 307 vobject = VirtualObject.get(obj.type(), virtualObjects.size()); 308 virtualObjects.put(obj, vobject); 309 pendingVirtualObjects.add(obj); 310 } 311 STATE_VIRTUAL_OBJECTS.increment(); 312 return vobject; 313 } 314 } else { 315 // Remove proxies from constants so the constant can be directly embedded. 316 ValueNode unproxied = GraphUtil.unproxify(value); 317 if (unproxied instanceof ConstantNode) { 318 STATE_CONSTANTS.increment(); 319 return unproxied.asJavaConstant(); 320 321 } else if (value != null) { 322 STATE_VARIABLES.increment(); 323 Value operand = nodeValueMap.operand(value); 324 if (operand instanceof ConstantValue && ((ConstantValue) operand).isJavaConstant()) { 325 return ((ConstantValue) operand).getJavaConstant(); 326 } else { 327 assert operand instanceof Variable : operand + " for " + value; 328 return (JavaValue) operand; 329 } 330 331 } else { 332 // return a dummy value because real value not needed 333 STATE_ILLEGALS.increment(); 334 return Value.ILLEGAL; 335 } 336 } 337 } catch (GraalError e) { 338 throw e.addContext("toValue: ", value); 339 } 340 } 341 } | 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.core.gen; 24 25 import java.util.ArrayDeque; 26 import java.util.Arrays; 27 import java.util.Queue; 28 29 import org.graalvm.compiler.debug.CounterKey; 30 import org.graalvm.compiler.debug.DebugContext; 31 import org.graalvm.compiler.debug.GraalError; 32 import org.graalvm.compiler.lir.ConstantValue; 33 import org.graalvm.compiler.lir.LIRFrameState; 34 import org.graalvm.compiler.lir.LabelRef; 35 import org.graalvm.compiler.lir.Variable; 36 import org.graalvm.compiler.nodes.ConstantNode; 37 import org.graalvm.compiler.nodes.FrameState; 38 import org.graalvm.compiler.nodes.ValueNode; 39 import org.graalvm.compiler.nodes.spi.NodeValueMap; 40 import org.graalvm.compiler.nodes.util.GraphUtil; 41 import org.graalvm.compiler.nodes.virtual.EscapeObjectState; 42 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; 43 import org.graalvm.compiler.virtual.nodes.MaterializedObjectState; 44 import org.graalvm.compiler.virtual.nodes.VirtualObjectState; 45 import org.graalvm.util.EconomicMap; 46 import org.graalvm.util.Equivalence; 47 48 import jdk.vm.ci.code.BytecodeFrame; 49 import jdk.vm.ci.code.VirtualObject; 50 import jdk.vm.ci.meta.JavaConstant; 51 import jdk.vm.ci.meta.JavaKind; 52 import jdk.vm.ci.meta.JavaType; 53 import jdk.vm.ci.meta.JavaValue; 54 import jdk.vm.ci.meta.ResolvedJavaField; 55 import jdk.vm.ci.meta.ResolvedJavaType; 56 import jdk.vm.ci.meta.Value; 57 58 /** 59 * Builds {@link LIRFrameState}s from {@link FrameState}s. 60 */ 61 public class DebugInfoBuilder { 62 63 protected final NodeValueMap nodeValueMap; 64 protected final DebugContext debug; 65 66 public DebugInfoBuilder(NodeValueMap nodeValueMap, DebugContext debug) { 67 this.nodeValueMap = nodeValueMap; 68 this.debug = debug; 69 } 70 71 private static final JavaValue[] NO_JAVA_VALUES = {}; 72 private static final JavaKind[] NO_JAVA_KINDS = {}; 73 74 protected final EconomicMap<VirtualObjectNode, VirtualObject> virtualObjects = EconomicMap.create(Equivalence.IDENTITY); 75 protected final EconomicMap<VirtualObjectNode, EscapeObjectState> objectStates = EconomicMap.create(Equivalence.IDENTITY); 76 77 protected final Queue<VirtualObjectNode> pendingVirtualObjects = new ArrayDeque<>(); 78 79 public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) { 80 assert virtualObjects.size() == 0; 81 assert objectStates.size() == 0; 82 assert pendingVirtualObjects.size() == 0; 83 84 // collect all VirtualObjectField instances: 85 FrameState current = topState; 86 do { 87 if (current.virtualObjectMappingCount() > 0) { 88 for (EscapeObjectState state : current.virtualObjectMappings()) { 261 } 262 263 protected void computeStack(FrameState state, int numLocals, int numStack, JavaValue[] values, JavaKind[] slotKinds) { 264 for (int i = 0; i < numStack; i++) { 265 ValueNode stack = state.stackAt(i); 266 values[numLocals + i] = toJavaValue(stack); 267 slotKinds[numLocals + i] = toSlotKind(stack); 268 } 269 } 270 271 protected void computeLocks(FrameState state, JavaValue[] values) { 272 for (int i = 0; i < state.locksSize(); i++) { 273 values[state.localsSize() + state.stackSize() + i] = computeLockValue(state, i); 274 } 275 } 276 277 protected JavaValue computeLockValue(FrameState state, int i) { 278 return toJavaValue(state.lockAt(i)); 279 } 280 281 private static final CounterKey STATE_VIRTUAL_OBJECTS = DebugContext.counter("StateVirtualObjects"); 282 private static final CounterKey STATE_ILLEGALS = DebugContext.counter("StateIllegals"); 283 private static final CounterKey STATE_VARIABLES = DebugContext.counter("StateVariables"); 284 private static final CounterKey STATE_CONSTANTS = DebugContext.counter("StateConstants"); 285 286 private static JavaKind toSlotKind(ValueNode value) { 287 if (value == null) { 288 return JavaKind.Illegal; 289 } else { 290 return value.getStackKind(); 291 } 292 } 293 294 protected JavaValue toJavaValue(ValueNode value) { 295 try { 296 if (value instanceof VirtualObjectNode) { 297 VirtualObjectNode obj = (VirtualObjectNode) value; 298 EscapeObjectState state = objectStates.get(obj); 299 if (state == null && obj.entryCount() > 0) { 300 // null states occur for objects with 0 fields 301 throw new GraalError("no mapping found for virtual object %s", obj); 302 } 303 if (state instanceof MaterializedObjectState) { 304 return toJavaValue(((MaterializedObjectState) state).materializedValue()); 305 } else { 306 assert obj.entryCount() == 0 || state instanceof VirtualObjectState; 307 VirtualObject vobject = virtualObjects.get(obj); 308 if (vobject == null) { 309 vobject = VirtualObject.get(obj.type(), virtualObjects.size()); 310 virtualObjects.put(obj, vobject); 311 pendingVirtualObjects.add(obj); 312 } 313 STATE_VIRTUAL_OBJECTS.increment(debug); 314 return vobject; 315 } 316 } else { 317 // Remove proxies from constants so the constant can be directly embedded. 318 ValueNode unproxied = GraphUtil.unproxify(value); 319 if (unproxied instanceof ConstantNode) { 320 STATE_CONSTANTS.increment(debug); 321 return unproxied.asJavaConstant(); 322 323 } else if (value != null) { 324 STATE_VARIABLES.increment(debug); 325 Value operand = nodeValueMap.operand(value); 326 if (operand instanceof ConstantValue && ((ConstantValue) operand).isJavaConstant()) { 327 return ((ConstantValue) operand).getJavaConstant(); 328 } else { 329 assert operand instanceof Variable : operand + " for " + value; 330 return (JavaValue) operand; 331 } 332 333 } else { 334 // return a dummy value because real value not needed 335 STATE_ILLEGALS.increment(debug); 336 return Value.ILLEGAL; 337 } 338 } 339 } catch (GraalError e) { 340 throw e.addContext("toValue: ", value); 341 } 342 } 343 } |