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