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 #include "JVMTITools.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /* ============================================================================= */
36 
37 /* scaffold objects */
38 static JNIEnv* jni = NULL;
39 static jvmtiEnv *jvmti = NULL;
40 static jlong timeout = 0;
41 static jrawMonitorID syncLock = NULL;
42 
43 /* constant names */
44 #define JVMTI_EVENT_COUNT   (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1)
45 #define EXPECTED_CLASS_NAME "Lnsk/jvmti/scenarios/events/EM01/em01t002a;"
46 #define CLASS_LOADER_COUNT_PARAM "classLoaderCount"
47 
48 static int eventCount[JVMTI_EVENT_COUNT];
49 
50 static int classLoaderCount = 0;
51 
52 static jvmtiPhase currentPhase;
53 
54 /* ============================================================================= */
55 /* ============================================================================= */
56 
57 
58 /*
59  * Class:     nsk_jvmti_scenarios_events_EM01_em01t002
60  * Method:    loadClass
61  * Signature: (Lnsk/share/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
62  */
63 JNIEXPORT jclass JNICALL
Java_nsk_jvmti_scenarios_events_EM01_em01t002_loadClass(JNIEnv * jni_env,jobject this,jobject loader,jstring className)64 Java_nsk_jvmti_scenarios_events_EM01_em01t002_loadClass(JNIEnv *jni_env,
65                         jobject this, jobject loader, jstring className) {
66     jclass klass;
67     jmethodID methodID;
68     jclass loadedClass;
69 
70     if (!NSK_JNI_VERIFY(jni_env, (klass =
71             NSK_CPP_STUB2(GetObjectClass, jni_env, loader)) != NULL)) {
72         nsk_jvmti_setFailStatus();
73         return NULL;
74     }
75 
76     if (!NSK_JNI_VERIFY(jni_env, (methodID =
77             NSK_CPP_STUB4(GetMethodID, jni_env, klass, "loadClass",
78                         "(Ljava/lang/String;)Ljava/lang/Class;")) != NULL)) {
79         nsk_jvmti_setFailStatus();
80         return NULL;
81     }
82 
83     if (!NSK_JNI_VERIFY(jni_env, (loadedClass =
84             NSK_CPP_STUB4(CallObjectMethod, jni_env, loader, methodID,
85                                     className)) != NULL)) {
86         nsk_jvmti_setFailStatus();
87         return NULL;
88     }
89 
90     return loadedClass;
91 }
92 
93 /*
94  * Class:     nsk_jvmti_scenarios_events_EM01_em01t002
95  * Method:    prepareClass
96  * Signature: (Ljava/lang/Class;)Z
97  */
98 JNIEXPORT jboolean JNICALL
Java_nsk_jvmti_scenarios_events_EM01_em01t002_prepareClass(JNIEnv * jni_env,jobject this,jclass klass)99 Java_nsk_jvmti_scenarios_events_EM01_em01t002_prepareClass(JNIEnv *jni_env,
100                         jobject this, jclass klass) {
101     jfieldID fieldID;
102 
103     if (!NSK_JNI_VERIFY(jni_env, (fieldID =
104             NSK_CPP_STUB4(GetStaticFieldID, jni_env, klass,
105                         "toProvokePreparation", "I")) != NULL)) {
106         nsk_jvmti_setFailStatus();
107         return NSK_FALSE;
108     }
109 
110     return NSK_TRUE;
111 }
112 
113 /*
114  * Class:     nsk_jvmti_scenarios_events_EM01_em01t002
115  * Method:    startThread
116  * Signature: (Ljava/lang/Thread;)Z
117  */
118 JNIEXPORT jboolean JNICALL
Java_nsk_jvmti_scenarios_events_EM01_em01t002_startThread(JNIEnv * jni_env,jobject this,jobject thread)119 Java_nsk_jvmti_scenarios_events_EM01_em01t002_startThread(JNIEnv *jni_env,
120                         jobject this, jobject thread) {
121     jclass klass;
122     jmethodID methodID;
123 
124     if (!NSK_JNI_VERIFY(jni_env, (klass =
125             NSK_CPP_STUB2(GetObjectClass, jni_env, thread)) != NULL)) {
126         nsk_jvmti_setFailStatus();
127         return NSK_FALSE;
128     }
129 
130     if (!NSK_JNI_VERIFY(jni_env, (methodID =
131             NSK_CPP_STUB4(GetMethodID, jni_env, klass, "start", "()V")) != NULL)) {
132         nsk_jvmti_setFailStatus();
133         return NSK_FALSE;
134     }
135 
136     if (!NSK_JNI_VERIFY_VOID(jni_env,
137             NSK_CPP_STUB3(CallVoidMethod, jni_env, thread, methodID)) ) {
138         nsk_jvmti_setFailStatus();
139         return NSK_FALSE;
140     }
141 
142     return NSK_TRUE;
143 }
144 
145 /* ============================================================================= */
146 /* ============================================================================= */
147 
148 static void
changeCount(jvmtiEvent event)149 changeCount(jvmtiEvent event) {
150 
151     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, syncLock)))
152         nsk_jvmti_setFailStatus();
153 
154     eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL]++;
155 
156     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, syncLock)))
157         nsk_jvmti_setFailStatus();
158 
159 }
160 
161 /* ============================================================================= */
162 
163 static void
showEventStatistics()164 showEventStatistics() {
165     int i;
166     const char* str;
167 
168     NSK_DISPLAY0("Event statistics\n");
169     NSK_DISPLAY0("----------------\n");
170     for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
171         if (eventCount[i] > 0) {
172             str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL));
173             NSK_DISPLAY2("%-40s %7d\n", str, eventCount[i]);
174         }
175     }
176 }
177 
178 /* ========================================================================== */
179 
180 /* callbacks */
181 void
classEventsHandler(jvmtiEvent event,jvmtiEnv * jvmti_env,JNIEnv * jni_env,jclass klass)182 classEventsHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env,
183                             jclass klass) {
184 
185     char *className;
186     char *generic;
187     jvmtiPhase phase;
188 
189     if (!NSK_JVMTI_VERIFY(
190             NSK_CPP_STUB4(GetClassSignature, jvmti_env, klass,
191                                 &className, &generic))) {
192         nsk_jvmti_setFailStatus();
193         return;
194     }
195 
196     if (strcmp(className, EXPECTED_CLASS_NAME) == 0) {
197         changeCount(event);
198         NSK_DISPLAY3("%25s(%4d)>>\tclass: %s\n",
199                             TranslateEvent(event),
200                             eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL],
201                             className);
202     }
203 
204     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
205         nsk_jvmti_setFailStatus();
206     }
207 
208     if (phase != currentPhase) {
209         NSK_DISPLAY2("Unexpected phase %s, but supposed %s",
210                 TranslatePhase(phase), TranslatePhase(currentPhase));
211     }
212 
213     if ((phase != JVMTI_PHASE_LIVE) && (phase != JVMTI_PHASE_START)) {
214         NSK_COMPLAIN4("%25s was sent during %s(%d)\n\tclass: %s\n",
215                     TranslateEvent(event),
216                     TranslatePhase(phase),
217                     phase,
218                     className);
219         nsk_jvmti_setFailStatus();
220     }
221 
222     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
223             jvmti_env, (unsigned char*)className))) {
224         nsk_jvmti_setFailStatus();
225     }
226     if (generic != NULL)
227         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
228                 jvmti_env, (unsigned char*)generic))) {
229             nsk_jvmti_setFailStatus();
230         }
231 }
232 
233 void
threadEventHandler(jvmtiEvent event,jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)234 threadEventHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env,
235                             jthread thread) {
236     jclass classObject;
237     char *className;
238     char *generic;
239     jvmtiPhase phase;
240 
241 
242     if (!NSK_JNI_VERIFY(jni_env, (classObject =
243             NSK_CPP_STUB2(GetObjectClass, jni_env, thread)) != NULL)) {
244         nsk_jvmti_setFailStatus();
245         return;
246     }
247 
248     if (!NSK_JVMTI_VERIFY(
249             NSK_CPP_STUB4(GetClassSignature, jvmti_env, classObject,
250                                 &className, &generic))) {
251         nsk_jvmti_setFailStatus();
252         return;
253     }
254 
255     if (strcmp(className, EXPECTED_CLASS_NAME) == 0) {
256         changeCount(event);
257         NSK_DISPLAY3("%25s(%4d)>>\tclass: %s\n",
258                             TranslateEvent(event),
259                             eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL],
260                             className);
261     }
262 
263     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
264         nsk_jvmti_setFailStatus();
265     }
266 
267     if (phase != currentPhase) {
268         NSK_DISPLAY2("Unexpected phase %s, but supposed %s",
269                 TranslatePhase(phase), TranslatePhase(currentPhase));
270     }
271 
272     if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) {
273         NSK_COMPLAIN4("%25s was sent during %s(%d)\n\tclass: %s\n",
274                     TranslateEvent(event),
275                     TranslatePhase(phase),
276                     phase,
277                     className);
278         nsk_jvmti_setFailStatus();
279     }
280 
281     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
282             jvmti_env, (unsigned char*)className))) {
283         nsk_jvmti_setFailStatus();
284     }
285     if (generic != NULL)
286         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
287                 jvmti_env, (unsigned char*)generic))) {
288             nsk_jvmti_setFailStatus();
289         }
290 }
291 
292 JNIEXPORT void JNICALL
cbVMStart(jvmtiEnv * jvmti_env,JNIEnv * jni_env)293 cbVMStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env) {
294 
295     jvmtiPhase phase;
296 
297     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
298         nsk_jvmti_setFailStatus();
299     }
300 
301     if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) {
302         NSK_COMPLAIN3("%25s was sent during %s(%d)\n",
303                     TranslateEvent(JVMTI_EVENT_VM_START),
304                     TranslatePhase(phase),
305                     phase);
306         nsk_jvmti_setFailStatus();
307     }
308 
309     changeCount(JVMTI_EVENT_VM_START);
310     currentPhase = JVMTI_PHASE_START;
311 }
312 
313 JNIEXPORT void JNICALL
cbVMInit(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)314 cbVMInit(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) {
315 
316     jvmtiPhase phase;
317 
318     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
319         nsk_jvmti_setFailStatus();
320     }
321 
322     if (phase != JVMTI_PHASE_LIVE) {
323         NSK_COMPLAIN3("%25s was sent during %s(%d)\n",
324                     TranslateEvent(JVMTI_EVENT_VM_INIT),
325                     TranslatePhase(phase),
326                     phase);
327         nsk_jvmti_setFailStatus();
328     }
329 
330     changeCount(JVMTI_EVENT_VM_INIT);
331     currentPhase = JVMTI_PHASE_LIVE;
332 }
333 
334 JNIEXPORT void JNICALL
cbVMDeath(jvmtiEnv * jvmti_env,JNIEnv * jni_env)335 cbVMDeath(jvmtiEnv* jvmti_env, JNIEnv* jni_env) {
336 
337     jvmtiPhase phase;
338 
339     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
340         nsk_jvmti_setFailStatus();
341     }
342 
343     if (phase != JVMTI_PHASE_LIVE) {
344         NSK_COMPLAIN3("%25s was sent during %s(%d)\n",
345                     TranslateEvent(JVMTI_EVENT_VM_INIT),
346                     TranslatePhase(phase),
347                     phase);
348         nsk_jvmti_setFailStatus();
349     }
350 
351     currentPhase = JVMTI_PHASE_DEAD;
352     changeCount(JVMTI_EVENT_VM_DEATH);
353 
354     if (!NSK_JVMTI_VERIFY(
355             NSK_CPP_STUB2(DestroyRawMonitor, jvmti, syncLock)))
356         nsk_jvmti_setFailStatus();
357 
358 }
359 
360 JNIEXPORT void JNICALL
cbClassLoad(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jclass klass)361 cbClassLoad(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread,
362                     jclass klass) {
363 
364     classEventsHandler(JVMTI_EVENT_CLASS_LOAD, jvmti_env, jni_env, klass);
365 }
366 
367 JNIEXPORT void JNICALL
cbClassPrepare(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jclass klass)368 cbClassPrepare(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread,
369                     jclass klass) {
370 
371     classEventsHandler(JVMTI_EVENT_CLASS_PREPARE, jvmti_env, jni_env, klass);
372 }
373 
374 JNIEXPORT void JNICALL
cbThreadStart(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)375 cbThreadStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) {
376 
377     threadEventHandler(JVMTI_EVENT_THREAD_START, jvmti_env, jni_env, thread);
378 }
379 
380 JNIEXPORT void JNICALL
cbThreadEnd(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)381 cbThreadEnd(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) {
382 
383     threadEventHandler(JVMTI_EVENT_THREAD_END, jvmti_env, jni_env, thread);
384 }
385 
386 /* ============================================================================= */
387 
388 static int
enableEvent(jvmtiEventMode enable,jvmtiEvent event)389 enableEvent(jvmtiEventMode enable, jvmtiEvent event) {
390 
391     if (enable == JVMTI_ENABLE) {
392         NSK_DISPLAY1("enabling %s\n", TranslateEvent(event));
393     } else {
394         NSK_DISPLAY1("disabling %s\n", TranslateEvent(event));
395     }
396 
397 
398     if (!NSK_JVMTI_VERIFY(
399             NSK_CPP_STUB4(SetEventNotificationMode, jvmti, enable,
400                                             event, NULL))) {
401         nsk_jvmti_setFailStatus();
402         return NSK_FALSE;
403     }
404 
405     return NSK_TRUE;
406 }
407 
408 /* ============================================================================= */
409 
410 /**
411  * Testcase: check tested events.
412  *   - check if expected events received for each method
413  *
414  * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break.
415  */
checkEvents(int step)416 int checkEvents(int step) {
417 
418     int i;
419     jvmtiEvent curr;
420     int result = NSK_TRUE;
421     int mustBeChecked;
422 
423     showEventStatistics();
424 
425     for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
426 
427         curr = i + JVMTI_MIN_EVENT_TYPE_VAL;
428         switch (step) {
429         case 1:
430             mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD)
431                     || (curr == JVMTI_EVENT_CLASS_PREPARE));
432             break;
433 
434         case 2:
435             mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD)
436                     || (curr == JVMTI_EVENT_CLASS_PREPARE)
437                     || (curr == JVMTI_EVENT_THREAD_START)
438                     || (curr == JVMTI_EVENT_THREAD_END));
439             break;
440         default:
441             mustBeChecked = NSK_TRUE;
442         }
443 
444         if (mustBeChecked && eventCount[i] != classLoaderCount) {
445                 nsk_jvmti_setFailStatus();
446                 NSK_COMPLAIN3("Unexpected number of %s events %7d\n\texpected value %d\n",
447                                     TranslateEvent(curr),
448                                     eventCount[i],
449                                     classLoaderCount);
450                 nsk_jvmti_setFailStatus();
451                 result = NSK_FALSE;
452         }
453     }
454 
455     return result;
456 }
457 
458 /* ============================================================================= */
459 
460 static int
setCallBacks()461 setCallBacks() {
462     jvmtiEventCallbacks eventCallbacks;
463     memset(&eventCallbacks, 0, sizeof(eventCallbacks));
464 
465     eventCallbacks.VMStart      = cbVMStart;
466     eventCallbacks.VMInit       = cbVMInit;
467     eventCallbacks.VMDeath      = cbVMDeath;
468     eventCallbacks.ClassLoad    = cbClassLoad;
469     eventCallbacks.ClassPrepare = cbClassPrepare;
470     eventCallbacks.ThreadStart  = cbThreadStart;
471     eventCallbacks.ThreadEnd    = cbThreadEnd;
472 
473     if (!NSK_JVMTI_VERIFY(
474             NSK_CPP_STUB3(SetEventCallbacks, jvmti,
475                                 &eventCallbacks,
476                                 sizeof(eventCallbacks))))
477         return NSK_FALSE;
478 
479     return NSK_TRUE;
480 }
481 
482 /* ============================================================================= */
483 
484 /** Agent algorithm. */
485 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * agentJNI,void * arg)486 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
487 
488     NSK_DISPLAY0("Wait for debuggee to become ready\n");
489     if (!nsk_jvmti_waitForSync(timeout))
490         return;
491 
492     NSK_DISPLAY0("Let debuggee to load class\n");
493     if (!nsk_jvmti_resumeSync())
494         return;
495 
496     if (!nsk_jvmti_waitForSync(timeout))
497         return;
498 
499     /* check only CLASS_LOAD and CLASS_PREPARE events */
500     if (!checkEvents(1)) {
501         nsk_jvmti_setFailStatus();
502     }
503 
504     NSK_DISPLAY0("Let debuggee to start threads\n");
505     if (!nsk_jvmti_resumeSync())
506         return;
507 
508     if (!nsk_jvmti_waitForSync(timeout))
509         return;
510 
511     NSK_DISPLAY0("check event 2\n");
512     if (!checkEvents(2)) {
513         nsk_jvmti_setFailStatus();
514     }
515 
516     NSK_DISPLAY0("Let debuggee to finish\n");
517     if (!nsk_jvmti_resumeSync())
518         return;
519 
520 }
521 
522 /* ============================================================================= */
523 
524 /** Agent library initialization. */
525 #ifdef STATIC_BUILD
Agent_OnLoad_em01t002(JavaVM * jvm,char * options,void * reserved)526 JNIEXPORT jint JNICALL Agent_OnLoad_em01t002(JavaVM *jvm, char *options, void *reserved) {
527     return Agent_Initialize(jvm, options, reserved);
528 }
Agent_OnAttach_em01t002(JavaVM * jvm,char * options,void * reserved)529 JNIEXPORT jint JNICALL Agent_OnAttach_em01t002(JavaVM *jvm, char *options, void *reserved) {
530     return Agent_Initialize(jvm, options, reserved);
531 }
JNI_OnLoad_em01t002(JavaVM * jvm,char * options,void * reserved)532 JNIEXPORT jint JNI_OnLoad_em01t002(JavaVM *jvm, char *options, void *reserved) {
533     return JNI_VERSION_1_8;
534 }
535 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)536 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
537 
538     currentPhase = JVMTI_PHASE_ONLOAD;
539 
540     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
541         return JNI_ERR;
542 
543     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
544     classLoaderCount = nsk_jvmti_findOptionIntValue(CLASS_LOADER_COUNT_PARAM, 10);
545 
546     if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
547         return JNI_ERR;
548 
549     if (!NSK_JVMTI_VERIFY(
550             NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_syncLock", &syncLock))) {
551         nsk_jvmti_setFailStatus();
552         return JNI_ERR;
553     }
554 
555     if (!setCallBacks()) {
556         return JNI_ERR;
557     }
558 
559     if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD)
560             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE)
561             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START)
562             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END)
563             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_START)
564             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT)
565             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH)
566             ) {
567         NSK_COMPLAIN0("Events could not be enabled");
568         nsk_jvmti_setFailStatus();
569         return JNI_ERR;
570     }
571 
572     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
573         return JNI_ERR;
574 
575     currentPhase = JVMTI_PHASE_PRIMORDIAL;
576 
577     return JNI_OK;
578 }
579 
580 #ifdef __cplusplus
581 }
582 #endif
583