diff a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -777,10 +777,16 @@ // but requires it to be linear in byte offset. return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); } UNSAFE_END +UNSAFE_ENTRY(jlong, Unsafe_GetObjectSize0(JNIEnv* env, jobject o, jobject obj)) + oop p = JNIHandles::resolve(obj); + return Universe::heap()->obj_size(p) * HeapWordSize; +UNSAFE_END + + static inline void throw_new(JNIEnv *env, const char *ename) { jclass cls = env->FindClass(ename); if (env->ExceptionCheck()) { env->ExceptionClear(); tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", ename); @@ -1238,10 +1244,11 @@ {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)}, {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)}, {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)}, {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)}, {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)}, + {CC "getObjectSize0", CC "(Ljava/lang/Object;)J", FN_PTR(Unsafe_GetObjectSize0)}, {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)}, {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)}, {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}, {CC "compareAndSetReference",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetReference)}, diff a/src/java.base/share/classes/java/util/Objects.java b/src/java.base/share/classes/java/util/Objects.java --- a/src/java.base/share/classes/java/util/Objects.java +++ b/src/java.base/share/classes/java/util/Objects.java @@ -25,10 +25,11 @@ package java.util; import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.misc.Unsafe; import java.util.function.Supplier; /** * This class consists of {@code static} utility methods for operating @@ -423,6 +424,16 @@ public static int checkFromIndexSize(int fromIndex, int size, int length) { return Preconditions.checkFromIndexSize(fromIndex, size, length, null); } + /** + * Return the size of the object in the heap. + * + * @param o an object + * @return the objects's size + * @since Valhalla + */ + public static long getObjectSize(Object o) { + return Unsafe.getUnsafe().getObjectSize(o); + } } diff a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -1332,10 +1332,21 @@ } return arrayIndexScale0(arrayClass); } + /** + * Return the size of the object in the heap. + * @param o an object + * @return the objects's size + * @since Valhalla + */ + public long getObjectSize(Object o) { + if (o == null) + throw new NullPointerException(); + return getObjectSize0(o); + } /** The value of {@code arrayIndexScale(boolean[].class)} */ public static final int ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale(boolean[].class); @@ -4186,10 +4197,11 @@ private native Object staticFieldBase0(Field f); private native boolean shouldBeInitialized0(Class c); private native void ensureClassInitialized0(Class c); private native int arrayBaseOffset0(Class arrayClass); private native int arrayIndexScale0(Class arrayClass); + private native long getObjectSize0(Object o); private native Class defineAnonymousClass0(Class hostClass, byte[] data, Object[] cpPatches); private native int getLoadAverage0(double[] loadavg, int nelems); /**