Skip to content
Permalink
Browse files
8266002: vmTestbase/nsk/jvmti/ClassPrepare/classprep001 should skip e…
…vents for unexpected classes

Reviewed-by: cjplummer, sspitsyn
  • Loading branch information
Alex Menkov committed May 6, 2021
1 parent 52f1db6 commit 0ca86da0e3563a8328f6ff2a3bc4d4c5b8a82e69
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,8 +40,8 @@
}
}

native static void getReady();
native static int check();
native static void getReady(Thread thread);
native static int check(Thread thread);

public static void main(String args[]) {
args = nsk.share.jvmti.JVMTITest.commonInit(args);
@@ -51,12 +51,26 @@ public static void main(String args[]) {
}

public static int run(String args[], PrintStream out) {
getReady();
Thread otherThread = new Thread(() -> {
new TestClass2().run();
});

getReady(Thread.currentThread());

// should generate the events
new TestClass().run();
return check();

// loading classes on other thread should not generate the events
otherThread.start();
try {
otherThread.join();
} catch (InterruptedException e) {
}

return check(Thread.currentThread());
}

static interface TestInterface {
interface TestInterface {
int constant = Integer.parseInt("10");
void run();
}
@@ -71,4 +85,13 @@ public void run() {
count++;
}
}

interface TestInterface2 {
void run();
}

static class TestClass2 implements TestInterface2 {
public void run() {
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,12 @@ static class_info classes[] = {
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestInterface;", EXP_STATUS, 2, 1, 0 },
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestClass;", EXP_STATUS, 3, 2, 1 }
};
// These classes are loaded on a different thread.
// We should not get ClassPrepare events for them.
static const class_info unexpectedClasses[] = {
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestInterface2;", 0, 0, 0, 0 },
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestClass2;", 0, 0, 0, 0}
};

void printStatus(jint status) {
int flags = 0;
@@ -87,6 +93,17 @@ void printStatus(jint status) {
printf(" (0x%x)\n", status);
}

const size_t NOT_FOUND = (size_t)(-1);

size_t findClass(const char *classSig, const class_info *arr, int size) {
for (int i = 0; i < size; i++) {
if (strcmp(classSig, arr[i].sig) == 0) {
return i;
}
}
return NOT_FOUND;
}

void JNICALL ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *env,
jthread thr, jclass cls) {
jvmtiError err;
@@ -188,19 +205,25 @@ void JNICALL ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *env,
printf("\n");
}

if (eventsCount >= eventsExpected) {
printf("(#%" PRIuPTR ") too many events: %" PRIuPTR ", expected: %" PRIuPTR "\n",
eventsCount, eventsCount + 1, eventsExpected);
result = STATUS_FAILED;
size_t expectedClassIdx = findClass(inf.sig, classes, sizeof(classes)/sizeof(class_info));
// Test classes loading may cause system classes loading - skip them.
if (expectedClassIdx == NOT_FOUND) {
size_t unexpectedClassIdx = findClass(inf.sig, unexpectedClasses,
sizeof(unexpectedClasses)/sizeof(class_info));
if (unexpectedClassIdx != NOT_FOUND) {
printf("# wrong class: \"%s\"\n", inf.sig);
result = STATUS_FAILED;
}
return;
}

if (inf.sig == NULL || strcmp(inf.sig, classes[eventsCount].sig) != 0) {
printf("(#%" PRIuPTR ") wrong class: \"%s\"",
eventsCount, inf.sig);
printf(", expected: \"%s\"\n", classes[eventsCount].sig);
if (eventsCount != expectedClassIdx) {
printf("(#%" PRIuPTR ") unexpected order: %" PRIuPTR ", expected: %" PRIuPTR "\n",
eventsCount, expectedClassIdx, eventsCount);
result = STATUS_FAILED;
return;
}

if (inf.status != classes[eventsCount].status) {
printf("(#%" PRIuPTR ") wrong status: ", eventsCount);
printStatus(inf.status);
@@ -266,24 +289,16 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
}

JNIEXPORT void JNICALL
Java_nsk_jvmti_ClassPrepare_classprep001_getReady(JNIEnv *env, jclass cls) {
Java_nsk_jvmti_ClassPrepare_classprep001_getReady(JNIEnv *env, jclass cls, jthread thread) {
jvmtiError err;
jthread prep_thread;

if (jvmti == NULL) {
printf("JVMTI client was not properly loaded!\n");
return;
}

err = jvmti->GetCurrentThread(&prep_thread);
if (err != JVMTI_ERROR_NONE) {
printf("Failed to get current thread: %s (%d)\n", TranslateError(err), err);
result = STATUS_FAILED;
return;
}

err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_CLASS_PREPARE, prep_thread);
JVMTI_EVENT_CLASS_PREPARE, thread);
if (err == JVMTI_ERROR_NONE) {
eventsExpected = sizeof(classes)/sizeof(class_info);
} else {
@@ -294,23 +309,16 @@ Java_nsk_jvmti_ClassPrepare_classprep001_getReady(JNIEnv *env, jclass cls) {
}

JNIEXPORT jint JNICALL
Java_nsk_jvmti_ClassPrepare_classprep001_check(JNIEnv *env, jclass cls) {
Java_nsk_jvmti_ClassPrepare_classprep001_check(JNIEnv *env, jclass cls, jthread thread) {
jvmtiError err;
jthread prep_thread;

if (jvmti == NULL) {
printf("JVMTI client was not properly loaded!\n");
return STATUS_FAILED;
}

err = jvmti->GetCurrentThread(&prep_thread);
if (err != JVMTI_ERROR_NONE) {
printf("Failed to get current thread: %s (%d)\n", TranslateError(err), err);
return STATUS_FAILED;
}

err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
JVMTI_EVENT_CLASS_PREPARE, prep_thread);
JVMTI_EVENT_CLASS_PREPARE, thread);
if (err != JVMTI_ERROR_NONE) {
printf("Failed to disable JVMTI_EVENT_CLASS_PREPARE: %s (%d)\n",
TranslateError(err), err);

0 comments on commit 0ca86da

Please sign in to comment.