Mercurial > hg > truffle
view graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.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 | 94f032472c28 |
children | 17b6a63fe7c2 |
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.virtual.phases.ea; import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.MergeableBlockState; import com.oracle.graal.virtual.nodes.*; class BlockState extends MergeableBlockState<BlockState> { private final HashMap<VirtualObjectNode, ObjectState> objectStates = new HashMap<>(); private final HashMap<ValueNode, VirtualObjectNode> objectAliases = new HashMap<>(); private final HashMap<ValueNode, ValueNode> scalarAliases = new HashMap<>(); public BlockState() { } public BlockState(BlockState other) { for (Map.Entry<VirtualObjectNode, ObjectState> entry : other.objectStates.entrySet()) { objectStates.put(entry.getKey(), entry.getValue().cloneState()); } for (Map.Entry<ValueNode, VirtualObjectNode> entry : other.objectAliases.entrySet()) { objectAliases.put(entry.getKey(), entry.getValue()); } for (Map.Entry<ValueNode, ValueNode> entry : other.scalarAliases.entrySet()) { scalarAliases.put(entry.getKey(), entry.getValue()); } } public ObjectState getObjectState(VirtualObjectNode object) { assert objectStates.containsKey(object); return objectStates.get(object); } public ObjectState getObjectStateOptional(VirtualObjectNode object) { return objectStates.get(object); } public ObjectState getObjectState(ValueNode value) { VirtualObjectNode object = objectAliases.get(value); return object == null ? null : getObjectState(object); } @Override public BlockState cloneState() { return new BlockState(this); } public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); HashSet<VirtualObjectNode> deferred = new HashSet<>(); GraphEffectList deferredStores = new GraphEffectList(); materializeChangedBefore(fixed, virtual, state, deferred, deferredStores, materializeEffects); materializeEffects.addAll(deferredStores); } private void materializeChangedBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, HashSet<VirtualObjectNode> deferred, GraphEffectList deferredStores, GraphEffectList materializeEffects) { trace("materializing %s at %s", virtual, fixed); ObjectState obj = getObjectState(virtual); if (obj.getLockCount() > 0 && obj.virtual.type().isArray()) { throw new BailoutException("array materialized with lock"); } ValueNode[] fieldState = obj.getEntries(); // determine if all entries are default constants boolean allDefault = true; for (int i = 0; i < fieldState.length; i++) { if (!fieldState[i].isConstant() || !fieldState[i].asConstant().isDefaultForKind()) { allDefault = false; break; } } if (allDefault && obj.getLockCount() == 0) { // create an ordinary NewInstance/NewArray node if all entries are default constants FixedWithNextNode newObject; if (virtual instanceof VirtualInstanceNode) { newObject = new NewInstanceNode(virtual.type(), true, false); } else { assert virtual instanceof VirtualArrayNode; ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); if (element.getKind() == Kind.Object) { newObject = new NewObjectArrayNode(element, ConstantNode.forInt(virtual.entryCount(), fixed.graph()), true, false); } else { newObject = new NewPrimitiveArrayNode(element, ConstantNode.forInt(virtual.entryCount(), fixed.graph()), true, false); } } newObject.setProbability(fixed.probability()); obj.escape(newObject, state); materializeEffects.addFixedNodeBefore(newObject, fixed); } else { // some entries are not default constants - do the materialization virtual.materializeAt(fixed); MaterializeObjectNode materialize = new MaterializeObjectNode(virtual, obj.getLockCount()); ValueNode[] values = new ValueNode[obj.getEntries().length]; materialize.setProbability(fixed.probability()); obj.escape(materialize, state); deferred.add(virtual); for (int i = 0; i < fieldState.length; i++) { ObjectState valueObj = getObjectState(fieldState[i]); if (valueObj != null) { if (valueObj.isVirtual()) { materializeChangedBefore(fixed, valueObj.virtual, state, deferred, deferredStores, materializeEffects); } if (deferred.contains(valueObj.virtual)) { Kind fieldKind; CyclicMaterializeStoreNode store; if (virtual instanceof VirtualArrayNode) { store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), i); fieldKind = ((VirtualArrayNode) virtual).componentType().getKind(); } else { VirtualInstanceNode instanceObject = (VirtualInstanceNode) virtual; store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), instanceObject.field(i)); fieldKind = instanceObject.field(i).getType().getKind(); } deferredStores.addFixedNodeBefore(store, fixed); values[i] = ConstantNode.defaultForKind(fieldKind, fixed.graph()); } else { values[i] = valueObj.getMaterializedValue(); } } else { values[i] = fieldState[i]; } } deferred.remove(virtual); materializeEffects.addMaterialization(materialize, fixed, values); } } void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) { objectAliases.put(node, virtual); if (node.isAlive()) { for (Node usage : node.usages()) { markVirtualUsages(usage, usages); } } } private void markVirtualUsages(Node node, NodeBitMap usages) { if (!usages.isNew(node)) { usages.mark(node); } if (node instanceof VirtualState) { for (Node usage : node.usages()) { markVirtualUsages(usage, usages); } } } public void addObject(VirtualObjectNode virtual, ObjectState state) { objectStates.put(virtual, state); } public void addScalarAlias(ValueNode alias, ValueNode value) { scalarAliases.put(alias, value); } public ValueNode getScalarAlias(ValueNode alias) { ValueNode result = scalarAliases.get(alias); return result == null ? alias : result; } public Iterable<ObjectState> getStates() { return objectStates.values(); } public Iterable<VirtualObjectNode> getVirtualObjects() { return objectAliases.values(); } @Override public String toString() { return objectStates.toString(); } public static BlockState meetAliases(List<BlockState> states) { BlockState newState = new BlockState(); newState.objectAliases.putAll(states.get(0).objectAliases); for (int i = 1; i < states.size(); i++) { BlockState state = states.get(i); for (Map.Entry<ValueNode, VirtualObjectNode> entry : states.get(0).objectAliases.entrySet()) { if (state.objectAliases.containsKey(entry.getKey())) { assert state.objectAliases.get(entry.getKey()) == entry.getValue(); } else { newState.objectAliases.remove(entry.getKey()); } } } newState.scalarAliases.putAll(states.get(0).scalarAliases); for (int i = 1; i < states.size(); i++) { BlockState state = states.get(i); for (Map.Entry<ValueNode, ValueNode> entry : states.get(0).scalarAliases.entrySet()) { if (state.scalarAliases.containsKey(entry.getKey())) { assert state.scalarAliases.get(entry.getKey()) == entry.getValue(); } else { newState.scalarAliases.remove(entry.getKey()); } } } return newState; } }