1 /*
2  * Copyright (c) 2014, 2018, 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  */
23 
24 
25 package org.graalvm.compiler.lir.util;
26 
27 import java.util.EnumSet;
28 import java.util.Objects;
29 
30 import org.graalvm.compiler.lir.InstructionValueConsumer;
31 import org.graalvm.compiler.lir.InstructionValueProcedure;
32 import org.graalvm.compiler.lir.LIRInstruction;
33 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
34 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
35 
36 import jdk.vm.ci.meta.Value;
37 
38 public final class IndexedValueMap {
39     private Value[] values;
40 
IndexedValueMap()41     public IndexedValueMap() {
42         values = Value.NO_VALUES;
43     }
44 
IndexedValueMap(IndexedValueMap other)45     public IndexedValueMap(IndexedValueMap other) {
46         int limit = other.values.length;
47         while (limit > 0) {
48             if (other.values[limit - 1] == null) {
49                 limit--;
50                 continue;
51             }
52             break;
53         }
54         if (limit == 0) {
55             values = Value.NO_VALUES;
56         } else {
57             values = new Value[limit];
58             System.arraycopy(other.values, 0, values, 0, values.length);
59         }
60     }
61 
get(int index)62     public Value get(int index) {
63         return values[index];
64     }
65 
put(int index, Value value)66     public void put(int index, Value value) {
67         if (values.length <= index) {
68             if (value == null) {
69                 return;
70             }
71             Value[] newValues = new Value[index + 1];
72             if (values.length > 0) {
73                 System.arraycopy(values, 0, newValues, 0, values.length);
74             }
75             values = newValues;
76             values[index] = value;
77         } else {
78             values[index] = value;
79         }
80     }
81 
putAll(IndexedValueMap stack)82     public void putAll(IndexedValueMap stack) {
83         Value[] otherValues = stack.values;
84         int limit = otherValues.length;
85         if (limit > values.length) {
86             while (limit > 0) {
87                 if (otherValues[limit - 1] == null) {
88                     limit--;
89                     continue;
90                 }
91                 break;
92             }
93             if (limit > values.length) {
94                 Value[] newValues = new Value[limit];
95                 System.arraycopy(values, 0, newValues, 0, values.length);
96                 values = newValues;
97             }
98         }
99         for (int i = 0; i < limit; i++) {
100             Value value = otherValues[i];
101             if (value != null) {
102                 values[i] = value;
103             }
104         }
105     }
106 
107     @Override
equals(Object other)108     public boolean equals(Object other) {
109         if (other instanceof IndexedValueMap) {
110             IndexedValueMap that = (IndexedValueMap) other;
111             int limit = Math.min(values.length, that.values.length);
112             for (int i = 0; i < limit; i++) {
113                 if (!Objects.equals(values[i], that.values[i])) {
114                     return false;
115                 }
116             }
117             for (int i = limit; i < values.length; i++) {
118                 if (values[i] != null) {
119                     return false;
120                 }
121             }
122             for (int i = limit; i < that.values.length; i++) {
123                 if (that.values[i] != null) {
124                     return false;
125                 }
126             }
127             return true;
128         }
129         return false;
130     }
131 
forEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueProcedure proc)132     public void forEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueProcedure proc) {
133         for (int i = 0; i < values.length; i++) {
134             if (values[i] != null) {
135                 values[i] = proc.doValue(inst, values[i], mode, flags);
136             }
137         }
138     }
139 
visitEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueConsumer consumer)140     public void visitEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueConsumer consumer) {
141         for (Value v : values) {
142             if (v != null) {
143                 consumer.visitValue(inst, v, mode, flags);
144             }
145         }
146     }
147 
148     @Override
hashCode()149     public int hashCode() {
150         throw new UnsupportedOperationException();
151     }
152 
153     @Override
toString()154     public String toString() {
155         StringBuilder sb = new StringBuilder("[");
156         boolean comma = false;
157 
158         for (int i = 0; i < values.length; i++) {
159             if (values[i] != null) {
160                 if (comma) {
161                     sb.append(", ");
162                 } else {
163                     comma = true;
164                 }
165 
166                 sb.append(i);
167                 sb.append(": ");
168                 sb.append(values[i]);
169             }
170         }
171         sb.append(']');
172         return sb.toString();
173     }
174 }
175