001/*
002 * Copyright (c) 2014, 2015, 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.lir.util;
024
025import java.util.*;
026
027import jdk.internal.jvmci.meta.*;
028
029import com.oracle.graal.lir.*;
030import com.oracle.graal.lir.LIRInstruction.OperandFlag;
031import com.oracle.graal.lir.LIRInstruction.OperandMode;
032
033public final class IndexedValueMap {
034    private Value[] values;
035
036    public IndexedValueMap() {
037        values = Value.NO_VALUES;
038    }
039
040    public IndexedValueMap(IndexedValueMap other) {
041        int limit = other.values.length;
042        while (limit > 0) {
043            if (other.values[limit - 1] == null) {
044                limit--;
045                continue;
046            }
047            break;
048        }
049        values = new Value[limit];
050        System.arraycopy(other.values, 0, values, 0, values.length);
051    }
052
053    public Value get(int index) {
054        return values[index];
055    }
056
057    public void put(int index, Value value) {
058        if (values.length <= index) {
059            if (value == null) {
060                return;
061            }
062            Value[] newValues = new Value[index + 1];
063            System.arraycopy(values, 0, newValues, 0, values.length);
064            values = newValues;
065            values[index] = value;
066        } else {
067            values[index] = value;
068        }
069    }
070
071    public void putAll(IndexedValueMap stack) {
072        Value[] otherValues = stack.values;
073        int limit = otherValues.length;
074        if (limit > values.length) {
075            while (limit > 0) {
076                if (otherValues[limit - 1] == null) {
077                    limit--;
078                    continue;
079                }
080                break;
081            }
082            if (limit > values.length) {
083                Value[] newValues = new Value[limit];
084                System.arraycopy(values, 0, newValues, 0, values.length);
085                values = newValues;
086            }
087        }
088        for (int i = 0; i < limit; i++) {
089            Value value = otherValues[i];
090            if (value != null) {
091                values[i] = value;
092            }
093        }
094    }
095
096    @Override
097    public boolean equals(Object other) {
098        if (other instanceof IndexedValueMap) {
099            IndexedValueMap that = (IndexedValueMap) other;
100            int limit = Math.min(values.length, that.values.length);
101            for (int i = 0; i < limit; i++) {
102                if (!Objects.equals(values[i], that.values[i])) {
103                    return false;
104                }
105            }
106            for (int i = limit; i < values.length; i++) {
107                if (values[i] != null) {
108                    return false;
109                }
110            }
111            for (int i = limit; i < that.values.length; i++) {
112                if (that.values[i] != null) {
113                    return false;
114                }
115            }
116            return true;
117        }
118        return false;
119    }
120
121    public void forEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueProcedure proc) {
122        for (int i = 0; i < values.length; i++) {
123            if (values[i] != null) {
124                values[i] = proc.doValue(inst, values[i], mode, flags);
125            }
126        }
127    }
128
129    public void forEach(LIRInstruction inst, OperandMode mode, EnumSet<OperandFlag> flags, InstructionValueConsumer consumer) {
130        for (Value v : values) {
131            if (v != null) {
132                consumer.visitValue(inst, v, mode, flags);
133            }
134        }
135    }
136
137    @Override
138    public int hashCode() {
139        throw new UnsupportedOperationException();
140    }
141
142    @Override
143    public String toString() {
144        StringBuilder sb = new StringBuilder("[");
145        boolean comma = false;
146
147        for (int i = 0; i < values.length; i++) {
148            if (values[i] != null) {
149                if (comma) {
150                    sb.append(", ");
151                } else {
152                    comma = true;
153                }
154
155                sb.append(i);
156                sb.append(": ");
157                sb.append(values[i]);
158            }
159        }
160        sb.append(']');
161        return sb.toString();
162    }
163}