diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index 6bca2aa644e55..dc3eecd57917e 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 cc553a39f89ba..8385aaa6560e1 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 @@ private DirectHotSpotObjectConstantImpl(Object object, boolean compressed) { @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 7c6d94bba999a..0becdf299765d 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 boolean isCompressed() { 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 ee4cb7bb397d0..e0ae6b4c881f3 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 @@ 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 b819eaf748448..358441d0b2282 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 @@ static MetaspaceObject getMetaspaceObject(Constant constant) { 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 @@ public boolean isCompressed() { 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 @@ public Constant compress() { @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 443673a8783bc..e4a77daf0d448 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 @@ public boolean isCompressed() { 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 33c6fde3b1880..fe268e9047662 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 @@ static void clearHandle(long handle) { @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); }