8212931: HeapMonitorStatIntervalTest.java fails due average calculation
authorjcbeyler
Fri, 16 Nov 2018 19:27:21 -0800
changeset 52597 3cda8fed1524
parent 52596 dfa02b3f728c
child 52598 0379b618ec46
8212931: HeapMonitorStatIntervalTest.java fails due average calculation Summary: Added a method to get the actual size Reviewed-by: amenkov, sspitsyn
test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitor.java
test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java
test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/libHeapMonitorTest.c
--- a/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitor.java	Fri Nov 16 16:10:25 2018 -0800
+++ b/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitor.java	Fri Nov 16 19:27:21 2018 -0800
@@ -103,43 +103,41 @@
     return sum;
   }
 
-  private static double averageOneElementSize;
-  private static native double getAverageSize();
+  private static long oneElementSize;
+  private static native long getSize(Frame[] frames, boolean checkLines);
+  private static long getSize(Frame[] frames) {
+    return getSize(frames, getCheckLines());
+  }
 
-  // Calculate the size of a 1-element array in order to assess average sampling interval
-  // via the HeapMonitorStatIntervalTest. This is needed because various GCs could add
-  // extra memory to arrays.
+  // Calculate the size of a 1-element array in order to assess sampling interval
+  // via the HeapMonitorStatIntervalTest.
   // This is done by allocating a 1-element array and then looking in the heap monitoring
-  // samples for the average size of objects collected.
-  public static void calculateAverageOneElementSize() {
+  // samples for the size of an object collected.
+  public static void calculateOneElementSize() {
     enableSamplingEvents();
-    // Assume a size of 24 for the average size.
-    averageOneElementSize = 24;
 
-    // Call allocateSize once, this allocates the internal array for the iterations.
-    int totalSize = 10 * 1024 * 1024;
-    allocateSize(totalSize);
-
-    // Reset the storage and now really track the size of the elements.
-    resetEventStorage();
-    allocateSize(totalSize);
+    List<Frame> frameList = allocate();
     disableSamplingEvents();
 
-    // Get the actual average size.
-    averageOneElementSize = getAverageSize();
-    if (averageOneElementSize == 0) {
-      throw new RuntimeException("Could not calculate the average size of a 1-element array.");
+    frameList.add(new Frame("calculateOneElementSize", "()V", "HeapMonitor.java", 119));
+    Frame[] frames = frameList.toArray(new Frame[0]);
+
+    // Get the actual size.
+    oneElementSize = getSize(frames);
+    System.out.println("Element size is: " + oneElementSize);
+
+    if (oneElementSize == 0) {
+      throw new RuntimeException("Could get the size of a 1-element array.");
     }
   }
 
   public static int allocateSize(int totalSize) {
-    if (averageOneElementSize == 0) {
-      throw new RuntimeException("Average size of a 1-element array was not calculated.");
+    if (oneElementSize == 0) {
+      throw new RuntimeException("Size of a 1-element array was not calculated.");
     }
 
     int sum = 0;
-
-    int iterations = (int) (totalSize / averageOneElementSize);
+    int iterations = (int) (totalSize / oneElementSize);
 
     if (arrays == null || arrays.length < iterations) {
       arrays = new int[iterations][];
@@ -200,7 +198,7 @@
 
     List<Frame> frameList = allocate();
     frameList.add(new Frame("allocateAndCheckFrames", "()[LMyPackage/Frame;", "HeapMonitor.java",
-          201));
+          199));
     Frame[] frames = frameList.toArray(new Frame[0]);
 
     if (!obtainedEvents(frames) && !garbageContains(frames)) {
--- a/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java	Fri Nov 16 16:10:25 2018 -0800
+++ b/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java	Fri Nov 16 19:27:21 2018 -0800
@@ -58,6 +58,9 @@
     double errorPercentage = error / expectedCount * 100;
 
     boolean success = (errorPercentage < 10.0);
+    System.out.println("Interval: " + interval + ", throw if failure: " + throwIfFailure
+        + " - Expected count: " + expectedCount + ", allocationIterations: " + allocationIterations
+        + ", actualCount: " + actualCount + " -> " + success);
 
     if (!success && throwIfFailure) {
       throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
@@ -82,7 +85,7 @@
   public static void main(String[] args) {
     int[] tab = {1024, 8192};
 
-    HeapMonitor.calculateAverageOneElementSize();
+    HeapMonitor.calculateOneElementSize();
 
     for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
       testInterval(tab[intervalIdx]);
--- a/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/libHeapMonitorTest.c	Fri Nov 16 16:10:25 2018 -0800
+++ b/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/libHeapMonitorTest.c	Fri Nov 16 19:27:21 2018 -0800
@@ -502,6 +502,27 @@
   return FALSE;
 }
 
+static jlong event_storage_get_size(JNIEnv* env,
+                                    EventStorage* storage,
+                                    ExpectedContentFrame* frames,
+                                    size_t size,
+                                    jboolean check_lines) {
+  int i;
+  event_storage_lock(storage);
+  fprintf(stderr, "Getting element from storage count, size %d\n", storage->live_object_count);
+  for (i = 0; i < storage->live_object_count; i++) {
+    ObjectTrace* trace = storage->live_objects[i];
+
+    if (check_sample_content(env, trace, frames, size, check_lines, PRINT_OUT)) {
+      jlong result = trace->size;
+      event_storage_unlock(storage);
+      return result;
+    }
+  }
+  event_storage_unlock(storage);
+  return 0;
+}
+
 static jboolean event_storage_garbage_contains(JNIEnv* env,
                                                EventStorage* storage,
                                                ExpectedContentFrame* frames,
@@ -968,30 +989,41 @@
               "Garbage Collection Finish");
 }
 
+static ExpectedContentFrame *get_native_frames(JNIEnv* env, jclass cls,
+                                               jobjectArray frames) {
+  ExpectedContentFrame *native_frames;
+  jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
+
+  if (JNI_ENV_PTR(env)->ExceptionOccurred(JNI_ENV_ARG(env))) {
+    JNI_ENV_PTR(env)->FatalError(
+        JNI_ENV_ARG2(env, "get_native_frames failed with the GetArrayLength call"));
+  }
+
+  native_frames = malloc(size * sizeof(*native_frames));
+
+  if (native_frames == NULL) {
+    JNI_ENV_PTR(env)->FatalError(
+        JNI_ENV_ARG2(env,
+                     "Error in get_native_frames: malloc returned NULL\n"));
+  }
+
+  if (fill_native_frames(env, frames, native_frames, size) != 0) {
+    JNI_ENV_PTR(env)->FatalError(
+        JNI_ENV_ARG2(env,
+                     "Error in get_native_frames: fill_native_frames returned failed status\n"));
+  }
+
+  return native_frames;
+}
+
 JNIEXPORT jboolean JNICALL
 Java_MyPackage_HeapMonitor_obtainedEvents(JNIEnv* env, jclass cls,
                                           jobjectArray frames,
                                           jboolean check_lines) {
   jboolean result;
   jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
-  ExpectedContentFrame *native_frames;
-
-  if (JNI_ENV_PTR(env)->ExceptionOccurred(JNI_ENV_ARG(env))) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "obtainedEvents failed with the GetArrayLength call"));
-  }
-
-  native_frames = malloc(size * sizeof(*native_frames));
+  ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
 
-  if (native_frames == NULL) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "Error in obtainedEvents: malloc returned NULL for native_frames allocation\n"));
-  }
-
-  if (fill_native_frames(env, frames, native_frames, size) != 0) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "Error in obtainedEvents: fill_native_frames returned failed status\n"));
-  }
   result = event_storage_contains(env, &global_event_storage, native_frames,
                                   size, check_lines);
 
@@ -1005,24 +1037,8 @@
                                            jboolean check_lines) {
   jboolean result;
   jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
-  ExpectedContentFrame *native_frames;
-
-  if (JNI_ENV_PTR(env)->ExceptionOccurred(JNI_ENV_ARG(env))) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "garbageContains failed with the GetArrayLength call"));
-  }
-
-  native_frames = malloc(size * sizeof(*native_frames));
+  ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
 
-  if (native_frames == NULL) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "Error in garbageContains: malloc returned NULL for native_frames allocation\n"));
-  }
-
-  if (fill_native_frames(env, frames, native_frames, size) != 0) {
-    JNI_ENV_PTR(env)->FatalError(
-        JNI_ENV_ARG2(env, "Error in garbageContains: fill_native_frames returned failed status\n"));
-  }
   result = event_storage_garbage_contains(env, &global_event_storage,
                                           native_frames, size, check_lines);
 
@@ -1030,6 +1046,21 @@
   return result;
 }
 
+JNIEXPORT jlong JNICALL
+Java_MyPackage_HeapMonitor_getSize(JNIEnv* env, jclass cls,
+                                   jobjectArray frames,
+                                   jboolean check_lines) {
+  jlong result = 0;
+  jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
+  ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
+
+  result = event_storage_get_size(env, &global_event_storage,
+                                  native_frames, size, check_lines);
+
+  free(native_frames), native_frames = NULL;
+  return result;
+}
+
 JNIEXPORT void JNICALL
 Java_MyPackage_HeapMonitor_forceGarbageCollection(JNIEnv* env, jclass cls) {
   check_error((*jvmti)->ForceGarbageCollection(jvmti),