1 /*
   2  * Copyright (c) 2007, 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 <jni.h>
  25 #include <stdio.h>
  26 #include "jni_tools.h"
  27 
  28 extern "C" {
  29 
  30 #define FIND_CLASS(_class, _className)\
  31     if (!NSK_JNI_VERIFY(env, (_class = \
  32             NSK_CPP_STUB2(FindClass, env, _className)) != NULL))\
  33         return
  34 
  35 #define GET_OBJECT_CLASS(_class, _obj)\
  36     if (!NSK_JNI_VERIFY(env, (_class = \
  37             NSK_CPP_STUB2(GetObjectClass, env, _obj)) != NULL))\
  38         return
  39 
  40 #define GET_STATIC_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\
  41     if (!NSK_JNI_VERIFY(env, (_fieldID = \
  42             NSK_CPP_STUB4(GetStaticFieldID, env, _class,\
  43                 _fieldName, _fieldSig)) != NULL))\
  44         return
  45 
  46 #define GET_STATIC_OBJ_FIELD(_value, _class, _fieldName, _fieldSig)\
  47     GET_STATIC_FIELD_ID(field, _class, _fieldName, _fieldSig);\
  48     _value = NSK_CPP_STUB3(GetStaticObjectField, env, _class, \
  49                                 field)
  50 
  51 #define GET_STATIC_BOOL_FIELD(_value, _class, _fieldName)\
  52     GET_STATIC_FIELD_ID(field, _class, _fieldName, "Z");\
  53     _value = NSK_CPP_STUB3(GetStaticBooleanField, env, _class, field)
  54 
  55 #define GET_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\
  56     if (!NSK_JNI_VERIFY(env, (_fieldID = \
  57             NSK_CPP_STUB4(GetFieldID, env, _class,\
  58                 _fieldName, _fieldSig)) != NULL))\
  59         return
  60 
  61 #define GET_INT_FIELD(_value, _obj, _class, _fieldName)\
  62     GET_FIELD_ID(field, _class, _fieldName, "I");\
  63     _value = NSK_CPP_STUB3(GetIntField, env, _obj, field)
  64 
  65 #define GET_LONG_FIELD(_value, _obj, _class, _fieldName)\
  66     GET_FIELD_ID(field, _class, _fieldName, "J");\
  67     _value = NSK_CPP_STUB3(GetLongField, env, _obj, field)
  68 
  69 #define GET_STATIC_INT_FIELD(_value, _class, _fieldName)\
  70     GET_STATIC_FIELD_ID(field, _class, _fieldName, "I");\
  71     _value = NSK_CPP_STUB3(GetStaticIntField, env, _class, field)
  72 
  73 #define SET_INT_FIELD(_obj, _class, _fieldName, _newValue)\
  74     GET_FIELD_ID(field, _class, _fieldName, "I");\
  75     NSK_CPP_STUB4(SetIntField, env, _obj, field, _newValue)
  76 
  77 #define GET_OBJ_FIELD(_value, _obj, _class, _fieldName, _fieldSig)\
  78     GET_FIELD_ID(field, _class, _fieldName, _fieldSig);\
  79     _value = NSK_CPP_STUB3(GetObjectField, env, _obj, field)
  80 
  81 
  82 #define GET_ARR_ELEMENT(_arr, _index)\
  83     NSK_CPP_STUB3(GetObjectArrayElement, env, _arr, _index)
  84 
  85 #define SET_ARR_ELEMENT(_arr, _index, _newValue)\
  86     NSK_CPP_STUB4(SetObjectArrayElement, env, _arr, _index, _newValue)
  87 
  88 #define GET_STATIC_METHOD_ID(_methodID, _class, _methodName, _sig)\
  89     if (!NSK_JNI_VERIFY(env, (_methodID = \
  90             NSK_CPP_STUB4(GetStaticMethodID, env, _class,\
  91                 _methodName, _sig)) != NULL))\
  92         return
  93 
  94 #define GET_METHOD_ID(_methodID, _class, _methodName, _sig)\
  95     if (!NSK_JNI_VERIFY(env, (_methodID = \
  96             NSK_CPP_STUB4(GetMethodID, env, _class,\
  97                 _methodName, _sig)) != NULL))\
  98         return
  99 
 100 #define CALL_STATIC_VOID_NOPARAM(_class, _methodName)\
 101     GET_STATIC_METHOD_ID(method, _class, _methodName, "()V");\
 102     if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB3(CallStaticVoidMethod, env,\
 103                             _class, method)))\
 104         return
 105 
 106 #define CALL_STATIC_VOID(_class, _methodName, _sig, _param)\
 107     GET_STATIC_METHOD_ID(method, _class, _methodName, _sig);\
 108     if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB4(CallStaticVoidMethod, env,\
 109                                                     _class, method, _param)))\
 110         return
 111 
 112 #define CALL_VOID_NOPARAM(_obj, _class, _methodName)\
 113     GET_METHOD_ID(method, _class, _methodName, "()V");\
 114     if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB3(CallVoidMethod, env, _obj,\
 115                                                     method)))\
 116         return
 117 
 118 #define CALL_VOID(_obj, _class, _methodName, _sig, _param)\
 119     GET_METHOD_ID(method, _class, _methodName, _sig);\
 120     if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB4(CallVoidMethod, env, _obj,\
 121                                                     method, _param)))\
 122         return
 123 
 124 #define CALL_VOID2(_obj, _class, _methodName, _sig, _param1, _param2)\
 125     GET_METHOD_ID(method, _class, _methodName, _sig);\
 126     if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB5(CallVoidMethod, env, _obj, \
 127                                                     method, _param1, _param2)))\
 128         return
 129 
 130 #define CALL_INT_NOPARAM(_value, _obj, _class, _methodName)\
 131     GET_METHOD_ID(method, _class, _methodName, "()I");\
 132     _value = NSK_CPP_STUB3(CallIntMethod, env, _obj, method)
 133 
 134 #define NEW_OBJ(_obj, _class, _constructorName, _sig, _params)\
 135     GET_METHOD_ID(method, _class, _constructorName, _sig);\
 136     if (!NSK_JNI_VERIFY(env, (_obj = \
 137             NSK_CPP_STUB4(NewObject, env, _class, method, _params)) != NULL))\
 138         return
 139 
 140 #define MONITOR_ENTER(x) \
 141     NSK_JNI_VERIFY(env, NSK_CPP_STUB2(MonitorEnter, env, x) == 0)
 142 
 143 #define MONITOR_EXIT(x) \
 144     NSK_JNI_VERIFY(env, NSK_CPP_STUB2(MonitorExit, env, x) == 0)
 145 
 146 #define TRACE(msg)\
 147    GET_OBJ_FIELD(logger, obj, threadClass, "logger", "Lnsk/share/Log$Logger;");\
 148    jmsg = NSK_CPP_STUB2(NewStringUTF, env, msg);\
 149    CALL_VOID2(logger, loggerClass, "trace",\
 150                            "(ILjava/lang/String;)V", 50, jmsg)
 151 
 152 
 153 /*
 154  * Class:     nsk_monitoring_share_thread_RecursiveMonitoringThread
 155  * Method:    nativeRecursiveMethod
 156  * Signature: (IZ)V
 157  */
 158 JNIEXPORT void JNICALL Java_nsk_monitoring_share_thread_RecursiveMonitoringThread_nativeRecursiveMethod
 159 (JNIEnv *env, jobject o, jint currentDepth, jboolean pureNative) {
 160         jclass klass;
 161         jmethodID method;
 162 
 163         GET_OBJECT_CLASS(klass, o);
 164         if (currentDepth-- > 0) {
 165 /*              printf("Current depth: %d\n", currentDepth); */
 166                 CALL_STATIC_VOID_NOPARAM(klass, "yield");
 167                 if (pureNative == JNI_TRUE) {
 168                         CALL_VOID2(o, klass, "nativeRecursiveMethod", "(IZ)V", currentDepth, pureNative);
 169                 } else {
 170                         CALL_VOID(o, klass, "recursiveMethod", "(I)V", currentDepth);
 171                 }
 172         } else {
 173                 CALL_VOID_NOPARAM(o, klass, "runInside");
 174         }
 175 }
 176 
 177 }
 178