test/hotspot/jtreg/vmTestbase/nsk/jvmti/IterateOverHeap/iterheap004/iterheap004.cpp
changeset 51551 e409244ce72e
parent 50260 46c67f5e27c2
child 51774 79dc492c00ab
equal deleted inserted replaced
51550:a2f1923b3e16 51551:e409244ce72e
       
     1 /*
       
     2  * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #include <string.h>
       
    25 #include "jvmti.h"
       
    26 #include "agent_common.h"
       
    27 #include "jni_tools.h"
       
    28 #include "jvmti_tools.h"
       
    29 
       
    30 #ifdef __cplusplus
       
    31 extern "C" {
       
    32 #endif
       
    33 
       
    34 static JNIEnv *jni = NULL;
       
    35 static jvmtiEnv *jvmti = NULL;
       
    36 static jvmtiCapabilities caps;
       
    37 static jlong timeout = 0;
       
    38 
       
    39 /* ============================================================================= */
       
    40 
       
    41 
       
    42 static volatile long objectDescCount = 0;
       
    43 static volatile int callbackAborted = 0;
       
    44 static volatile int numberOfDeallocatedFromCallbacksDescriptors = 0;
       
    45 
       
    46 typedef struct ObjectDescStruct {
       
    47     struct ObjectDescStruct *next;
       
    48 } ObjectDesc;
       
    49 
       
    50 static ObjectDesc* volatile objectDescList;
       
    51 static ObjectDesc* *objectDescArr;
       
    52 static unsigned char* deallocatedFlagsArr;
       
    53 
       
    54 
       
    55 /* ============================================================================= */
       
    56 
       
    57 
       
    58 /** heapRootCallback for first heap iteration. */
       
    59 jvmtiIterationControl JNICALL
       
    60 heapObjectCallbackForFirstIteration(jlong class_tag,
       
    61                    jlong size,
       
    62                    jlong* tag_ptr,
       
    63                    void* user_data) {
       
    64     ObjectDesc *objectDescBuf;
       
    65 
       
    66     /* set tag */
       
    67     *tag_ptr = (jlong)++objectDescCount;
       
    68 
       
    69     /* Allocate memory for next list element*/
       
    70     if (!NSK_JVMTI_VERIFY(
       
    71             NSK_CPP_STUB3(Allocate, jvmti, (sizeof(ObjectDesc)),
       
    72                                                (unsigned char**)&objectDescBuf))) {
       
    73         nsk_jvmti_setFailStatus();
       
    74         callbackAborted = 1;
       
    75         NSK_COMPLAIN0("heapObjectCallbackForFirstIteration: Allocation failed. Iteration aborted.\n");
       
    76         return JVMTI_ITERATION_ABORT;
       
    77     }
       
    78     objectDescBuf->next = objectDescList;
       
    79     objectDescList = objectDescBuf;
       
    80 
       
    81     return JVMTI_ITERATION_CONTINUE;
       
    82 }
       
    83 
       
    84 /** heapRootCallback for second heap iterator. */
       
    85 jvmtiIterationControl JNICALL
       
    86 heapObjectCallbackForSecondIteration(jlong class_tag,
       
    87                    jlong size,
       
    88                    jlong* tag_ptr,
       
    89                    void* user_data) {
       
    90 
       
    91     long ind = (long)((*tag_ptr) - 1);
       
    92 
       
    93     if (ind < 0 || ind > objectDescCount ) {
       
    94         NSK_COMPLAIN1("heapObjectCallbackForSecondIteration: invalid object tag value: %d\n", (long)*tag_ptr);
       
    95         nsk_jvmti_setFailStatus();
       
    96         callbackAborted = 1;
       
    97         return JVMTI_ITERATION_ABORT;
       
    98     }
       
    99 
       
   100     /* Deallocate memory of list element*/
       
   101     if (!NSK_JVMTI_VERIFY(
       
   102             NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)objectDescArr[ind]))) {
       
   103         nsk_jvmti_setFailStatus();
       
   104         callbackAborted = 1;
       
   105         NSK_COMPLAIN0("heapObjectCallbackForSecondIteration: Deallocation failed. Iteration aborted.\n");
       
   106         return JVMTI_ITERATION_ABORT;
       
   107     }
       
   108 
       
   109     numberOfDeallocatedFromCallbacksDescriptors++;
       
   110     deallocatedFlagsArr[ind] = 1;
       
   111 
       
   112     /* unset tag */
       
   113     *tag_ptr = 0;
       
   114 
       
   115     return JVMTI_ITERATION_CONTINUE;
       
   116 }
       
   117 
       
   118 /* ============================================================================= */
       
   119 
       
   120 /** Agent algorithm. */
       
   121 static void JNICALL
       
   122 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
       
   123     long ind;
       
   124     ObjectDesc *objectDesc;
       
   125     int fakeUserData = 0;
       
   126 
       
   127     NSK_DISPLAY0("Wait for debugee start\n");
       
   128     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
       
   129         return;
       
   130 
       
   131     {
       
   132         do {
       
   133             objectDescList = NULL;
       
   134 
       
   135             NSK_DISPLAY0("Calling IterateOverHeap with filter JVMTI_HEAP_OBJECT_UNTAGGED\n");
       
   136             {
       
   137                 if (!NSK_JVMTI_VERIFY(
       
   138                         NSK_CPP_STUB4(IterateOverHeap, jvmti,
       
   139                             JVMTI_HEAP_OBJECT_UNTAGGED, heapObjectCallbackForFirstIteration,
       
   140                             &fakeUserData))) {
       
   141                     nsk_jvmti_setFailStatus();
       
   142                     break;
       
   143                 }
       
   144             }
       
   145             if (callbackAborted) break;
       
   146 
       
   147             if (objectDescCount == 0) {
       
   148                 NSK_COMPLAIN0("First IterateOverHeap call had not visited any object\n");
       
   149                 nsk_jvmti_setFailStatus();
       
   150                 break;
       
   151             } else {
       
   152                 NSK_DISPLAY1("Number of objects first IterateOverHeap visited: %d\n", objectDescCount);
       
   153             }
       
   154 
       
   155             /* Allocate memory for array to save pointers to ObjectDescList elements */
       
   156             if (!NSK_JVMTI_VERIFY(
       
   157                     NSK_CPP_STUB3(Allocate, jvmti, (objectDescCount * sizeof(ObjectDesc*)),
       
   158                                       (unsigned char**)&objectDescArr))) {
       
   159                 nsk_jvmti_setFailStatus();
       
   160                 break;
       
   161             }
       
   162 
       
   163             /* Allocate memory for flags array and fill with false values */
       
   164             if (!NSK_JVMTI_VERIFY(
       
   165                     NSK_CPP_STUB3(Allocate, jvmti, (objectDescCount * sizeof(unsigned char)),
       
   166                                       &deallocatedFlagsArr))) {
       
   167                 nsk_jvmti_setFailStatus();
       
   168                 break;
       
   169             }
       
   170 
       
   171             for (ind = 0; ind < objectDescCount; ind++) {
       
   172                 deallocatedFlagsArr[ind] = 0;
       
   173             }
       
   174 
       
   175             /* Save all pointers to ObjectDescList elements in objectDescArr */
       
   176             objectDesc = objectDescList;
       
   177             for (ind = 0; ind < objectDescCount; ind++) {
       
   178                 objectDescArr[ind] = objectDesc;
       
   179                 objectDesc = objectDesc->next;
       
   180             }
       
   181 
       
   182             /* Verify objectDescCount and objectDescList length in agreement */
       
   183             if (!NSK_VERIFY(objectDesc == NULL)) {
       
   184                nsk_jvmti_setFailStatus();
       
   185                break;
       
   186             }
       
   187 
       
   188             NSK_DISPLAY0("Calling IterateOverHeap with filter JVMTI_HEAP_OBJECT_TAGGED\n");
       
   189             {
       
   190                 if (!NSK_JVMTI_VERIFY(
       
   191                         NSK_CPP_STUB4(IterateOverHeap, jvmti,
       
   192                             JVMTI_HEAP_OBJECT_TAGGED, heapObjectCallbackForSecondIteration,
       
   193                             &fakeUserData))) {
       
   194                     nsk_jvmti_setFailStatus();
       
   195                 }
       
   196             }
       
   197 
       
   198             if (numberOfDeallocatedFromCallbacksDescriptors == 0) {
       
   199                 NSK_COMPLAIN1("Deallocate func. hasn't been called from IterateOverHeap'callback. "
       
   200                         "numberOfDeallocatedFromCallbacksDescriptors = %d\n", numberOfDeallocatedFromCallbacksDescriptors);
       
   201                 nsk_jvmti_setFailStatus();
       
   202             }
       
   203 
       
   204             for (ind = 0; ind < objectDescCount; ind++) {
       
   205                 if (!deallocatedFlagsArr[ind]) {
       
   206                     if (!NSK_JVMTI_VERIFY(
       
   207                            NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)objectDescArr[ind]))) {
       
   208                         NSK_COMPLAIN1("Unable to deallocate descriptor. Index = %d \n", ind);
       
   209                         nsk_jvmti_setFailStatus();
       
   210                         return;
       
   211                     }
       
   212                 }
       
   213             }
       
   214 
       
   215             if (!NSK_JVMTI_VERIFY(
       
   216                     NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)objectDescArr))) {
       
   217                 nsk_jvmti_setFailStatus();
       
   218             }
       
   219 
       
   220          if (!NSK_JVMTI_VERIFY(
       
   221                     NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)deallocatedFlagsArr))) {
       
   222                 nsk_jvmti_setFailStatus();
       
   223          }
       
   224 
       
   225         } while (0);
       
   226     }
       
   227 
       
   228     NSK_DISPLAY0("Let debugee to finish\n");
       
   229     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
       
   230         return;
       
   231 }
       
   232 
       
   233 /* ============================================================================= */
       
   234 
       
   235 /* ============================================================================= */
       
   236 
       
   237 /** Agent library initialization. */
       
   238 #ifdef STATIC_BUILD
       
   239 JNIEXPORT jint JNICALL Agent_OnLoad_iterheap004(JavaVM *jvm, char *options, void *reserved) {
       
   240     return Agent_Initialize(jvm, options, reserved);
       
   241 }
       
   242 JNIEXPORT jint JNICALL Agent_OnAttach_iterheap004(JavaVM *jvm, char *options, void *reserved) {
       
   243     return Agent_Initialize(jvm, options, reserved);
       
   244 }
       
   245 JNIEXPORT jint JNI_OnLoad_iterheap004(JavaVM *jvm, char *options, void *reserved) {
       
   246     return JNI_VERSION_1_8;
       
   247 }
       
   248 #endif
       
   249 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
       
   250 
       
   251     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
       
   252         return JNI_ERR;
       
   253 
       
   254     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
       
   255 
       
   256     if (!NSK_VERIFY((jvmti =
       
   257             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
       
   258         return JNI_ERR;
       
   259 
       
   260     memset(&caps, 0, sizeof(caps));
       
   261     caps.can_tag_objects = 1;
       
   262     if (!NSK_JVMTI_VERIFY(
       
   263             NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
       
   264         return JNI_ERR;
       
   265     }
       
   266 
       
   267     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities,
       
   268             jvmti, &caps)))
       
   269         return JNI_ERR;
       
   270 
       
   271     if (!caps.can_tag_objects)
       
   272         NSK_DISPLAY0("Warning: tagging objects is not available\n");
       
   273 
       
   274     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
       
   275         return JNI_ERR;
       
   276 
       
   277     return JNI_OK;
       
   278 }
       
   279 
       
   280 /* ============================================================================= */
       
   281 
       
   282 #ifdef __cplusplus
       
   283 }
       
   284 #endif