194 /* Delete global references */ 195 if ( clazz != NULL ) { 196 tossGlobalRef(env, &clazz); 197 } 198 if ( instance != NULL ) { 199 tossGlobalRef(env, &instance); 200 } 201 if ( argRefs!=NULL ) { 202 for ( argIndex=0; argIndex < request->argumentCount; argIndex++ ) { 203 if ( argRefs[argIndex] != NULL ) { 204 tossGlobalRef(env, &argRefs[argIndex]); 205 } 206 } 207 jvmtiDeallocate(argRefs); 208 } 209 } 210 211 return error; 212 } 213 214 /* 215 * Delete global references from the request which got put there before a 216 * invoke request was carried out. See fillInvokeRequest() and invoker invoke*() 217 * impls. 218 */ 219 static void 220 deleteGlobalRefs(JNIEnv *env, InvokeRequest *request) 221 { 222 void *cursor; 223 jint argIndex = 0; 224 jvalue *argument = request->arguments; 225 jbyte argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor); 226 227 if (request->clazz != NULL) { 228 tossGlobalRef(env, &(request->clazz)); 229 } 230 if (request->instance != NULL) { 231 tossGlobalRef(env, &(request->instance)); 232 } 233 /* Delete global argument references */ 234 while (argIndex < request->argumentCount) { 235 if ((argumentTag == JDWP_TAG(OBJECT)) || 236 (argumentTag == JDWP_TAG(ARRAY))) { 237 if (argument->l != NULL) { 238 tossGlobalRef(env, &(argument->l)); 239 } 240 } 241 argument++; 242 argIndex++; 243 argumentTag = nextArgumentTypeTag(&cursor); 244 } 245 /* Delete potentially saved return values */ 246 if ((request->invokeType == INVOKE_CONSTRUCTOR) || 247 (returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT)) || 248 (returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY))) { 249 if (request->returnValue.l != NULL) { 250 tossGlobalRef(env, &(request->returnValue.l)); 251 } 252 } 253 } 254 255 static jvmtiError 256 fillInvokeRequest(JNIEnv *env, InvokeRequest *request, 257 jbyte invokeType, jbyte options, jint id, 258 jthread thread, jclass clazz, jmethodID method, 259 jobject instance, 260 jvalue *arguments, jint argumentCount) 261 { 262 jvmtiError error; 263 if (!request->available) { 264 /* 265 * Thread is not at a point where it can invoke. 266 */ 267 return AGENT_ERROR_INVALID_THREAD; 268 } 269 if (request->pending) { 270 /* 271 * Pending invoke 272 */ 273 return AGENT_ERROR_ALREADY_INVOKING; 274 } 760 } 761 id = request->id; 762 exc = request->exception; 763 returnValue = request->returnValue; 764 } 765 766 /* 767 * Give up the lock before I/O operation 768 */ 769 debugMonitorExit(invokerLock); 770 eventHandler_unlock(); 771 772 773 if (!detached) { 774 outStream_initReply(&out, id); 775 (void)outStream_writeValue(env, &out, tag, returnValue); 776 (void)outStream_writeObjectTag(env, &out, exc); 777 (void)outStream_writeObjectRef(env, &out, exc); 778 outStream_sendReply(&out); 779 } 780 781 /* 782 * At this time, there's no need to retain global references on 783 * arguments since the reply is processed. No one will deal with 784 * this request ID anymore, so we must call deleteGlobalRefs(). 785 */ 786 deleteGlobalRefs(env, request); 787 } 788 789 jboolean 790 invoker_isPending(jthread thread) 791 { 792 InvokeRequest *request; 793 794 JDI_ASSERT(thread); 795 request = threadControl_getInvokeRequest(thread); 796 if (request == NULL) { 797 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"); 798 } 799 return request->pending; 800 } 801 802 jboolean 803 invoker_isEnabled(jthread thread) 804 { 805 InvokeRequest *request; 806 | 194 /* Delete global references */ 195 if ( clazz != NULL ) { 196 tossGlobalRef(env, &clazz); 197 } 198 if ( instance != NULL ) { 199 tossGlobalRef(env, &instance); 200 } 201 if ( argRefs!=NULL ) { 202 for ( argIndex=0; argIndex < request->argumentCount; argIndex++ ) { 203 if ( argRefs[argIndex] != NULL ) { 204 tossGlobalRef(env, &argRefs[argIndex]); 205 } 206 } 207 jvmtiDeallocate(argRefs); 208 } 209 } 210 211 return error; 212 } 213 214 static jvmtiError 215 fillInvokeRequest(JNIEnv *env, InvokeRequest *request, 216 jbyte invokeType, jbyte options, jint id, 217 jthread thread, jclass clazz, jmethodID method, 218 jobject instance, 219 jvalue *arguments, jint argumentCount) 220 { 221 jvmtiError error; 222 if (!request->available) { 223 /* 224 * Thread is not at a point where it can invoke. 225 */ 226 return AGENT_ERROR_INVALID_THREAD; 227 } 228 if (request->pending) { 229 /* 230 * Pending invoke 231 */ 232 return AGENT_ERROR_ALREADY_INVOKING; 233 } 719 } 720 id = request->id; 721 exc = request->exception; 722 returnValue = request->returnValue; 723 } 724 725 /* 726 * Give up the lock before I/O operation 727 */ 728 debugMonitorExit(invokerLock); 729 eventHandler_unlock(); 730 731 732 if (!detached) { 733 outStream_initReply(&out, id); 734 (void)outStream_writeValue(env, &out, tag, returnValue); 735 (void)outStream_writeObjectTag(env, &out, exc); 736 (void)outStream_writeObjectRef(env, &out, exc); 737 outStream_sendReply(&out); 738 } 739 } 740 741 jboolean 742 invoker_isPending(jthread thread) 743 { 744 InvokeRequest *request; 745 746 JDI_ASSERT(thread); 747 request = threadControl_getInvokeRequest(thread); 748 if (request == NULL) { 749 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"); 750 } 751 return request->pending; 752 } 753 754 jboolean 755 invoker_isEnabled(jthread thread) 756 { 757 InvokeRequest *request; 758 |