001/* 002 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.virtual.phases.ea; 024 025import static com.oracle.graal.compiler.common.GraalOptions.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.meta.*; 030 031import com.oracle.graal.graph.*; 032import com.oracle.graal.graph.spi.*; 033import com.oracle.graal.nodes.*; 034import com.oracle.graal.nodes.calc.*; 035import com.oracle.graal.nodes.java.*; 036import com.oracle.graal.nodes.spi.*; 037import com.oracle.graal.nodes.virtual.*; 038 039class VirtualizerToolImpl implements VirtualizerTool, CanonicalizerTool { 040 041 private final MetaAccessProvider metaAccess; 042 private final ConstantReflectionProvider constantReflection; 043 private final PartialEscapeClosure<?> closure; 044 045 VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, PartialEscapeClosure<?> closure) { 046 this.metaAccess = metaAccess; 047 this.constantReflection = constantReflection; 048 this.closure = closure; 049 } 050 051 private boolean deleted; 052 private PartialEscapeBlockState<?> state; 053 private ValueNode current; 054 private FixedNode position; 055 private GraphEffectList effects; 056 057 @Override 058 public MetaAccessProvider getMetaAccessProvider() { 059 return metaAccess; 060 } 061 062 public ConstantReflectionProvider getConstantReflectionProvider() { 063 return constantReflection; 064 } 065 066 public void reset(PartialEscapeBlockState<?> newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) { 067 deleted = false; 068 state = newState; 069 current = newCurrent; 070 position = newPosition; 071 effects = newEffects; 072 } 073 074 public boolean isDeleted() { 075 return deleted; 076 } 077 078 @Override 079 public ValueNode getAlias(ValueNode value) { 080 return closure.getAliasAndResolve(state, value); 081 } 082 083 public ValueNode getEntry(VirtualObjectNode virtualObject, int index) { 084 return state.getObjectState(virtualObject).getEntry(index); 085 } 086 087 @Override 088 public void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, boolean unsafe) { 089 ObjectState obj = state.getObjectState(virtual); 090 assert obj.isVirtual() : "not virtual: " + obj; 091 ValueNode newValue; 092 if (value == null) { 093 newValue = null; 094 } else { 095 newValue = closure.getAliasAndResolve(state, value); 096 assert unsafe || obj.getEntry(index) == null || obj.getEntry(index).getKind() == newValue.getKind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue)); 097 } 098 state.setEntry(virtual.getObjectId(), index, newValue); 099 } 100 101 public void setEnsureVirtualized(VirtualObjectNode virtualObject, boolean ensureVirtualized) { 102 int id = virtualObject.getObjectId(); 103 state.setEnsureVirtualized(id, ensureVirtualized); 104 } 105 106 public boolean getEnsureVirtualized(VirtualObjectNode virtualObject) { 107 return state.getObjectState(virtualObject).getEnsureVirtualized(); 108 } 109 110 private static boolean isObjectEntry(ValueNode value) { 111 return value.getKind() == Kind.Object || value instanceof VirtualObjectNode; 112 } 113 114 @Override 115 public void replaceWithVirtual(VirtualObjectNode virtual) { 116 closure.addAndMarkAlias(virtual, current); 117 effects.deleteNode(current); 118 deleted = true; 119 } 120 121 @Override 122 public void replaceWithValue(ValueNode replacement) { 123 effects.replaceAtUsages(current, closure.getScalarAlias(replacement)); 124 closure.addScalarAlias(current, replacement); 125 deleted = true; 126 } 127 128 @Override 129 public void delete() { 130 effects.deleteNode(current); 131 deleted = true; 132 } 133 134 @Override 135 public void replaceFirstInput(Node oldInput, Node replacement) { 136 effects.replaceFirstInput(current, oldInput, replacement); 137 } 138 139 @Override 140 public void addNode(ValueNode node) { 141 if (node instanceof FloatingNode) { 142 effects.addFloatingNode(node, "VirtualizerTool"); 143 } else { 144 effects.addFixedNodeBefore((FixedWithNextNode) node, position); 145 } 146 } 147 148 @Override 149 public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, List<MonitorIdNode> locks, boolean ensureVirtualized) { 150 VirtualUtil.trace("{{%s}} ", current); 151 if (!virtualObject.isAlive()) { 152 effects.addFloatingNode(virtualObject, "newVirtualObject"); 153 } 154 for (int i = 0; i < entryState.length; i++) { 155 ValueNode entry = entryState[i]; 156 entryState[i] = entry instanceof VirtualObjectNode ? entry : closure.getAliasAndResolve(state, entry); 157 } 158 int id = virtualObject.getObjectId(); 159 if (id == -1) { 160 id = closure.virtualObjects.size(); 161 closure.virtualObjects.add(virtualObject); 162 virtualObject.setObjectId(id); 163 } 164 state.addObject(id, new ObjectState(entryState, locks, ensureVirtualized)); 165 closure.addAndMarkAlias(virtualObject, virtualObject); 166 PartialEscapeClosure.METRIC_ALLOCATION_REMOVED.increment(); 167 } 168 169 @Override 170 public int getMaximumEntryCount() { 171 return MaximumEscapeAnalysisArrayLength.getValue(); 172 } 173 174 @Override 175 public void replaceWith(ValueNode node) { 176 if (node instanceof VirtualObjectNode) { 177 replaceWithVirtual((VirtualObjectNode) node); 178 } else { 179 replaceWithValue(node); 180 } 181 } 182 183 public void addLock(VirtualObjectNode virtualObject, MonitorIdNode monitorId) { 184 int id = virtualObject.getObjectId(); 185 state.addLock(id, monitorId); 186 } 187 188 public MonitorIdNode removeLock(VirtualObjectNode virtualObject) { 189 int id = virtualObject.getObjectId(); 190 return state.removeLock(id); 191 } 192 193 public MetaAccessProvider getMetaAccess() { 194 return metaAccess; 195 } 196 197 public ConstantReflectionProvider getConstantReflection() { 198 return constantReflection; 199 } 200 201 public boolean canonicalizeReads() { 202 return false; 203 } 204 205 @Override 206 public boolean allUsagesAvailable() { 207 return true; 208 } 209}