diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index 6bca2aa644e..dc3eecd5791 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -343,6 +343,7 @@ narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section int index = _oop_recorder->find_index(klass); section->relocate(dest, metadata_Relocation::spec(index)); JVMCI_event_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string()); + guarantee(CompressedKlassPointers::is_encodable(klass), "klass cannot be compressed: %s", klass->external_name()); return CompressedKlassPointers::encode(klass); } #endif diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java index cc553a39f89..8385aaa6560 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java @@ -51,13 +51,17 @@ final class DirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { @Override public JavaConstant compress() { - assert !compressed; + if (compressed) { + throw new IllegalArgumentException("already compressed: " + this); + } return new DirectHotSpotObjectConstantImpl(object, true); } @Override public JavaConstant uncompress() { - assert compressed; + if (!compressed) { + throw new IllegalArgumentException("not compressed: " + this); + } return new DirectHotSpotObjectConstantImpl(object, false); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java index 7c6d94bba99..0becdf29976 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java @@ -51,9 +51,14 @@ public final class HotSpotCompressedNullConstant implements JavaConstant, HotSpo return true; } + @Override + public boolean isCompressible() { + return false; + } + @Override public Constant compress() { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("not compressible"); } @Override diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java index ee4cb7bb397..e0ae6b4c881 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstant.java @@ -25,13 +25,34 @@ package jdk.vm.ci.hotspot; import jdk.vm.ci.meta.Constant; /** - * Marker interface for hotspot specific constants. + * A value in a space managed by Hotspot (e.g. heap or metaspace). + * Some of these values can be referenced with a compressed pointer + * instead of a full word-sized pointer. */ public interface HotSpotConstant extends Constant { + /** + * Determines if this constant is compressed. + */ boolean isCompressed(); + /** + * Determines if this constant is compressible. + */ + boolean isCompressible(); + + /** + * Gets a compressed version of this uncompressed constant. + * + * @throws IllegalArgumentException if this constant is not compressible + */ Constant compress(); + /** + * Gets an uncompressed version of this compressed constant. + * + * @throws IllegalArgumentException if this is an uncompressed constant + * or this constant is not compressible + */ Constant uncompress(); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java index b819eaf7484..358441d0b22 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java @@ -43,6 +43,9 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM private HotSpotMetaspaceConstantImpl(MetaspaceObject metaspaceObject, boolean compressed) { this.metaspaceObject = metaspaceObject; this.compressed = compressed; + if (compressed && !canBeStoredInCompressibleMetaSpace()) { + throw new IllegalArgumentException("constant cannot be compressed: " + metaspaceObject); + } } @Override @@ -83,9 +86,28 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM return compressed; } + @Override + public boolean isCompressible() { + if (compressed) { + return false; + } + return canBeStoredInCompressibleMetaSpace(); + } + + private boolean canBeStoredInCompressibleMetaSpace() { + if (metaspaceObject instanceof HotSpotResolvedJavaType t && !t.isArray()) { + // As of JDK-8338526, interface and abstract types are not stored + // in compressible metaspace. + return !t.isInterface() && !t.isAbstract(); + } + return true; + } + @Override public Constant compress() { - assert !isCompressed(); + if (compressed) { + throw new IllegalArgumentException("already compressed: " + this); + } HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true); assert res.isCompressed(); return res; @@ -93,7 +115,9 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM @Override public Constant uncompress() { - assert isCompressed(); + if (!compressed) { + throw new IllegalArgumentException("not compressed: " + this); + } HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false); assert !res.isCompressed(); return res; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java index 443673a8783..e4a77daf0d4 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java @@ -52,6 +52,11 @@ abstract class HotSpotObjectConstantImpl implements HotSpotObjectConstant { return compressed; } + @Override + public boolean isCompressible() { + return !compressed; + } + @Override public abstract JavaConstant compress(); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java index 33c6fde3b18..fe268e90476 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java @@ -164,13 +164,17 @@ final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl @Override public JavaConstant compress() { - assert !compressed; + if (compressed) { + throw new IllegalArgumentException("already compressed: " + this); + } return new IndirectHotSpotObjectConstantImpl(this, true); } @Override public JavaConstant uncompress() { - assert compressed; + if (!compressed) { + throw new IllegalArgumentException("not compressed: " + this); + } return new IndirectHotSpotObjectConstantImpl(this, false); }