1 /*
  2  * Copyright (c) 2014, 2025, 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 java.util.Objects;
 26 
 27 import jdk.vm.ci.meta.Constant;
 28 import jdk.vm.ci.meta.VMConstant;
 29 
 30 final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant {
 31 
 32     static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceObject metaspaceObject, boolean compressed) {
 33         return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
 34     }
 35 
 36     static MetaspaceObject getMetaspaceObject(Constant constant) {
 37         return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject;
 38     }
 39 
 40     private final MetaspaceObject metaspaceObject;
 41     private final boolean compressed;
 42 
 43     private HotSpotMetaspaceConstantImpl(MetaspaceObject metaspaceObject, boolean compressed) {
 44         this.metaspaceObject = metaspaceObject;
 45         this.compressed = compressed;
 46         if (compressed && !canBeStoredInCompressibleMetaSpace()) {
 47             throw new IllegalArgumentException("constant cannot be compressed: " + metaspaceObject);
 48         }
 49     }
 50 
 51     @Override
 52     public int hashCode() {
 53         return System.identityHashCode(metaspaceObject) ^ (compressed ? 1 : 2);
 54     }
 55 
 56     @Override
 57     public boolean equals(Object o) {
 58         if (o == this) {
 59             return true;
 60         }
 61         if (!(o instanceof HotSpotMetaspaceConstantImpl)) {
 62             return false;
 63         }
 64 
 65         HotSpotMetaspaceConstantImpl other = (HotSpotMetaspaceConstantImpl) o;
 66         return Objects.equals(this.metaspaceObject, other.metaspaceObject) && this.compressed == other.compressed;
 67     }
 68 
 69     @Override
 70     public String toValueString() {
 71         return String.format("meta{%s%s}", metaspaceObject, compressed ? ";compressed" : "");
 72     }
 73 
 74     @Override
 75     public String toString() {
 76         return toValueString();
 77     }
 78 
 79     @Override
 80     public boolean isDefaultForKind() {
 81         return false;
 82     }
 83 
 84     @Override
 85     public boolean isCompressed() {
 86         return compressed;
 87     }
 88 
 89     @Override
 90     public boolean isCompressible() {
 91         if (compressed) {
 92             return false;
 93         }
 94         return canBeStoredInCompressibleMetaSpace();
 95     }
 96 
 97     private boolean canBeStoredInCompressibleMetaSpace() {
 98         if (!HotSpotVMConfig.config().useClassMetaspaceForAllClasses && metaspaceObject instanceof HotSpotResolvedJavaType t && !t.isArray()) {
 99             // As of JDK-8338526, interface and abstract types are not stored
100             // in compressible metaspace.
101             return !t.isInterface() && !t.isAbstract();
102         }
103         return true;
104     }
105 
106     @Override
107     public Constant compress() {
108         if (compressed) {
109             throw new IllegalArgumentException("already compressed: " + this);
110         }
111         HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true);
112         assert res.isCompressed();
113         return res;
114     }
115 
116     @Override
117     public Constant uncompress() {
118         if (!compressed) {
119             throw new IllegalArgumentException("not compressed: " + this);
120         }
121         HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false);
122         assert !res.isCompressed();
123         return res;
124     }
125 
126     @Override
127     public HotSpotResolvedObjectType asResolvedJavaType() {
128         if (metaspaceObject instanceof HotSpotResolvedObjectType) {
129             return (HotSpotResolvedObjectType) metaspaceObject;
130         }
131         return null;
132     }
133 
134     @Override
135     public HotSpotResolvedJavaMethod asResolvedJavaMethod() {
136         if (metaspaceObject instanceof HotSpotResolvedJavaMethod) {
137             return (HotSpotResolvedJavaMethod) metaspaceObject;
138         }
139         return null;
140     }
141 }