PEReadEliminationBlockState.java revision 13083:b9a173f12fe6
1/*
2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
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 */
23package org.graalvm.compiler.virtual.phases.ea;
24
25import java.util.Iterator;
26import java.util.List;
27
28import org.graalvm.api.word.LocationIdentity;
29import org.graalvm.compiler.nodes.FieldLocationIdentity;
30import org.graalvm.compiler.nodes.ValueNode;
31import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
32import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
33import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
34import org.graalvm.compiler.options.OptionValues;
35import org.graalvm.util.EconomicMap;
36import org.graalvm.util.Equivalence;
37
38public final class PEReadEliminationBlockState extends PartialEscapeBlockState<PEReadEliminationBlockState> {
39
40    final EconomicMap<ReadCacheEntry, ValueNode> readCache;
41
42    static final class ReadCacheEntry {
43
44        public final LocationIdentity identity;
45        public final ValueNode object;
46        public final int index;
47
48        ReadCacheEntry(LocationIdentity identity, ValueNode object, int index) {
49            this.identity = identity;
50            this.object = object;
51            this.index = index;
52        }
53
54        @Override
55        public int hashCode() {
56            int result = 31 + ((identity == null) ? 0 : identity.hashCode());
57            result = 31 * result + ((object == null) ? 0 : System.identityHashCode(object));
58            return result * 31 + index;
59        }
60
61        @Override
62        public boolean equals(Object obj) {
63            if (!(obj instanceof ReadCacheEntry)) {
64                return false;
65            }
66            ReadCacheEntry other = (ReadCacheEntry) obj;
67            return identity.equals(other.identity) && object == other.object && index == other.index;
68        }
69
70        @Override
71        public String toString() {
72            return index == -1 ? (object + ":" + identity) : (object + "[" + index + "]:" + identity);
73        }
74    }
75
76    public PEReadEliminationBlockState(OptionValues options) {
77        super(options);
78        readCache = EconomicMap.create(Equivalence.DEFAULT);
79    }
80
81    public PEReadEliminationBlockState(PEReadEliminationBlockState other) {
82        super(other);
83        readCache = EconomicMap.create(Equivalence.DEFAULT, other.readCache);
84    }
85
86    @Override
87    public String toString() {
88        return super.toString() + " " + readCache;
89    }
90
91    @Override
92    protected void objectMaterialized(VirtualObjectNode virtual, AllocatedObjectNode representation, List<ValueNode> values) {
93        if (virtual instanceof VirtualInstanceNode) {
94            VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
95            for (int i = 0; i < instance.entryCount(); i++) {
96                readCache.put(new ReadCacheEntry(new FieldLocationIdentity(instance.field(i)), representation, -1), values.get(i));
97            }
98        }
99    }
100
101    @Override
102    public boolean equivalentTo(PEReadEliminationBlockState other) {
103        if (!isSubMapOf(readCache, other.readCache)) {
104            return false;
105        }
106        return super.equivalentTo(other);
107    }
108
109    public void addReadCache(ValueNode object, LocationIdentity identity, int index, ValueNode value, PartialEscapeClosure<?> closure) {
110        ValueNode cacheObject;
111        ObjectState obj = closure.getObjectState(this, object);
112        if (obj != null) {
113            assert !obj.isVirtual();
114            cacheObject = obj.getMaterializedValue();
115        } else {
116            cacheObject = object;
117        }
118        readCache.put(new ReadCacheEntry(identity, cacheObject, index), value);
119    }
120
121    public ValueNode getReadCache(ValueNode object, LocationIdentity identity, int index, PartialEscapeClosure<?> closure) {
122        ValueNode cacheObject;
123        ObjectState obj = closure.getObjectState(this, object);
124        if (obj != null) {
125            assert !obj.isVirtual() : object;
126            cacheObject = obj.getMaterializedValue();
127        } else {
128            cacheObject = object;
129        }
130        ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject, index));
131        obj = closure.getObjectState(this, cacheValue);
132        if (obj != null) {
133            assert !obj.isVirtual();
134            cacheValue = obj.getMaterializedValue();
135        } else {
136            // assert !scalarAliases.containsKey(cacheValue);
137            cacheValue = closure.getScalarAlias(cacheValue);
138        }
139        return cacheValue;
140    }
141
142    public void killReadCache() {
143        readCache.clear();
144    }
145
146    public void killReadCache(LocationIdentity identity, int index) {
147        Iterator<ReadCacheEntry> iter = readCache.getKeys().iterator();
148        while (iter.hasNext()) {
149            ReadCacheEntry entry = iter.next();
150            if (entry.identity.equals(identity) && (index == -1 || entry.index == -1 || index == entry.index)) {
151                iter.remove();
152            }
153        }
154    }
155
156    public EconomicMap<ReadCacheEntry, ValueNode> getReadCache() {
157        return readCache;
158    }
159}
160