# HG changeset patch # User never # Date 1461966881 25200 # Fri Apr 29 14:54:41 2016 -0700 # Node ID 9c1249262ba68317c014885f6b0d7d2f60e851a3 # Parent c9894d44a9db35002ae5aa99e39a7a6067902d09 8155771: [JVMCI] expose JVM_ACC_IS_CLONEABLE_FAST Reviewed-by: twisti diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -882,4 +882,9 @@ public boolean isTrustedInterfaceType() { return TrustedInterface.class.isAssignableFrom(mirror()); } + + @Override + public boolean isCloneableWithAllocation() { + return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0; + } } diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java @@ -267,4 +267,9 @@ public boolean isTrustedInterfaceType() { return false; } + + @Override + public boolean isCloneableWithAllocation() { + return false; + } } diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -1077,6 +1077,7 @@ @HotSpotVMConstant(name = "JVM_ACC_FIELD_STABLE") @Stable public int jvmAccFieldStable; @HotSpotVMConstant(name = "JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE") @Stable public int jvmAccFieldHasGenericSignature; @HotSpotVMConstant(name = "JVM_ACC_WRITTEN_FLAGS") @Stable public int jvmAccWrittenFlags; + @HotSpotVMConstant(name = "JVM_ACC_IS_CLONEABLE_FAST") @Stable public int jvmAccIsCloneableFast; // Modifier.SYNTHETIC is not public so we get it via vmStructs. @HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int jvmAccSynthetic; diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java @@ -359,4 +359,12 @@ } return null; } + + /** + * Returns true if this type is {@link Cloneable} and can be safely cloned by creating a normal + * Java allocation and populating it from the fields returned by + * {@link #getInstanceFields(boolean)}. Some types may require special handling by the platform + * so they would to go through the normal {@link Object#clone} path. + */ + boolean isCloneableWithAllocation(); } diff --git a/src/share/vm/jvmci/vmStructs_jvmci.cpp b/src/share/vm/jvmci/vmStructs_jvmci.cpp --- a/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -309,6 +309,7 @@ declare_constant(JVM_ACC_MONITOR_MATCH) \ declare_constant(JVM_ACC_HAS_MONITOR_BYTECODES) \ declare_constant(JVM_ACC_HAS_FINALIZER) \ + declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ declare_constant(JVM_ACC_FIELD_INTERNAL) \ declare_constant(JVM_ACC_FIELD_STABLE) \ declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) \ diff --git a/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java --- a/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -866,6 +866,31 @@ } } + static class TrivialCloneable implements Cloneable { + @Override + protected Object clone() { + return new TrivialCloneable(); + } + } + + @Test + public void isCloneableWithAllocationTest() { + ResolvedJavaType cloneable = metaAccess.lookupJavaType(Cloneable.class); + for (Class c : classes) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + if (type.isCloneableWithAllocation()) { + // Only Cloneable types should be allocation cloneable + assertTrue(c.toString(), cloneable.isAssignableFrom(type)); + } + } + /* + * We can't know for sure which types should be allocation cloneable on a particular + * platform but assume that at least totally trivial objects should be. + */ + ResolvedJavaType trivialCloneable = metaAccess.lookupJavaType(TrivialCloneable.class); + assertTrue(trivialCloneable.toString(), trivialCloneable.isCloneableWithAllocation()); + } + @Test public void findMethodTest() { try {