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     if (!NSK_JNI_VERIFY(jni, (thrClass = jni->FindClass("java/lang/Thread")) != NULL )) {
 343         nsk_jvmti_setFailStatus();
 344         return result;
 345     }
 346 
 347     if (!NSK_JNI_VERIFY(jni, (cid = jni->GetMethodID(thrClass, "<init>", "()V")) != NULL )) {
 348         nsk_jvmti_setFailStatus();
 349         return result;
 350     }
 351 
 352     if (!NSK_JNI_VERIFY(jni, (result = jni->NewObject(thrClass, cid)) != NULL )) {
 353         nsk_jvmti_setFailStatus();
 354         return result;
 355     }
 356 
 357     return result;
 358 }
 359 
 360 /***********************************************************************/
 361 
 362 /** Clean counters and start new agent thread with agent_start() body. */
 363 static int prepareToIteration (JNIEnv* jni) {
 364     jthread threadObj = NULL;
 365 
 366     setCounter(&iterationCount, 0);
 367     setCounter(&objectCount, 0);
 368 
 369     if (!NSK_VERIFY((threadObj = newThreadObj(jni)) != NULL)) {
 370         nsk_jvmti_setFailStatus();
 371         return NSK_FALSE;
 372     }
 373 
 374     /* enter endLock */
 375     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(endLock))) {
 376         nsk_jvmti_setFailStatus();
 377     }
 378 
 379     NSK_DISPLAY0("Starting new agent thread...\n");
 380     return startThread(jni, threadObj);
 381 }
 382 
 383 /** Wait for new agent thread to complete. */
 384 static void afterIteration (JNIEnv* jni) {
 385 
 386     /* notify new agent thread (in case if not yet notified) */
 387     notifyThread();
 388 
 389     NSK_DISPLAY0("Wait for new agent thread to complete\n");
 390 
 391     /* wait on endLock */
 392     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorWait(endLock, timeout))) {
 393         nsk_jvmti_setFailStatus();
 394     }
 395 
 396     /* exit endLock */
 397     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(endLock))) {
 398         nsk_jvmti_setFailStatus();
 399     }
 400 }
 401 
 402 /***********************************************************************/
 403 
 404 JNIEXPORT void JNICALL
 405 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_setTag( JNIEnv* jni,
 406                                                           jclass  klass,
 407                                                           jobject target, /* object to be tagged */
 408                                                           jlong   tag ) {
 409 
 410     if (!NSK_JVMTI_VERIFY(jvmti->SetTag(target, tag))) {
 411         nsk_jvmti_setFailStatus();
 412     }
 413 }
 414 
 415 JNIEXPORT void JNICALL
 416 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverHeap( JNIEnv* jni,
 417                                                                       jclass  klass ) {
 418     int modified = 0;
 419     int found = 0;
 420 
 421     if (!prepareToIteration(jni))
 422         return;
 423 
 424     NSK_DISPLAY0("Calling IterateOverHeap...\n");
 425     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_TAGGED,
 426                                                  heapObjectCallback,
 427                                                  NULL /*user_data*/))) {
 428         nsk_jvmti_setFailStatus();
 429     }
 430     NSK_DISPLAY0("IterateOverHeap finished.\n");
 431 
 432     afterIteration(jni);
 433 
 434     found = getCounter(&objectCount);
 435     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 436 
 437     modified = OBJ_MAX_COUNT - found;
 438     if (modified > 0) {
 439         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 440                                                         modified, OBJ_MAX_COUNT);
 441         nsk_jvmti_setFailStatus();
 442     }
 443 }
 444 
 445 JNIEXPORT void JNICALL
 446 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverReachableObjects( JNIEnv* jni,
 447                                                                                   jclass  klass ) {
 448     int modified = 0;
 449     int found = 0;
 450 
 451     if (!prepareToIteration(jni))
 452         return;
 453 
 454     NSK_DISPLAY0("Calling IterateOverReachableObjects...\n");
 455     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverReachableObjects(heapRootCallback,
 456                                                              stackReferenceCallback,
 457                                                              objectReferenceCallback,
 458                                                              NULL /*user_data*/))) {
 459         nsk_jvmti_setFailStatus();
 460     }
 461     NSK_DISPLAY0("IterateOverReachableObjects finished.\n");
 462 
 463     afterIteration(jni);
 464 
 465     found = getCounter(&objectCount);
 466     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 467 
 468     modified = OBJ_MAX_COUNT - found;
 469     if (modified > 0) {
 470         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 471                                                         modified, OBJ_MAX_COUNT);
 472         nsk_jvmti_setFailStatus();
 473     }
 474 }
 475 
 476 JNIEXPORT void JNICALL
 477 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverInstancesOfClass( JNIEnv* jni,
 478                                                                                   jclass  klass ) {
 479     int modified = 0;
 480     int found = 0;
 481 
 482     if (!prepareToIteration(jni))
 483         return;
 484 
 485     NSK_DISPLAY0("Calling IterateOverInstancesOfClass...\n");
 486     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverInstancesOfClass(debugeeClass,
 487                                                              JVMTI_HEAP_OBJECT_TAGGED,
 488                                                              heapObjectCallback,
 489                                                              NULL /*user_data*/))) {
 490         nsk_jvmti_setFailStatus();
 491     }
 492     NSK_DISPLAY0("IterateOverInstancesOfClass finished.\n");
 493 
 494     afterIteration(jni);
 495 
 496     found = getCounter(&objectCount);
 497     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 498 
 499     modified = OBJ_MAX_COUNT - found;
 500     if (modified > 0) {
 501         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 502                                                         modified, OBJ_MAX_COUNT);
 503         nsk_jvmti_setFailStatus();
 504     }
 505 }
 506 
 507 JNIEXPORT void JNICALL
 508 Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverObjectsReachableFromObject( JNIEnv* jni,
 509                                                                                             jclass  klass ) {
 510     jobject root = NULL;
 511     int modified = 0;
 512     int found = 0;
 513 
 514     if (!NSK_JNI_VERIFY(jni, (root =
 515             jni->GetStaticObjectField(debugeeClass, rootFieldID)) != NULL )) {
 516         NSK_COMPLAIN0("GetStaticObjectField returned NULL for 'root' field value\n\n");
 517         nsk_jvmti_setFailStatus();
 518         return;
 519     }
 520 
 521     if (!prepareToIteration(jni))
 522         return;
 523 
 524     NSK_DISPLAY0("Calling IterateOverObjectsReachableFromObject...\n");
 525     if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject(root,
 526                                                                        objectReferenceCallback,
 527                                                                        NULL /*user_data*/))) {
 528         nsk_jvmti_setFailStatus();
 529     }
 530     NSK_DISPLAY0("IterateOverObjectsReachableFromObject finished.\n");
 531 
 532     afterIteration(jni);
 533 
 534     found = getCounter(&objectCount);
 535     NSK_DISPLAY1("Found tagged objects: %d\n", found);
 536 
 537     modified = OBJ_MAX_COUNT - found;
 538     if (modified > 0) {
 539         NSK_COMPLAIN2("Tags were modified by other thread during heap iteration: %d of %d\n",
 540                                                         modified, OBJ_MAX_COUNT);
 541         nsk_jvmti_setFailStatus();
 542     }
 543 }
 544 
 545 static void JNICALL
 546 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
 547 
 548     NSK_DISPLAY0("Wait for debugee start\n\n");
 549     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 550         return;
 551 
 552     NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_SIGNATURE);
 553     debugeeClass = nsk_jvmti_classBySignature(DEBUGEE_SIGNATURE);
 554     if (debugeeClass == NULL) {
 555         nsk_jvmti_setFailStatus();
 556         return;
 557     }
 558 
 559     if (!NSK_JNI_VERIFY(jni, (debugeeClass = (jclass)jni->NewGlobalRef(debugeeClass)) != NULL))
 560         return;
 561 
 562     NSK_DISPLAY1("Find ID of 'root' field: %s\n", ROOT_SIGNATURE);
 563     if (!NSK_JNI_VERIFY(jni, (rootFieldID =
 564             jni->GetStaticFieldID(debugeeClass, "root", ROOT_SIGNATURE)) != NULL )) {
 565         nsk_jvmti_setFailStatus();
 566         return;
 567     }
 568 
 569     NSK_DISPLAY0("Let debugee to run test cases\n");
 570     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 571         return;
 572 
 573     NSK_DISPLAY0("Wait for completion of test cases\n\n");
 574     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 575         return;
 576 
 577     NSK_TRACE(jni->DeleteGlobalRef(debugeeClass));
 578     NSK_TRACE(jvmti->DestroyRawMonitor(counterMonitor_ptr));
 579     NSK_TRACE(jvmti->DestroyRawMonitor(startLock));
 580     NSK_TRACE(jvmti->DestroyRawMonitor(runLock));
 581     NSK_TRACE(jvmti->DestroyRawMonitor(endLock));
 582 
 583     NSK_DISPLAY0("Let debugee to finish\n");
 584     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 585         return;
 586 }
 587 
 588 #ifdef STATIC_BUILD
 589 JNIEXPORT jint JNICALL Agent_OnLoad_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 590     return Agent_Initialize(jvm, options, reserved);
 591 }
 592 JNIEXPORT jint JNICALL Agent_OnAttach_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 593     return Agent_Initialize(jvm, options, reserved);
 594 }
 595 JNIEXPORT jint JNI_OnLoad_ap04t003(JavaVM *jvm, char *options, void *reserved) {
 596     return JNI_VERSION_1_8;
 597 }
 598 #endif
 599 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 600     /* init framework and parse options */
 601     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 602         return JNI_ERR;
 603 
 604     /* create JVMTI environment */
 605     if (!NSK_VERIFY((jvmti =
 606             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
 607         return JNI_ERR;
 608 
 609     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("counterMonitor", &counterMonitor_ptr))) {
 610         return JNI_ERR;
 611     }
 612 
 613     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("startLock", &startLock))) {
 614         return JNI_ERR;
 615     }
 616     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("runLock", &runLock))) {
 617         return JNI_ERR;
 618     }
 619     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("endLock", &endLock))) {
 620         return JNI_ERR;
 621     }
 622 
 623     memset(&caps, 0, sizeof(jvmtiCapabilities));
 624     caps.can_tag_objects = 1;
 625 
 626     if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps)))
 627         return JNI_ERR;
 628 
 629     if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps)))
 630         return JNI_ERR;
 631 
 632     if (!caps.can_tag_objects)
 633         NSK_DISPLAY0("Warning: tagging objects is not available\n");
 634 
 635     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 636         return JNI_ERR;
 637     NSK_DISPLAY0("agentProc has been set\n\n");
 638 
 639     return JNI_OK;
 640 }
 641 
 642 }