jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c
changeset 41198 f7477110f0d7
parent 38352 b0ac5e2b8641
child 41359 23b0a20c3e3c
equal deleted inserted replaced
41197:d98087633032 41198:f7477110f0d7
   209     }
   209     }
   210 
   210 
   211     return error;
   211     return error;
   212 }
   212 }
   213 
   213 
       
   214 /*
       
   215  * Delete saved global references - if any - for:
       
   216  * - a potentially thrown Exception
       
   217  * - a returned refernce/array value
       
   218  * See invoker_doInvoke() and invoke* methods where global references
       
   219  * are being saved.
       
   220  */
       
   221 static void
       
   222 deletePotentiallySavedGlobalRefs(JNIEnv *env, InvokeRequest *request)
       
   223 {
       
   224     /* Delete potentially saved return value */
       
   225     if ((request->invokeType == INVOKE_CONSTRUCTOR) ||
       
   226         (returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT)) ||
       
   227         (returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY))) {
       
   228         if (request->returnValue.l != NULL) {
       
   229             tossGlobalRef(env, &(request->returnValue.l));
       
   230         }
       
   231     }
       
   232     /* Delete potentially saved exception */
       
   233     if (request->exception != NULL) {
       
   234         tossGlobalRef(env, &(request->exception));
       
   235     }
       
   236 }
       
   237 
       
   238 /*
       
   239  * Delete global argument references from the request which got put there before a
       
   240  * invoke request was carried out. See fillInvokeRequest().
       
   241  */
       
   242 static void
       
   243 deleteGlobalArgumentRefs(JNIEnv *env, InvokeRequest *request)
       
   244 {
       
   245     void *cursor;
       
   246     jint argIndex = 0;
       
   247     jvalue *argument = request->arguments;
       
   248     jbyte argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
       
   249 
       
   250     if (request->clazz != NULL) {
       
   251         tossGlobalRef(env, &(request->clazz));
       
   252     }
       
   253     if (request->instance != NULL) {
       
   254         tossGlobalRef(env, &(request->instance));
       
   255     }
       
   256     /* Delete global argument references */
       
   257     while (argIndex < request->argumentCount) {
       
   258         if ((argumentTag == JDWP_TAG(OBJECT)) ||
       
   259             (argumentTag == JDWP_TAG(ARRAY))) {
       
   260             if (argument->l != NULL) {
       
   261                 tossGlobalRef(env, &(argument->l));
       
   262             }
       
   263         }
       
   264         argument++;
       
   265         argIndex++;
       
   266         argumentTag = nextArgumentTypeTag(&cursor);
       
   267     }
       
   268 }
       
   269 
   214 static jvmtiError
   270 static jvmtiError
   215 fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
   271 fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
   216                   jbyte invokeType, jbyte options, jint id,
   272                   jbyte invokeType, jbyte options, jint id,
   217                   jthread thread, jclass clazz, jmethodID method,
   273                   jthread thread, jclass clazz, jmethodID method,
   218                   jobject instance,
   274                   jobject instance,
   320 
   376 
   321 static void
   377 static void
   322 invokeConstructor(JNIEnv *env, InvokeRequest *request)
   378 invokeConstructor(JNIEnv *env, InvokeRequest *request)
   323 {
   379 {
   324     jobject object;
   380     jobject object;
       
   381 
       
   382     JDI_ASSERT_MSG(request->clazz, "Request clazz null");
   325     object = JNI_FUNC_PTR(env,NewObjectA)(env, request->clazz,
   383     object = JNI_FUNC_PTR(env,NewObjectA)(env, request->clazz,
   326                                      request->method,
   384                                      request->method,
   327                                      request->arguments);
   385                                      request->arguments);
   328     request->returnValue.l = NULL;
   386     request->returnValue.l = NULL;
   329     if (object != NULL) {
   387     if (object != NULL) {
   336 {
   394 {
   337     switch(returnTypeTag(request->methodSignature)) {
   395     switch(returnTypeTag(request->methodSignature)) {
   338         case JDWP_TAG(OBJECT):
   396         case JDWP_TAG(OBJECT):
   339         case JDWP_TAG(ARRAY): {
   397         case JDWP_TAG(ARRAY): {
   340             jobject object;
   398             jobject object;
       
   399             JDI_ASSERT_MSG(request->clazz, "Request clazz null");
   341             object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
   400             object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
   342                                        request->clazz,
   401                                        request->clazz,
   343                                        request->method,
   402                                        request->method,
   344                                        request->arguments);
   403                                        request->arguments);
   345             request->returnValue.l = NULL;
   404             request->returnValue.l = NULL;
   424 {
   483 {
   425     switch(returnTypeTag(request->methodSignature)) {
   484     switch(returnTypeTag(request->methodSignature)) {
   426         case JDWP_TAG(OBJECT):
   485         case JDWP_TAG(OBJECT):
   427         case JDWP_TAG(ARRAY): {
   486         case JDWP_TAG(ARRAY): {
   428             jobject object;
   487             jobject object;
       
   488             JDI_ASSERT_MSG(request->instance, "Request instance null");
   429             object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
   489             object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
   430                                  request->instance,
   490                                  request->instance,
   431                                  request->method,
   491                                  request->method,
   432                                  request->arguments);
   492                                  request->arguments);
   433             request->returnValue.l = NULL;
   493             request->returnValue.l = NULL;
   511 {
   571 {
   512     switch(returnTypeTag(request->methodSignature)) {
   572     switch(returnTypeTag(request->methodSignature)) {
   513         case JDWP_TAG(OBJECT):
   573         case JDWP_TAG(OBJECT):
   514         case JDWP_TAG(ARRAY): {
   574         case JDWP_TAG(ARRAY): {
   515             jobject object;
   575             jobject object;
       
   576             JDI_ASSERT_MSG(request->clazz, "Request clazz null");
       
   577             JDI_ASSERT_MSG(request->instance, "Request instance null");
   516             object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
   578             object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
   517                                            request->instance,
   579                                            request->instance,
   518                                            request->clazz,
   580                                            request->clazz,
   519                                            request->method,
   581                                            request->method,
   520                                            request->arguments);
   582                                            request->arguments);
   607 invoker_doInvoke(jthread thread)
   669 invoker_doInvoke(jthread thread)
   608 {
   670 {
   609     JNIEnv *env;
   671     JNIEnv *env;
   610     jboolean startNow;
   672     jboolean startNow;
   611     InvokeRequest *request;
   673     InvokeRequest *request;
       
   674     jbyte options;
       
   675     jbyte invokeType;
   612 
   676 
   613     JDI_ASSERT(thread);
   677     JDI_ASSERT(thread);
   614 
   678 
   615     debugMonitorEnter(invokerLock);
   679     debugMonitorEnter(invokerLock);
   616 
   680 
   623     startNow = request->pending && !request->started;
   687     startNow = request->pending && !request->started;
   624 
   688 
   625     if (startNow) {
   689     if (startNow) {
   626         request->started = JNI_TRUE;
   690         request->started = JNI_TRUE;
   627     }
   691     }
       
   692     options = request->options;
       
   693     invokeType = request->invokeType;
       
   694 
   628     debugMonitorExit(invokerLock);
   695     debugMonitorExit(invokerLock);
   629 
   696 
   630     if (!startNow) {
   697     if (!startNow) {
   631         return JNI_FALSE;
   698         return JNI_FALSE;
   632     }
   699     }
   637 
   704 
   638         jobject exception;
   705         jobject exception;
   639 
   706 
   640         JNI_FUNC_PTR(env,ExceptionClear)(env);
   707         JNI_FUNC_PTR(env,ExceptionClear)(env);
   641 
   708 
   642         switch (request->invokeType) {
   709         switch (invokeType) {
   643             case INVOKE_CONSTRUCTOR:
   710             case INVOKE_CONSTRUCTOR:
   644                 invokeConstructor(env, request);
   711                 invokeConstructor(env, request);
   645                 break;
   712                 break;
   646             case INVOKE_STATIC:
   713             case INVOKE_STATIC:
   647                 invokeStatic(env, request);
   714                 invokeStatic(env, request);
   648                 break;
   715                 break;
   649             case INVOKE_INSTANCE:
   716             case INVOKE_INSTANCE:
   650                 if (request->options & JDWP_INVOKE_OPTIONS(NONVIRTUAL) ) {
   717                 if (options & JDWP_INVOKE_OPTIONS(NONVIRTUAL) ) {
   651                     invokeNonvirtual(env, request);
   718                     invokeNonvirtual(env, request);
   652                 } else {
   719                 } else {
   653                     invokeVirtual(env, request);
   720                     invokeVirtual(env, request);
   654                 }
   721                 }
   655                 break;
   722                 break;
   723         exc = request->exception;
   790         exc = request->exception;
   724         returnValue = request->returnValue;
   791         returnValue = request->returnValue;
   725     }
   792     }
   726 
   793 
   727     /*
   794     /*
       
   795      * At this time, there's no need to retain global references on
       
   796      * arguments since the reply is processed. No one will deal with
       
   797      * this request ID anymore, so we must call deleteGlobalArgumentRefs().
       
   798      *
       
   799      * We cannot delete saved exception or return value references
       
   800      * since otherwise a deleted handle would escape when writing
       
   801      * the response to the stream. Instead, we clean those refs up
       
   802      * after writing the respone.
       
   803      */
       
   804     deleteGlobalArgumentRefs(env, request);
       
   805 
       
   806     /*
   728      * Give up the lock before I/O operation
   807      * Give up the lock before I/O operation
   729      */
   808      */
   730     debugMonitorExit(invokerLock);
   809     debugMonitorExit(invokerLock);
   731     eventHandler_unlock();
   810     eventHandler_unlock();
   732 
       
   733 
   811 
   734     if (!detached) {
   812     if (!detached) {
   735         outStream_initReply(&out, id);
   813         outStream_initReply(&out, id);
   736         (void)outStream_writeValue(env, &out, tag, returnValue);
   814         (void)outStream_writeValue(env, &out, tag, returnValue);
   737         (void)outStream_writeObjectTag(env, &out, exc);
   815         (void)outStream_writeObjectTag(env, &out, exc);
   738         (void)outStream_writeObjectRef(env, &out, exc);
   816         (void)outStream_writeObjectRef(env, &out, exc);
   739         outStream_sendReply(&out);
   817         outStream_sendReply(&out);
   740     }
   818     }
       
   819 
       
   820     /*
       
   821      * Delete potentially saved global references of return value
       
   822      * and exception
       
   823      */
       
   824     eventHandler_lock(); // for proper lock order
       
   825     debugMonitorEnter(invokerLock);
       
   826     deletePotentiallySavedGlobalRefs(env, request);
       
   827     debugMonitorExit(invokerLock);
       
   828     eventHandler_unlock();
   741 }
   829 }
   742 
   830 
   743 jboolean
   831 jboolean
   744 invoker_isEnabled(jthread thread)
   832 invoker_isEnabled(jthread thread)
   745 {
   833 {