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 <stdio.h>
  25 #include <string.h>
  26 #include <jvmti.h>
  27 #include "agent_common.h"
  28 
  29 #include "nsk_tools.h"
  30 #include "jni_tools.h"
  31 #include "JVMTITools.h"
  32 #include "jvmti_tools.h"
  33 
  34 extern "C" {
  35 
  36 #define OBJ_MAX_COUNT 100000
  37 
  38 static JNIEnv *jni = NULL;
  39 static jvmtiEnv *jvmti = NULL;
  40 static jvmtiEventCallbacks callbacks;
  41 static jvmtiCapabilities caps;
  42 
  43 static jlong timeout = 0;
  44 
  45 static const char* DEBUGEE_SIGNATURE = "Lnsk/jvmti/scenarios/allocation/AP04/ap04t003;";
  46 static const char* ROOT_SIGNATURE    = "[Lnsk/jvmti/scenarios/allocation/AP04/ap04t003;";
  47 
  48 static jclass debugeeClass = NULL;
  49 static jfieldID rootFieldID;
  50 
  51 static jrawMonitorID startLock = NULL;
  52 static jrawMonitorID runLock = NULL;
  53 static jrawMonitorID endLock = NULL;
  54 
  55 static volatile int iterationCount = 0;
  56 static volatile int objectCount = 0;
  57 
  58 /***********************************************************************/
  59 
  60 static jrawMonitorID counterMonitor_ptr = NULL;
  61 
  62 static void increaseCounter(volatile int* counterPtr) {
  63 
  64     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(counterMonitor_ptr))) {
  65         nsk_jvmti_setFailStatus();
  66     }
  67 
  68     (*counterPtr)++;
  69 
  70     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(counterMonitor_ptr))) {
  71         nsk_jvmti_setFailStatus();
  72     }
  73 }
  74 
  75 static void setCounter(volatile int* counterPtr, int value) {
  76 
  77     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(counterMonitor_ptr))) {
  78         nsk_jvmti_setFailStatus();
  79     }
  80 
  81     *counterPtr = value;
  82 
  83     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(counterMonitor_ptr))) {
  84         nsk_jvmti_setFailStatus();
  85     }
  86 }
  87 
  88 static int getCounter(volatile int* counterPtr) {
  89     int result;
  90 
  91     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(counterMonitor_ptr))) {
  92         nsk_jvmti_setFailStatus();
  93     }
  94 
  95     result = *counterPtr;
  96 
  97     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(counterMonitor_ptr))) {
  98         nsk_jvmti_setFailStatus();
  99     }
 100 
 101     return result;
 102 }
 103 
 104 /***********************************************************************/
 105 
 106 void notifyThread() {
 107 
 108     /* enter and notify runLock */
 109     {
 110         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(runLock))) {
 111             nsk_jvmti_setFailStatus();
 112         }
 113         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorNotify(runLock))) {
 114             nsk_jvmti_setFailStatus();
 115         }
 116         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(runLock))) {
 117             nsk_jvmti_setFailStatus();
 118         }
 119     }
 120 }
 121 
 122 jvmtiIterationControl JNICALL
 123 heapObjectCallback(jlong  class_tag,
 124                    jlong  size,
 125                    jlong* tag_ptr,
 126                    void*  user_data) {
 127 
 128     if (getCounter(&iterationCount) == 0) {
 129         notifyThread();
 130     }
 131     increaseCounter(&iterationCount);
 132 
 133     if (*tag_ptr > 0) {
 134         increaseCounter(&objectCount);
 135     }
 136 
 137     return JVMTI_ITERATION_CONTINUE;
 138 }
 139 
 140 /* jvmtiHeapRootCallback */
 141 jvmtiIterationControl JNICALL
 142 heapRootCallback(jvmtiHeapRootKind root_kind,
 143                  jlong class_tag,
 144                  jlong size,
 145                  jlong* tag_ptr,
 146                  void* user_data) {
 147 
 148     if (getCounter(&iterationCount) == 0) {
 149         notifyThread();
 150     }
 151     increaseCounter(&iterationCount);
 152 
 153     if (*tag_ptr > 0) {
 154         increaseCounter(&objectCount);
 155     }
 156 
 157     return JVMTI_ITERATION_CONTINUE;
 158 }
 159 
 160 /* jvmtiStackReferenceCallback */
 161 jvmtiIterationControl JNICALL
 162 stackReferenceCallback(jvmtiHeapRootKind root_kind,
 163                        jlong     class_tag,
 164                        jlong     size,
 165                        jlong*    tag_ptr,
 166                        jlong     thread_tag,
 167                        jint      depth,
 168                        jmethodID method,
 169                        jint      slot,
 170                        void*     user_data) {
 171 
 172     if (getCounter(&iterationCount) == 0) {
 173         notifyThread();
 174     }
 175     increaseCounter(&iterationCount);
 176 
 177     if (*tag_ptr > 0) {
 178         increaseCounter(&objectCount);
 179     }
 180 
 181     return JVMTI_ITERATION_CONTINUE;
 182 }
 183 
 184 
 185 /* jvmtiObjectReferenceCallback */
 186 jvmtiIterationControl JNICALL
 187 objectReferenceCallback(jvmtiObjectReferenceKind reference_kind,
 188                         jlong  class_tag,
 189                         jlong  size,
 190                         jlong* tag_ptr,
 191                         jlong  referrer_tag,
 192                         jint   referrer_index,
 193                         void*  user_data) {
 194 
 195     if (getCounter(&iterationCount) == 0) {
 196         notifyThread();
 197     }
 198     increaseCounter(&iterationCount);
 199 
 200     if (*tag_ptr > 0) {
 201         increaseCounter(&objectCount);
 202     }
 203 
 204     return JVMTI_ITERATION_CONTINUE;
 205 }
 206 
 207 /********* Agent thread modifying tags of objects ************/
 208 
 209 /** Body of new agent thread: modify tags of tagged object. */
 210 void JNICALL agent_start(jvmtiEnv* jvmti, JNIEnv* jni, void *p) {
 211 
 212     jint taggedObjectsCount = 0;
 213     jobject* taggedObjectsList = NULL;
 214 
 215     NSK_DISPLAY0("Agent thread: started.\n");
 216 
 217     /* obtain tagged objects list */
 218     {
 219         jlong tag = (jlong)1;
 220 
 221         if (!NSK_JVMTI_VERIFY(jvmti->GetObjectsWithTags(
 222                 1, &tag, &taggedObjectsCount, &taggedObjectsList, NULL))) {
 223             nsk_jvmti_setFailStatus();
 224             return;
 225         }
 226     }
 227 
 228     NSK_DISPLAY1("Agent thread: got tagged objects: %d\n", (int)taggedObjectsCount);
 229 
 230     if (!NSK_VERIFY(taggedObjectsCount == OBJ_MAX_COUNT)) {
 231         nsk_jvmti_setFailStatus();
 232         return;
 233     }
 234 
 235     /* enter runLock */
 236     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(runLock))) {
 237         nsk_jvmti_setFailStatus();
 238     }
 239 
 240     /* enter and notify startLock */
 241     {
 242         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(startLock))) {
 243             nsk_jvmti_setFailStatus();
 244         }
 245         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorNotify(startLock))) {
 246             nsk_jvmti_setFailStatus();
 247         }
 248         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(startLock))) {
 249             nsk_jvmti_setFailStatus();
 250         }
 251     }
 252 
 253     NSK_DISPLAY0("Agent thread: wait for run notification\n");
 254 
 255     /* wait on runLock */
 256     {
 257         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorWait(runLock, timeout))) {
 258             nsk_jvmti_setFailStatus();
 259         }
 260         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(runLock))) {
 261             nsk_jvmti_setFailStatus();
 262         }
 263     }
 264 
 265     NSK_DISPLAY0("Agent thread: modify tags of each even object.\n");
 266 
 267     /* modify tags of each even object */
 268     {
 269         int modified = 0;
 270         int i;
 271         for (i = 0; i < taggedObjectsCount; i+=2) {
 272             if (!NSK_JVMTI_VERIFY(jvmti->SetTag(taggedObjectsList[i], 0))) {
 273                 nsk_jvmti_setFailStatus();
 274                 continue;
 275             }
 276             modified++;
 277         }
 278 
 279         NSK_DISPLAY2("Agent thread: tags modified: %d of %d\n",
 280                                             modified, (int)taggedObjectsCount);
 281     }
 282 
 283     /* destroy objects list */
 284     {
 285         if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)taggedObjectsList))) {
 286             nsk_jvmti_setFailStatus();
 287         }
 288     }
 289 
 290     /* enter and notify endLock */
 291     {
 292         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(endLock))) {
 293             nsk_jvmti_setFailStatus();
 294         }
 295         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorNotify(endLock))) {
 296             nsk_jvmti_setFailStatus();
 297         }
 298         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(endLock))) {
 299             nsk_jvmti_setFailStatus();
 300         }
 301     }
 302 
 303     NSK_DISPLAY0("Agent thread: finished.\n");
 304 }
 305 
 306 /***********************************************************************/
 307 
 308 static int startThread(JNIEnv* jni, jthread threadObj) {
 309     int success = NSK_TRUE;
 310 
 311     /* enter startLock */
 312     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(startLock))) {
 313         nsk_jvmti_setFailStatus();
 314     }
 315 
 316     /* start thread */
 317     if (!NSK_JVMTI_VERIFY(
 318             jvmti->RunAgentThread(threadObj, agent_start, NULL, JVMTI_THREAD_NORM_PRIORITY))) {
 319         success = NSK_FALSE;
 320         nsk_jvmti_setFailStatus();
 321     } else {
 322         /* wait on startLock */
 323         if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorWait(startLock, timeout))) {
 324             nsk_jvmti_setFailStatus();
 325         }
 326     }
 327 
 328     /* exit starLock */
 329     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(startLock))) {
 330         nsk_jvmti_setFailStatus();
 331     }
 332 
 333     return success;
 334 }
 335 
 336 /** Create thread object for new agent thread. */
 337 static jthread newThreadObj(JNIEnv* jni) {
 338     jclass thrClass;
 339     jmethodID cid;
 340     jthread result = NULL;
 341 
 342     thrClass = jni->FindClass("java/lang/Thread");
 343     if (!NSK_JNI_VERIFY(jni, thrClass != NULL)) {
 344         nsk_jvmti_setFailStatus();
 345         return result;
 346     }
 347 
 348     cid = jni->GetMethodID(thrClass, "<init>", "()V");
 349     if (!NSK_JNI_VERIFY(jni, cid != NULL)) {
 350         nsk_jvmti_setFailStatus();
 351         return result;
 352     }
 353 
 354     result = jni->NewObject(thrClass, cid);
 355     if (!NSK_JNI_VERIFY(jni, result != NULL)) {
 356         nsk_jvmti_setFailStatus();
 357         return result;
 358     }
 359 
 360     return result;
 361 }
 362 
 363 /***********************************************************************/
 364 
 365 /** Clean counters and start new agent thread with agent_start() body. */
 366 static int prepareToIteration (JNIEnv* jni) {
 367     jthread threadObj = NULL;
 368 
 369     setCounter(&iterationCount, 0);
 370     setCounter(&objectCount, 0);
 371 
 372     threadObj = newThreadObj(jni);
 373     if (!NSK_VERIFY(threadObj != NULL)) {
 374         nsk_jvmti_setFailStatus();
 375         return NSK_FALSE;
 376     }
 377 
 378     /* enter endLock */
 379     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(endLock))) {
 380         nsk_jvmti_setFailStatus();
 381     }
 382 
 383     NSK_DISPLAY0("Starting new agent thread...\n");
 384     return startThread(jni, threadObj);
 385 }
 386 
 387 /** Wait for new agent thread to complete. */
 388 static void afterIteration (JNIEnv* jni) {
 389 
 390     /* notify new agent thread (in case if not yet notified) */
 391     notifyThread();
 392 
 393     NSK_DISPLAY0("Wait for new agent thread to complete\n");
 394 
 395     /* wait on endLock */
 396     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorWait(endLock, timeout))) {
 397         nsk_jvmti_setFailStatus();
 398     }
 399 
 400     /* exit endLock */
 401     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(endLock))) {
 402         nsk_jvmti_setFailStatus();
 403     }
 404 }
 405 
 406 /***********************************************************************/
 407 
 408 JNIEXPORT void JNICALL
 409 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_setTag(JNIEnv* jni,
 410                                                          jclass  klass,
 411                                                          jobject target, /* object to be tagged */
 412                                                          jlong   tag) {
 413 
 414     if (!NSK_JVMTI_VERIFY(jvmti->SetTag(target, tag))) {
 415         nsk_jvmti_setFailStatus();
 416     }
 417 }
 418 
 419 JNIEXPORT void JNICALL
 420 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverHeap(JNIEnv* jni,
 421                                                                      jclass  klass) {
 422     int modified = 0;
 423     int found = 0;
 424 
 425     if (!prepareToIteration(jni))
 426         return;
 427 
 428     NSK_DISPLAY0("Calling IterateOverHeap...\n");
 429     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_TAGGED,
 430                                                  heapObjectCallback,
 431                                                  NULL /*user_data*/))) {
 432         nsk_jvmti_setFailStatus();
 433     }
 434     NSK_DISPLAY0("IterateOverHeap finished.\n");
 435 
 436     afterIteration(jni);
 437 
 438     found = getCounter(&objectCount);
 439     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 440 
 441     modified = OBJ_MAX_COUNT - found;
 442     if (modified > 0) {
 443         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 444                                                         modified, OBJ_MAX_COUNT);
 445         nsk_jvmti_setFailStatus();
 446     }
 447 }
 448 
 449 JNIEXPORT void JNICALL
 450 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverReachableObjects(JNIEnv* jni,
 451                                                                                  jclass  klass) {
 452     int modified = 0;
 453     int found = 0;
 454 
 455     if (!prepareToIteration(jni))
 456         return;
 457 
 458     NSK_DISPLAY0("Calling IterateOverReachableObjects...\n");
 459     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverReachableObjects(heapRootCallback,
 460                                                              stackReferenceCallback,
 461                                                              objectReferenceCallback,
 462                                                              NULL /*user_data*/))) {
 463         nsk_jvmti_setFailStatus();
 464     }
 465     NSK_DISPLAY0("IterateOverReachableObjects finished.\n");
 466 
 467     afterIteration(jni);
 468 
 469     found = getCounter(&objectCount);
 470     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 471 
 472     modified = OBJ_MAX_COUNT - found;
 473     if (modified > 0) {
 474         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 475                                                         modified, OBJ_MAX_COUNT);
 476         nsk_jvmti_setFailStatus();
 477     }
 478 }
 479 
 480 JNIEXPORT void JNICALL
 481 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverInstancesOfClass(JNIEnv* jni,
 482                                                                                  jclass  klass) {
 483     int modified = 0;
 484     int found = 0;
 485 
 486     if (!prepareToIteration(jni))
 487         return;
 488 
 489     NSK_DISPLAY0("Calling IterateOverInstancesOfClass...\n");
 490     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverInstancesOfClass(debugeeClass,
 491                                                              JVMTI_HEAP_OBJECT_TAGGED,
 492                                                              heapObjectCallback,
 493                                                              NULL /*user_data*/))) {
 494         nsk_jvmti_setFailStatus();
 495     }
 496     NSK_DISPLAY0("IterateOverInstancesOfClass finished.\n");
 497 
 498     afterIteration(jni);
 499 
 500     found = getCounter(&objectCount);
 501     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 502 
 503     modified = OBJ_MAX_COUNT - found;
 504     if (modified > 0) {
 505         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 506                                                         modified, OBJ_MAX_COUNT);
 507         nsk_jvmti_setFailStatus();
 508     }
 509 }
 510 
 511 JNIEXPORT void JNICALL
 512 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverObjectsReachableFromObject(JNIEnv* jni,
 513                                                                                            jclass  klass) {
 514     jobject root = NULL;
 515     int modified = 0;
 516     int found = 0;
 517 
 518     root = jni->GetStaticObjectField(debugeeClass, rootFieldID);
 519     if (!NSK_JNI_VERIFY(jni, root != NULL)) {
 520         NSK_COMPLAIN0("GetStaticObjectField returned NULL for 'root' field value\n\n");
 521         nsk_jvmti_setFailStatus();
 522         return;
 523     }
 524 
 525     if (!prepareToIteration(jni))
 526         return;
 527 
 528     NSK_DISPLAY0("Calling IterateOverObjectsReachableFromObject...\n");
 529     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject(root,
 530                                                                        objectReferenceCallback,
 531                                                                        NULL /*user_data*/))) {
 532         nsk_jvmti_setFailStatus();
 533     }
 534     NSK_DISPLAY0("IterateOverObjectsReachableFromObject finished.\n");
 535 
 536     afterIteration(jni);
 537 
 538     found = getCounter(&objectCount);
 539     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 540 
 541     modified = OBJ_MAX_COUNT - found;
 542     if (modified > 0) {
 543         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 544                                                         modified, OBJ_MAX_COUNT);
 545         nsk_jvmti_setFailStatus();
 546     }
 547 }
 548 
 549 static void JNICALL
 550 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
 551 
 552     NSK_DISPLAY0("Wait for debugee start\n\n");
 553     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 554         return;
 555 
 556     NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_SIGNATURE);
 557     debugeeClass = nsk_jvmti_classBySignature(DEBUGEE_SIGNATURE);
 558     if (debugeeClass == NULL) {
 559         nsk_jvmti_setFailStatus();
 560         return;
 561     }
 562 
 563     debugeeClass = (jclass) jni->NewGlobalRef(debugeeClass);
 564     if (!NSK_JNI_VERIFY(jni, debugeeClass != NULL))
 565         return;
 566 
 567     NSK_DISPLAY1("Find ID of 'root' field: %s\n", ROOT_SIGNATURE);
 568     rootFieldID = jni->GetStaticFieldID(debugeeClass, "root", ROOT_SIGNATURE);
 569     if (!NSK_JNI_VERIFY(jni, rootFieldID != NULL)) {
 570         nsk_jvmti_setFailStatus();
 571         return;
 572     }
 573 
 574     NSK_DISPLAY0("Let debugee to run test cases\n");
 575     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 576         return;
 577 
 578     NSK_DISPLAY0("Wait for completion of test cases\n\n");
 579     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 580         return;
 581 
 582     NSK_TRACE(jni->DeleteGlobalRef(debugeeClass));
 583     NSK_TRACE(jvmti->DestroyRawMonitor(counterMonitor_ptr));
 584     NSK_TRACE(jvmti->DestroyRawMonitor(startLock));
 585     NSK_TRACE(jvmti->DestroyRawMonitor(runLock));
 586     NSK_TRACE(jvmti->DestroyRawMonitor(endLock));
 587 
 588     NSK_DISPLAY0("Let debugee to finish\n");
 589     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 590         return;
 591 }
 592 
 593 #ifdef STATIC_BUILD
 594 JNIEXPORT jint JNICALL Agent_OnLoad_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 595     return Agent_Initialize(jvm, options, reserved);
 596 }
 597 JNIEXPORT jint JNICALL Agent_OnAttach_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 598     return Agent_Initialize(jvm, options, reserved);
 599 }
 600 JNIEXPORT jint JNI_OnLoad_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 601     return JNI_VERSION_1_8;
 602 }
 603 #endif
 604 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 605     /* init framework and parse options */
 606     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 607         return JNI_ERR;
 608 
 609     /* create JVMTI environment */
 610     jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved);
 611     if (!NSK_VERIFY(jvmti != NULL))
 612         return JNI_ERR;
 613 
 614     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("counterMonitor", &counterMonitor_ptr))) {
 615         return JNI_ERR;
 616     }
 617 
 618     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("startLock", &startLock))) {
 619         return JNI_ERR;
 620     }
 621     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("runLock", &runLock))) {
 622         return JNI_ERR;
 623     }
 624     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("endLock", &endLock))) {
 625         return JNI_ERR;
 626     }
 627 
 628     memset(&caps, 0, sizeof(jvmtiCapabilities));
 629     caps.can_tag_objects = 1;
 630 
 631     if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps)))
 632         return JNI_ERR;
 633 
 634     if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps)))
 635         return JNI_ERR;
 636 
 637     if (!caps.can_tag_objects)
 638         NSK_DISPLAY0("Warning: tagging objects is not available\n");
 639 
 640     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 641         return JNI_ERR;
 642     NSK_DISPLAY0("agentProc has been set\n\n");
 643 
 644     return JNI_OK;
 645 }
 646 
 647 }