1 /*
   2  * Copyright (c) 2009, 2017, 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 jdk.vm.ci.hotspot;
  24 
  25 import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
  26 
  27 import java.lang.invoke.CallSite;
  28 import java.lang.invoke.ConstantCallSite;
  29 import java.lang.invoke.MethodHandle;
  30 
  31 import jdk.vm.ci.meta.Assumptions;
  32 import jdk.vm.ci.meta.Constant;
  33 import jdk.vm.ci.meta.JavaConstant;
  34 import jdk.vm.ci.meta.JavaKind;
  35 import jdk.vm.ci.meta.ResolvedJavaType;
  36 
  37 /**
  38  * Represents a constant non-{@code null} object reference, within the compiler and across the
  39  * compiler/runtime interface.
  40  */
  41 class HotSpotObjectConstantImpl implements HotSpotObjectConstant {
  42 
  43     static JavaConstant forObject(Object object) {
  44         return forObject(object, false);
  45     }
  46 
  47     static JavaConstant forObject(Object object, boolean compressed) {
  48         if (object == null) {
  49             return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER;
  50         } else {
  51             return new HotSpotObjectConstantImpl(object, compressed);
  52         }
  53     }
  54 
  55     public static JavaConstant forBoxedValue(JavaKind kind, Object value) {
  56         if (kind == JavaKind.Object) {
  57             return HotSpotObjectConstantImpl.forObject(value);
  58         } else {
  59             return JavaConstant.forBoxedPrimitive(value);
  60         }
  61     }
  62 
  63     static Object asBoxedValue(Constant constant) {
  64         if (JavaConstant.isNull(constant)) {
  65             return null;
  66         } else if (constant instanceof HotSpotObjectConstantImpl) {
  67             return ((HotSpotObjectConstantImpl) constant).object;
  68         } else {
  69             return ((JavaConstant) constant).asBoxedPrimitive();
  70         }
  71     }
  72 
  73     private final Object object;
  74     private final boolean compressed;
  75 
  76     protected HotSpotObjectConstantImpl(Object object, boolean compressed) {
  77         this.object = object;
  78         this.compressed = compressed;
  79         assert object != null;
  80     }
  81 
  82     @Override
  83     public JavaKind getJavaKind() {
  84         return JavaKind.Object;
  85     }
  86 
  87     /**
  88      * Package-private accessor for the object represented by this constant.
  89      */
  90     Object object() {
  91         return object;
  92     }
  93 
  94     @Override
  95     public boolean isCompressed() {
  96         return compressed;
  97     }
  98 
  99     @Override
 100     public JavaConstant compress() {
 101         assert !compressed;
 102         return new HotSpotObjectConstantImpl(object, true);
 103     }
 104 
 105     @Override
 106     public JavaConstant uncompress() {
 107         assert compressed;
 108         return new HotSpotObjectConstantImpl(object, false);
 109     }
 110 
 111     @Override
 112     public HotSpotResolvedObjectType getType() {
 113         return fromObjectClass(object.getClass());
 114     }
 115 
 116     @Override
 117     public int getIdentityHashCode() {
 118         return System.identityHashCode(object);
 119     }
 120 
 121     @Override
 122     public JavaConstant getCallSiteTarget(Assumptions assumptions) {
 123         if (object instanceof CallSite) {
 124             CallSite callSite = (CallSite) object;
 125             MethodHandle target = callSite.getTarget();
 126             JavaConstant targetConstant = HotSpotObjectConstantImpl.forObject(target);
 127             if (!(callSite instanceof ConstantCallSite)) {
 128                 if (assumptions == null) {
 129                     return null;
 130                 }
 131                 assumptions.record(new Assumptions.CallSiteTargetValue(this, targetConstant));
 132             }
 133 
 134             return targetConstant;
 135         }
 136         return null;
 137     }
 138 
 139     @Override
 140     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want")
 141     public boolean isInternedString() {
 142         if (object instanceof String) {
 143             String s = (String) object;
 144             return s.intern() == s;
 145         }
 146         return false;
 147     }
 148 
 149     @Override
 150     public <T> T asObject(Class<T> type) {
 151         if (type.isInstance(object)) {
 152             return type.cast(object);
 153         }
 154         return null;
 155     }
 156 
 157     @Override
 158     public Object asObject(ResolvedJavaType type) {
 159         if (type.isInstance(this)) {
 160             return object;
 161         }
 162         return null;
 163     }
 164 
 165     @Override
 166     public boolean isNull() {
 167         return false;
 168     }
 169 
 170     @Override
 171     public boolean isDefaultForKind() {
 172         return false;
 173     }
 174 
 175     @Override
 176     public Object asBoxedPrimitive() {
 177         throw new IllegalArgumentException();
 178     }
 179 
 180     @Override
 181     public int asInt() {
 182         throw new IllegalArgumentException();
 183     }
 184 
 185     @Override
 186     public boolean asBoolean() {
 187         throw new IllegalArgumentException();
 188     }
 189 
 190     @Override
 191     public long asLong() {
 192         throw new IllegalArgumentException();
 193     }
 194 
 195     @Override
 196     public float asFloat() {
 197         throw new IllegalArgumentException();
 198     }
 199 
 200     @Override
 201     public double asDouble() {
 202         throw new IllegalArgumentException();
 203     }
 204 
 205     @Override
 206     public int hashCode() {
 207         return System.identityHashCode(object);
 208     }
 209 
 210     @Override
 211     public boolean equals(Object o) {
 212         if (o == this) {
 213             return true;
 214         } else if (o instanceof HotSpotObjectConstantImpl) {
 215             HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o;
 216             return object == other.object && compressed == other.compressed;
 217         }
 218         return false;
 219     }
 220 
 221     @Override
 222     public String toValueString() {
 223         if (object instanceof String) {
 224             return "\"" + (String) object + "\"";
 225         } else {
 226             return JavaKind.Object.format(object);
 227         }
 228     }
 229 
 230     @Override
 231     public String toString() {
 232         return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + JavaKind.Object.format(object) + "]";
 233     }
 234 }