Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/libdefine.cpp
41159 views
/*1* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22#include <jni.h>23#include <stdio.h>2425#include <string.h>26#include <jvmti.h>2728#define STATUS_FAILED 229#define STATUS_PASSED 03031#define REFERENCES_ARRAY_SIZE 100000003233#ifndef _Included_gc_g1_unloading_unloading_classloaders_JNIClassloader34#define _Included_gc_g1_unloading_unloading_classloaders_JNIClassloader3536extern "C" {3738/*39* Class: gc_g1_unloading_unloading_classloaders_JNIClassloader40* Method: loadThroughJNI041* Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;[B)Ljava/lang/Class;42*/43JNIEXPORT jclass JNICALL Java_gc_g1_unloading_classloaders_JNIClassloader_loadThroughJNI0 (JNIEnv * env,44jclass clazz, jstring className, jobject classLoader, jbyteArray bytecode) {4546const char * classNameChar = env->GetStringUTFChars(className, NULL);47jbyte * arrayContent = env->GetByteArrayElements(bytecode, NULL);48jsize bytecodeLength = env->GetArrayLength(bytecode);49jclass returnValue = env->DefineClass(classNameChar, classLoader, arrayContent, bytecodeLength);50env->ReleaseByteArrayElements(bytecode, arrayContent, JNI_ABORT);51env->ReleaseStringUTFChars(className, classNameChar);52if (!returnValue) {53printf("ERROR: DefineClass call returned NULL by some reason. Classloading failed.\n");54}5556return returnValue;57}5859/*60* Class: gc_g1_unloading_unloading_loading_ClassLoadingHelper61* Method: makeRedefinition062* Signature: (ILjava/lang/Class;[B)I63*/64JNIEXPORT jint JNICALL Java_gc_g1_unloading_loading_ClassLoadingHelper_makeRedefinition0(JNIEnv *env,65jclass clazz, jint fl, jclass redefCls, jbyteArray classBytes) {66JavaVM * jvm;67jvmtiEnv * jvmti;68jvmtiError err;69jvmtiCapabilities caps;70jvmtiClassDefinition classDef;71jint jint_err = env->GetJavaVM(&jvm);72if (jint_err) {73printf("GetJavaVM returned nonzero: %d", jint_err);74return STATUS_FAILED;75}7677jint_err = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_0);78if (jint_err) {79printf("GetEnv returned nonzero: %d", jint_err);80return STATUS_FAILED;81}8283err = jvmti->GetPotentialCapabilities(&caps);84if (err != JVMTI_ERROR_NONE) {85printf("(GetPotentialCapabilities) unexpected error: %d\n",err);86return JNI_ERR;87}8889err = jvmti->AddCapabilities(&caps);90if (err != JVMTI_ERROR_NONE) {91printf("(AddCapabilities) unexpected error: %d\n", err);92return JNI_ERR;93}9495if (!caps.can_redefine_classes) {96printf("ERROR: Can't redefine classes. jvmtiCapabilities.can_redefine_classes isn't set up.");97return STATUS_FAILED;98}99100classDef.klass = redefCls;101classDef.class_byte_count =102env->GetArrayLength(classBytes);103jbyte * class_bytes = env->GetByteArrayElements(classBytes, NULL);104classDef.class_bytes = (unsigned char *)class_bytes;105106if (fl == 2) {107printf(">>>>>>>> Invoke RedefineClasses():\n");108printf("\tnew class byte count=%d\n", classDef.class_byte_count);109}110err = jvmti->RedefineClasses(1, &classDef);111env->ReleaseByteArrayElements(classBytes, class_bytes, JNI_ABORT);112if (err != JVMTI_ERROR_NONE) {113printf("%s: Failed to call RedefineClasses():\n", __FILE__);114printf("\tthe function returned error %d\n", err);115printf("\tFor more info about this error see the JVMTI spec.\n");116return STATUS_FAILED;117}118if (fl == 2)119printf("<<<<<<<< RedefineClasses() is successfully done\n");120121return STATUS_PASSED;122}123124jobject referencesArray[REFERENCES_ARRAY_SIZE];125int firstFreeIndex = 0;126127/*128* Class: gc_g1_unloading_unloading_keepref_JNIGlobalRefHolder129* Method: keepGlobalJNIReference130* Signature: (Ljava/lang/Object;)I131*/132JNIEXPORT jint JNICALL Java_gc_g1_unloading_keepref_JNIGlobalRefHolder_keepGlobalJNIReference133(JNIEnv * env, jclass clazz, jobject obj) {134int returnValue;135referencesArray[firstFreeIndex] = env->NewGlobalRef(obj);136printf("checkpoint1 %d \n", firstFreeIndex);137returnValue = firstFreeIndex;138firstFreeIndex++;139return returnValue;140}141142/*143* Class: gc_g1_unloading_unloading_keepref_JNIGlobalRefHolder144* Method: deleteGlobalJNIReference145* Signature: (I)V146*/147JNIEXPORT void JNICALL Java_gc_g1_unloading_keepref_JNIGlobalRefHolder_deleteGlobalJNIReference148(JNIEnv * env, jclass clazz, jint index) {149env->DeleteGlobalRef(referencesArray[index]);150}151152153/*154* Class: gc_g1_unloading_unloading_keepref_JNILocalRefHolder155* Method: holdWithJNILocalReference156* Signature: (Ljava/lang/Object;)V157*/158JNIEXPORT void JNICALL Java_gc_g1_unloading_keepref_JNILocalRefHolder_holdWithJNILocalReference159(JNIEnv * env, jobject thisObject, jobject syncObject) {160jclass clazz, objectClazz;161jfieldID objectToKeepField;162jobject objectToKeep, localRef;163jmethodID waitMethod;164165clazz = env->GetObjectClass(thisObject);166objectToKeepField = env->GetFieldID(clazz, "objectToKeep", "Ljava/lang/Object;");167objectToKeep = env->GetObjectField(thisObject, objectToKeepField);168localRef = env->NewLocalRef(objectToKeep);169env->SetObjectField(thisObject, objectToKeepField, NULL);170171objectClazz = env->FindClass("Ljava/lang/Object;");172waitMethod = env->GetMethodID(objectClazz, "wait", "()V");173env->CallVoidMethod(syncObject, waitMethod);174printf("checkpoint2 \n");175}176}177#endif178179180