001/* 002 * Copyright (c) 2011, 2013, 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 java.util.*; 026 027import jdk.internal.jvmci.meta.*; 028 029import com.oracle.graal.compiler.common.*; 030import com.oracle.graal.nodes.*; 031import com.oracle.graal.nodes.virtual.*; 032 033public class PEReadEliminationBlockState extends PartialEscapeBlockState<PEReadEliminationBlockState> { 034 035 final HashMap<ReadCacheEntry, ValueNode> readCache; 036 037 static final class ReadCacheEntry { 038 039 public final LocationIdentity identity; 040 public final ValueNode object; 041 public final int index; 042 043 public ReadCacheEntry(LocationIdentity identity, ValueNode object, int index) { 044 this.identity = identity; 045 this.object = object; 046 this.index = index; 047 } 048 049 @Override 050 public int hashCode() { 051 int result = 31 + ((identity == null) ? 0 : identity.hashCode()); 052 result = 31 * result + ((object == null) ? 0 : object.hashCode()); 053 return result * 31 + index; 054 } 055 056 @Override 057 public boolean equals(Object obj) { 058 if (!(obj instanceof ReadCacheEntry)) { 059 return false; 060 } 061 ReadCacheEntry other = (ReadCacheEntry) obj; 062 return identity.equals(other.identity) && object == other.object; 063 } 064 065 @Override 066 public String toString() { 067 return index == -1 ? (object + ":" + identity) : (object + "[" + index + "]:" + identity); 068 } 069 } 070 071 public PEReadEliminationBlockState() { 072 readCache = CollectionsFactory.newMap(); 073 } 074 075 public PEReadEliminationBlockState(PEReadEliminationBlockState other) { 076 super(other); 077 readCache = CollectionsFactory.newMap(other.readCache); 078 } 079 080 @Override 081 public String toString() { 082 return super.toString() + " " + readCache; 083 } 084 085 @Override 086 protected void objectMaterialized(VirtualObjectNode virtual, AllocatedObjectNode representation, List<ValueNode> values) { 087 if (virtual instanceof VirtualInstanceNode) { 088 VirtualInstanceNode instance = (VirtualInstanceNode) virtual; 089 for (int i = 0; i < instance.entryCount(); i++) { 090 readCache.put(new ReadCacheEntry(instance.field(i).getLocationIdentity(), representation, -1), values.get(i)); 091 } 092 } 093 } 094 095 @Override 096 public boolean equivalentTo(PEReadEliminationBlockState other) { 097 if (!compareMapsNoSize(readCache, other.readCache)) { 098 return false; 099 } 100 return super.equivalentTo(other); 101 } 102 103 public void addReadCache(ValueNode object, LocationIdentity identity, int index, ValueNode value, PartialEscapeClosure<?> closure) { 104 ValueNode cacheObject; 105 ObjectState obj = closure.getObjectState(this, object); 106 if (obj != null) { 107 assert !obj.isVirtual(); 108 cacheObject = obj.getMaterializedValue(); 109 } else { 110 cacheObject = object; 111 } 112 readCache.put(new ReadCacheEntry(identity, cacheObject, index), value); 113 } 114 115 public ValueNode getReadCache(ValueNode object, LocationIdentity identity, int index, PartialEscapeClosure<?> closure) { 116 ValueNode cacheObject; 117 ObjectState obj = closure.getObjectState(this, object); 118 if (obj != null) { 119 assert !obj.isVirtual() : object; 120 cacheObject = obj.getMaterializedValue(); 121 } else { 122 cacheObject = object; 123 } 124 ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject, index)); 125 obj = closure.getObjectState(this, cacheValue); 126 if (obj != null) { 127 assert !obj.isVirtual(); 128 cacheValue = obj.getMaterializedValue(); 129 } else { 130 // assert !scalarAliases.containsKey(cacheValue); 131 cacheValue = closure.getScalarAlias(cacheValue); 132 } 133 return cacheValue; 134 } 135 136 public void killReadCache() { 137 readCache.clear(); 138 } 139 140 public void killReadCache(LocationIdentity identity, int index) { 141 Iterator<Map.Entry<ReadCacheEntry, ValueNode>> iter = readCache.entrySet().iterator(); 142 while (iter.hasNext()) { 143 ReadCacheEntry entry = iter.next().getKey(); 144 if (entry.identity.equals(identity) && (index == -1 || entry.index == -1 || index == entry.index)) { 145 iter.remove(); 146 } 147 } 148 } 149 150 public Map<ReadCacheEntry, ValueNode> getReadCache() { 151 return readCache; 152 } 153}