Mercurial > hg > truffle
view graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java @ 7530:5e3d1a68664e
applied mx eclipseformat to all Java files
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 23 Jan 2013 16:34:57 +0100 |
parents | 9c71ad0a0652 |
children | 3a8b3b03ffa0 1ceb9aeb5ea4 |
line wrap: on
line source
/* * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.graal.compiler.gen; import java.util.*; import java.util.Map.Entry; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.virtual.nodes.*; public class DebugInfoBuilder { private final NodeMap<Value> nodeOperands; public DebugInfoBuilder(NodeMap<Value> nodeOperands) { this.nodeOperands = nodeOperands; } private HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>(); private IdentityHashMap<VirtualObjectNode, EscapeObjectState> objectStates = new IdentityHashMap<>(); public LIRFrameState build(FrameState topState, List<StackSlot> lockData, List<StackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) { assert virtualObjects.size() == 0; assert objectStates.size() == 0; // collect all VirtualObjectField instances: FrameState current = topState; do { for (EscapeObjectState state : current.virtualObjectMappings()) { if (objectStates == null) { objectStates = new IdentityHashMap<>(); } if (!objectStates.containsKey(state.object())) { if (!(state instanceof MaterializedObjectState) || ((MaterializedObjectState) state).materializedValue() != state.object()) { objectStates.put(state.object(), state); } } } current = current.outerFrameState(); } while (current != null); BytecodeFrame frame = computeFrameForState(topState, lockData, leafGraphId); VirtualObject[] virtualObjectsArray = null; if (virtualObjects.size() != 0) { // fill in the VirtualObject values: // during this process new VirtualObjects might be discovered, so repeat until no more // changes occur. boolean changed; do { changed = false; IdentityHashMap<VirtualObjectNode, VirtualObject> virtualObjectsCopy = new IdentityHashMap<>(virtualObjects); for (Entry<VirtualObjectNode, VirtualObject> entry : virtualObjectsCopy.entrySet()) { if (entry.getValue().getValues() == null) { VirtualObjectNode vobj = entry.getKey(); if (vobj instanceof BoxedVirtualObjectNode) { BoxedVirtualObjectNode boxedVirtualObjectNode = (BoxedVirtualObjectNode) vobj; entry.getValue().setValues(new Value[]{toValue(boxedVirtualObjectNode.getUnboxedValue())}); } else { Value[] values = new Value[vobj.entryCount()]; if (values.length > 0) { changed = true; VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj); assert currentField != null; for (int i = 0; i < vobj.entryCount(); i++) { values[i] = toValue(currentField.fieldValues().get(i)); } } entry.getValue().setValues(values); } } } } while (changed); virtualObjectsArray = virtualObjects.values().toArray(new VirtualObject[virtualObjects.size()]); virtualObjects.clear(); } objectStates.clear(); return new LIRFrameState(frame, virtualObjectsArray, pointerSlots, exceptionEdge); } private BytecodeFrame computeFrameForState(FrameState state, List<StackSlot> lockDataSlots, long leafGraphId) { int numLocals = state.localsSize(); int numStack = state.stackSize(); int numLocks = state.locksSize(); Value[] values = new Value[numLocals + numStack + numLocks]; for (int i = 0; i < numLocals; i++) { values[i] = toValue(state.localAt(i)); } for (int i = 0; i < numStack; i++) { values[numLocals + i] = toValue(state.stackAt(i)); } for (int i = 0; i < numLocks; i++) { // frames are traversed from the outside in, so the locks for the current frame are at // the end of the lockDataSlots list StackSlot lockData = lockDataSlots.get(lockDataSlots.size() - numLocks + i); values[numLocals + numStack + i] = new MonitorValue(toValue(state.lockAt(i)), lockData, state.lockAt(i) instanceof VirtualObjectNode); } BytecodeFrame caller = null; if (state.outerFrameState() != null) { // remove the locks that were used for this frame from the lockDataSlots list List<StackSlot> nextLockDataSlots = lockDataSlots.subList(0, lockDataSlots.size() - numLocks); caller = computeFrameForState(state.outerFrameState(), nextLockDataSlots, -1); } else { if (lockDataSlots.size() != numLocks) { throw new BailoutException("unbalanced monitors: found monitor for unknown frame (%d != %d) at %s", lockDataSlots.size(), numLocks, state); } } assert state.bci >= 0 || state.bci == FrameState.BEFORE_BCI; return new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, numLocals, numStack, numLocks, leafGraphId); } private Value toValue(ValueNode value) { if (value instanceof VirtualObjectNode) { VirtualObjectNode obj = (VirtualObjectNode) value; EscapeObjectState state = objectStates.get(obj); if (state == null && obj.entryCount() > 0 && !(obj instanceof BoxedVirtualObjectNode)) { // null states occur for objects with 0 fields throw new GraalInternalError("no mapping found for virtual object %s", obj); } if (state instanceof MaterializedObjectState) { return toValue(((MaterializedObjectState) state).materializedValue()); } else { assert obj.entryCount() == 0 || state instanceof VirtualObjectState || obj instanceof BoxedVirtualObjectNode; VirtualObject vobject = virtualObjects.get(value); if (vobject == null) { vobject = VirtualObject.get(obj.type(), null, virtualObjects.size()); virtualObjects.put(obj, vobject); } Debug.metric("StateVirtualObjects").increment(); return vobject; } } else if (value instanceof ConstantNode) { Debug.metric("StateConstants").increment(); return ((ConstantNode) value).value; } else if (value != null) { Debug.metric("StateVariables").increment(); Value operand = nodeOperands.get(value); assert operand != null && (operand instanceof Variable || operand instanceof Constant) : operand + " for " + value; return operand; } else { // return a dummy value because real value not needed Debug.metric("StateIllegals").increment(); return Value.ILLEGAL; } } }