1 /*
   2  * Copyright (c) 2015, 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.dfa;
  24 
  25 import org.graalvm.compiler.core.common.LIRKind;
  26 import org.graalvm.compiler.lir.LIR;
  27 import org.graalvm.compiler.lir.LIRFrameState;
  28 import org.graalvm.compiler.lir.LIRInstruction;
  29 import org.graalvm.compiler.lir.Variable;
  30 import org.graalvm.compiler.lir.framemap.FrameMap;
  31 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  32 import org.graalvm.compiler.lir.phases.AllocationPhase;
  33 import org.graalvm.compiler.lir.util.IndexedValueMap;
  34 import org.graalvm.compiler.lir.util.ValueSet;
  35 
  36 import jdk.vm.ci.code.TargetDescription;
  37 import jdk.vm.ci.meta.Value;
  38 import jdk.vm.ci.meta.ValueKind;
  39 
  40 /**
  41  * Record all derived reference base pointers in a frame state.
  42  */
  43 public final class MarkBasePointersPhase extends AllocationPhase {
  44 
  45     @Override
  46     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
  47         new Marker(lirGenRes.getLIR(), null).build();
  48     }
  49 
  50     private static final class Marker extends LocationMarker<Marker.BasePointersSet> {
  51 
  52         private final class BasePointersSet extends ValueSet<Marker.BasePointersSet> {
  53 
  54             private final IndexedValueMap variables;
  55 
  56             BasePointersSet() {
  57                 variables = new IndexedValueMap();
  58             }
  59 
  60             private BasePointersSet(BasePointersSet s) {
  61                 variables = new IndexedValueMap(s.variables);
  62             }
  63 
  64             @Override
  65             public Marker.BasePointersSet copy() {
  66                 return new BasePointersSet(this);
  67             }
  68 
  69             @Override
  70             public void put(Value v) {
  71                 Variable base = (Variable) v.getValueKind(LIRKind.class).getDerivedReferenceBase();
  72                 assert !base.getValueKind(LIRKind.class).isValue();
  73                 variables.put(base.index, base);
  74             }
  75 
  76             @Override
  77             public void putAll(BasePointersSet v) {
  78                 variables.putAll(v.variables);
  79             }
  80 
  81             @Override
  82             public void remove(Value v) {
  83                 Variable base = (Variable) v.getValueKind(LIRKind.class).getDerivedReferenceBase();
  84                 assert !base.getValueKind(LIRKind.class).isValue();
  85                 variables.put(base.index, null);
  86             }
  87 
  88             @Override
  89             public boolean equals(Object obj) {
  90                 if (obj instanceof Marker.BasePointersSet) {
  91                     BasePointersSet other = (BasePointersSet) obj;
  92                     return variables.equals(other.variables);
  93                 } else {
  94                     return false;
  95                 }
  96             }
  97 
  98             @Override
  99             public int hashCode() {
 100                 throw new UnsupportedOperationException();
 101             }
 102         }
 103 
 104         private Marker(LIR lir, FrameMap frameMap) {
 105             super(lir, frameMap);
 106         }
 107 
 108         @Override
 109         protected Marker.BasePointersSet newLiveValueSet() {
 110             return new BasePointersSet();
 111         }
 112 
 113         @Override
 114         protected boolean shouldProcessValue(Value operand) {
 115             ValueKind<?> kind = operand.getValueKind();
 116             if (kind instanceof LIRKind) {
 117                 return ((LIRKind) kind).isDerivedReference();
 118             } else {
 119                 return false;
 120             }
 121         }
 122 
 123         @Override
 124         protected void processState(LIRInstruction op, LIRFrameState info, BasePointersSet values) {
 125             info.setLiveBasePointers(new IndexedValueMap(values.variables));
 126         }
 127     }
 128 }