xref: /aosp_15_r20/external/oj-libjdwp/src/share/back/invoker.c (revision e82f7db8c62aed3c168547abe4f9f4aeceaebfc7)
1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker  * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker  *
5*e82f7db8SAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker  *
11*e82f7db8SAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker  * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker  *
17*e82f7db8SAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker  *
21*e82f7db8SAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker  * questions.
24*e82f7db8SAndroid Build Coastguard Worker  */
25*e82f7db8SAndroid Build Coastguard Worker 
26*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
27*e82f7db8SAndroid Build Coastguard Worker #include "invoker.h"
28*e82f7db8SAndroid Build Coastguard Worker #include "eventHandler.h"
29*e82f7db8SAndroid Build Coastguard Worker #include "threadControl.h"
30*e82f7db8SAndroid Build Coastguard Worker #include "outStream.h"
31*e82f7db8SAndroid Build Coastguard Worker 
32*e82f7db8SAndroid Build Coastguard Worker static jrawMonitorID invokerLock;
33*e82f7db8SAndroid Build Coastguard Worker 
34*e82f7db8SAndroid Build Coastguard Worker void
invoker_initialize(void)35*e82f7db8SAndroid Build Coastguard Worker invoker_initialize(void)
36*e82f7db8SAndroid Build Coastguard Worker {
37*e82f7db8SAndroid Build Coastguard Worker     invokerLock = debugMonitorCreate("JDWP Invocation Lock");
38*e82f7db8SAndroid Build Coastguard Worker }
39*e82f7db8SAndroid Build Coastguard Worker 
40*e82f7db8SAndroid Build Coastguard Worker void
invoker_reset(void)41*e82f7db8SAndroid Build Coastguard Worker invoker_reset(void)
42*e82f7db8SAndroid Build Coastguard Worker {
43*e82f7db8SAndroid Build Coastguard Worker }
44*e82f7db8SAndroid Build Coastguard Worker 
invoker_lock(void)45*e82f7db8SAndroid Build Coastguard Worker void invoker_lock(void)
46*e82f7db8SAndroid Build Coastguard Worker {
47*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
48*e82f7db8SAndroid Build Coastguard Worker }
49*e82f7db8SAndroid Build Coastguard Worker 
invoker_unlock(void)50*e82f7db8SAndroid Build Coastguard Worker void invoker_unlock(void)
51*e82f7db8SAndroid Build Coastguard Worker {
52*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
53*e82f7db8SAndroid Build Coastguard Worker }
54*e82f7db8SAndroid Build Coastguard Worker 
55*e82f7db8SAndroid Build Coastguard Worker static jbyte
returnTypeTag(char * signature)56*e82f7db8SAndroid Build Coastguard Worker returnTypeTag(char *signature)
57*e82f7db8SAndroid Build Coastguard Worker {
58*e82f7db8SAndroid Build Coastguard Worker     char *tagPtr = strchr(signature, SIGNATURE_END_ARGS);
59*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(tagPtr);
60*e82f7db8SAndroid Build Coastguard Worker     tagPtr++;    /* 1st character after the end of args */
61*e82f7db8SAndroid Build Coastguard Worker     return (jbyte)*tagPtr;
62*e82f7db8SAndroid Build Coastguard Worker }
63*e82f7db8SAndroid Build Coastguard Worker 
64*e82f7db8SAndroid Build Coastguard Worker static jbyte
nextArgumentTypeTag(void ** cursor)65*e82f7db8SAndroid Build Coastguard Worker nextArgumentTypeTag(void **cursor)
66*e82f7db8SAndroid Build Coastguard Worker {
67*e82f7db8SAndroid Build Coastguard Worker     char *tagPtr = *cursor;
68*e82f7db8SAndroid Build Coastguard Worker     jbyte argumentTag = (jbyte)*tagPtr;
69*e82f7db8SAndroid Build Coastguard Worker 
70*e82f7db8SAndroid Build Coastguard Worker     if (*tagPtr != SIGNATURE_END_ARGS) {
71*e82f7db8SAndroid Build Coastguard Worker         /* Skip any array modifiers */
72*e82f7db8SAndroid Build Coastguard Worker         while (*tagPtr == JDWP_TAG(ARRAY)) {
73*e82f7db8SAndroid Build Coastguard Worker             tagPtr++;
74*e82f7db8SAndroid Build Coastguard Worker         }
75*e82f7db8SAndroid Build Coastguard Worker         /* Skip class name */
76*e82f7db8SAndroid Build Coastguard Worker         if (*tagPtr == JDWP_TAG(OBJECT)) {
77*e82f7db8SAndroid Build Coastguard Worker             tagPtr = strchr(tagPtr, SIGNATURE_END_CLASS) + 1;
78*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT(tagPtr);
79*e82f7db8SAndroid Build Coastguard Worker         } else {
80*e82f7db8SAndroid Build Coastguard Worker             /* Skip primitive sig */
81*e82f7db8SAndroid Build Coastguard Worker             tagPtr++;
82*e82f7db8SAndroid Build Coastguard Worker         }
83*e82f7db8SAndroid Build Coastguard Worker     }
84*e82f7db8SAndroid Build Coastguard Worker 
85*e82f7db8SAndroid Build Coastguard Worker     *cursor = tagPtr;
86*e82f7db8SAndroid Build Coastguard Worker     return argumentTag;
87*e82f7db8SAndroid Build Coastguard Worker }
88*e82f7db8SAndroid Build Coastguard Worker 
89*e82f7db8SAndroid Build Coastguard Worker static jbyte
firstArgumentTypeTag(char * signature,void ** cursor)90*e82f7db8SAndroid Build Coastguard Worker firstArgumentTypeTag(char *signature, void **cursor)
91*e82f7db8SAndroid Build Coastguard Worker {
92*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(signature[0] == SIGNATURE_BEGIN_ARGS);
93*e82f7db8SAndroid Build Coastguard Worker     *cursor = signature + 1; /* skip to the first arg */
94*e82f7db8SAndroid Build Coastguard Worker     return nextArgumentTypeTag(cursor);
95*e82f7db8SAndroid Build Coastguard Worker }
96*e82f7db8SAndroid Build Coastguard Worker 
97*e82f7db8SAndroid Build Coastguard Worker 
98*e82f7db8SAndroid Build Coastguard Worker /*
99*e82f7db8SAndroid Build Coastguard Worker  * Note: argument refs may be destroyed on out-of-memory error
100*e82f7db8SAndroid Build Coastguard Worker  */
101*e82f7db8SAndroid Build Coastguard Worker static jvmtiError
createGlobalRefs(JNIEnv * env,InvokeRequest * request)102*e82f7db8SAndroid Build Coastguard Worker createGlobalRefs(JNIEnv *env, InvokeRequest *request)
103*e82f7db8SAndroid Build Coastguard Worker {
104*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
105*e82f7db8SAndroid Build Coastguard Worker     jclass clazz = NULL;
106*e82f7db8SAndroid Build Coastguard Worker     jobject instance = NULL;
107*e82f7db8SAndroid Build Coastguard Worker     jint argIndex;
108*e82f7db8SAndroid Build Coastguard Worker     jbyte argumentTag;
109*e82f7db8SAndroid Build Coastguard Worker     jvalue *argument;
110*e82f7db8SAndroid Build Coastguard Worker     void *cursor;
111*e82f7db8SAndroid Build Coastguard Worker     jobject *argRefs = NULL;
112*e82f7db8SAndroid Build Coastguard Worker 
113*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_ERROR_NONE;
114*e82f7db8SAndroid Build Coastguard Worker 
115*e82f7db8SAndroid Build Coastguard Worker     if ( request->argumentCount > 0 ) {
116*e82f7db8SAndroid Build Coastguard Worker         /*LINTED*/
117*e82f7db8SAndroid Build Coastguard Worker         argRefs = jvmtiAllocate((jint)(request->argumentCount*sizeof(jobject)));
118*e82f7db8SAndroid Build Coastguard Worker         if ( argRefs==NULL ) {
119*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_OUT_OF_MEMORY;
120*e82f7db8SAndroid Build Coastguard Worker         } else {
121*e82f7db8SAndroid Build Coastguard Worker             /*LINTED*/
122*e82f7db8SAndroid Build Coastguard Worker             (void)memset(argRefs, 0, request->argumentCount*sizeof(jobject));
123*e82f7db8SAndroid Build Coastguard Worker         }
124*e82f7db8SAndroid Build Coastguard Worker     }
125*e82f7db8SAndroid Build Coastguard Worker 
126*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
127*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, request->clazz, &clazz);
128*e82f7db8SAndroid Build Coastguard Worker         if (clazz == NULL) {
129*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_OUT_OF_MEMORY;
130*e82f7db8SAndroid Build Coastguard Worker         }
131*e82f7db8SAndroid Build Coastguard Worker     }
132*e82f7db8SAndroid Build Coastguard Worker 
133*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE && request->instance != NULL ) {
134*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, request->instance, &instance);
135*e82f7db8SAndroid Build Coastguard Worker         if (instance == NULL) {
136*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_OUT_OF_MEMORY;
137*e82f7db8SAndroid Build Coastguard Worker         }
138*e82f7db8SAndroid Build Coastguard Worker     }
139*e82f7db8SAndroid Build Coastguard Worker 
140*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE && argRefs!=NULL ) {
141*e82f7db8SAndroid Build Coastguard Worker         argIndex = 0;
142*e82f7db8SAndroid Build Coastguard Worker         argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
143*e82f7db8SAndroid Build Coastguard Worker         argument = request->arguments;
144*e82f7db8SAndroid Build Coastguard Worker         while (argumentTag != SIGNATURE_END_ARGS) {
145*e82f7db8SAndroid Build Coastguard Worker             if ( argIndex > request->argumentCount ) {
146*e82f7db8SAndroid Build Coastguard Worker                 break;
147*e82f7db8SAndroid Build Coastguard Worker             }
148*e82f7db8SAndroid Build Coastguard Worker             if ((argumentTag == JDWP_TAG(OBJECT)) ||
149*e82f7db8SAndroid Build Coastguard Worker                 (argumentTag == JDWP_TAG(ARRAY))) {
150*e82f7db8SAndroid Build Coastguard Worker                 /* Create a global ref for any non-null argument */
151*e82f7db8SAndroid Build Coastguard Worker                 if (argument->l != NULL) {
152*e82f7db8SAndroid Build Coastguard Worker                     saveGlobalRef(env, argument->l, &argRefs[argIndex]);
153*e82f7db8SAndroid Build Coastguard Worker                     if (argRefs[argIndex] == NULL) {
154*e82f7db8SAndroid Build Coastguard Worker                         error = AGENT_ERROR_OUT_OF_MEMORY;
155*e82f7db8SAndroid Build Coastguard Worker                         break;
156*e82f7db8SAndroid Build Coastguard Worker                     }
157*e82f7db8SAndroid Build Coastguard Worker                 }
158*e82f7db8SAndroid Build Coastguard Worker             }
159*e82f7db8SAndroid Build Coastguard Worker             argument++;
160*e82f7db8SAndroid Build Coastguard Worker             argIndex++;
161*e82f7db8SAndroid Build Coastguard Worker             argumentTag = nextArgumentTypeTag(&cursor);
162*e82f7db8SAndroid Build Coastguard Worker         }
163*e82f7db8SAndroid Build Coastguard Worker     }
164*e82f7db8SAndroid Build Coastguard Worker 
165*e82f7db8SAndroid Build Coastguard Worker #ifdef FIXUP /* Why isn't this an error? */
166*e82f7db8SAndroid Build Coastguard Worker     /* Make sure the argument count matches */
167*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE && argIndex != request->argumentCount ) {
168*e82f7db8SAndroid Build Coastguard Worker         error = AGENT_ERROR_INVALID_COUNT;
169*e82f7db8SAndroid Build Coastguard Worker     }
170*e82f7db8SAndroid Build Coastguard Worker #endif
171*e82f7db8SAndroid Build Coastguard Worker 
172*e82f7db8SAndroid Build Coastguard Worker     /* Finally, put the global refs into the request if no errors */
173*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
174*e82f7db8SAndroid Build Coastguard Worker         request->clazz = clazz;
175*e82f7db8SAndroid Build Coastguard Worker         request->instance = instance;
176*e82f7db8SAndroid Build Coastguard Worker         if ( argRefs!=NULL ) {
177*e82f7db8SAndroid Build Coastguard Worker             argIndex = 0;
178*e82f7db8SAndroid Build Coastguard Worker             argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
179*e82f7db8SAndroid Build Coastguard Worker             argument = request->arguments;
180*e82f7db8SAndroid Build Coastguard Worker             while ( argIndex < request->argumentCount ) {
181*e82f7db8SAndroid Build Coastguard Worker                 if ((argumentTag == JDWP_TAG(OBJECT)) ||
182*e82f7db8SAndroid Build Coastguard Worker                     (argumentTag == JDWP_TAG(ARRAY))) {
183*e82f7db8SAndroid Build Coastguard Worker                     argument->l = argRefs[argIndex];
184*e82f7db8SAndroid Build Coastguard Worker                 }
185*e82f7db8SAndroid Build Coastguard Worker                 argument++;
186*e82f7db8SAndroid Build Coastguard Worker                 argIndex++;
187*e82f7db8SAndroid Build Coastguard Worker                 argumentTag = nextArgumentTypeTag(&cursor);
188*e82f7db8SAndroid Build Coastguard Worker             }
189*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(argRefs);
190*e82f7db8SAndroid Build Coastguard Worker         }
191*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_ERROR_NONE;
192*e82f7db8SAndroid Build Coastguard Worker 
193*e82f7db8SAndroid Build Coastguard Worker     } else {
194*e82f7db8SAndroid Build Coastguard Worker         /* Delete global references */
195*e82f7db8SAndroid Build Coastguard Worker         if ( clazz != NULL ) {
196*e82f7db8SAndroid Build Coastguard Worker             tossGlobalRef(env, &clazz);
197*e82f7db8SAndroid Build Coastguard Worker         }
198*e82f7db8SAndroid Build Coastguard Worker         if ( instance != NULL ) {
199*e82f7db8SAndroid Build Coastguard Worker             tossGlobalRef(env, &instance);
200*e82f7db8SAndroid Build Coastguard Worker         }
201*e82f7db8SAndroid Build Coastguard Worker         if ( argRefs!=NULL ) {
202*e82f7db8SAndroid Build Coastguard Worker             for ( argIndex=0; argIndex < request->argumentCount; argIndex++ ) {
203*e82f7db8SAndroid Build Coastguard Worker                 if ( argRefs[argIndex] != NULL ) {
204*e82f7db8SAndroid Build Coastguard Worker                     tossGlobalRef(env, &argRefs[argIndex]);
205*e82f7db8SAndroid Build Coastguard Worker                 }
206*e82f7db8SAndroid Build Coastguard Worker             }
207*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(argRefs);
208*e82f7db8SAndroid Build Coastguard Worker         }
209*e82f7db8SAndroid Build Coastguard Worker     }
210*e82f7db8SAndroid Build Coastguard Worker 
211*e82f7db8SAndroid Build Coastguard Worker     return error;
212*e82f7db8SAndroid Build Coastguard Worker }
213*e82f7db8SAndroid Build Coastguard Worker 
214*e82f7db8SAndroid Build Coastguard Worker /*
215*e82f7db8SAndroid Build Coastguard Worker  * Delete saved global references - if any - for:
216*e82f7db8SAndroid Build Coastguard Worker  * - a potentially thrown Exception
217*e82f7db8SAndroid Build Coastguard Worker  * - a returned refernce/array value
218*e82f7db8SAndroid Build Coastguard Worker  * See invoker_doInvoke() and invoke* methods where global references
219*e82f7db8SAndroid Build Coastguard Worker  * are being saved.
220*e82f7db8SAndroid Build Coastguard Worker  */
221*e82f7db8SAndroid Build Coastguard Worker static void
deletePotentiallySavedGlobalRefs(JNIEnv * env,InvokeRequest * request)222*e82f7db8SAndroid Build Coastguard Worker deletePotentiallySavedGlobalRefs(JNIEnv *env, InvokeRequest *request)
223*e82f7db8SAndroid Build Coastguard Worker {
224*e82f7db8SAndroid Build Coastguard Worker     /* Delete potentially saved return value */
225*e82f7db8SAndroid Build Coastguard Worker     if ((request->invokeType == INVOKE_CONSTRUCTOR) ||
226*e82f7db8SAndroid Build Coastguard Worker         (returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT)) ||
227*e82f7db8SAndroid Build Coastguard Worker         (returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY))) {
228*e82f7db8SAndroid Build Coastguard Worker         if (request->returnValue.l != NULL) {
229*e82f7db8SAndroid Build Coastguard Worker             tossGlobalRef(env, &(request->returnValue.l));
230*e82f7db8SAndroid Build Coastguard Worker         }
231*e82f7db8SAndroid Build Coastguard Worker     }
232*e82f7db8SAndroid Build Coastguard Worker     /* Delete potentially saved exception */
233*e82f7db8SAndroid Build Coastguard Worker     if (request->exception != NULL) {
234*e82f7db8SAndroid Build Coastguard Worker         tossGlobalRef(env, &(request->exception));
235*e82f7db8SAndroid Build Coastguard Worker     }
236*e82f7db8SAndroid Build Coastguard Worker }
237*e82f7db8SAndroid Build Coastguard Worker 
238*e82f7db8SAndroid Build Coastguard Worker /*
239*e82f7db8SAndroid Build Coastguard Worker  * Delete global argument references from the request which got put there before a
240*e82f7db8SAndroid Build Coastguard Worker  * invoke request was carried out. See fillInvokeRequest().
241*e82f7db8SAndroid Build Coastguard Worker  */
242*e82f7db8SAndroid Build Coastguard Worker static void
deleteGlobalArgumentRefs(JNIEnv * env,InvokeRequest * request)243*e82f7db8SAndroid Build Coastguard Worker deleteGlobalArgumentRefs(JNIEnv *env, InvokeRequest *request)
244*e82f7db8SAndroid Build Coastguard Worker {
245*e82f7db8SAndroid Build Coastguard Worker     void *cursor;
246*e82f7db8SAndroid Build Coastguard Worker     jint argIndex = 0;
247*e82f7db8SAndroid Build Coastguard Worker     jvalue *argument = request->arguments;
248*e82f7db8SAndroid Build Coastguard Worker     jbyte argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
249*e82f7db8SAndroid Build Coastguard Worker 
250*e82f7db8SAndroid Build Coastguard Worker     if (request->clazz != NULL) {
251*e82f7db8SAndroid Build Coastguard Worker         tossGlobalRef(env, &(request->clazz));
252*e82f7db8SAndroid Build Coastguard Worker     }
253*e82f7db8SAndroid Build Coastguard Worker     if (request->instance != NULL) {
254*e82f7db8SAndroid Build Coastguard Worker         tossGlobalRef(env, &(request->instance));
255*e82f7db8SAndroid Build Coastguard Worker     }
256*e82f7db8SAndroid Build Coastguard Worker     /* Delete global argument references */
257*e82f7db8SAndroid Build Coastguard Worker     while (argIndex < request->argumentCount) {
258*e82f7db8SAndroid Build Coastguard Worker         if ((argumentTag == JDWP_TAG(OBJECT)) ||
259*e82f7db8SAndroid Build Coastguard Worker             (argumentTag == JDWP_TAG(ARRAY))) {
260*e82f7db8SAndroid Build Coastguard Worker             if (argument->l != NULL) {
261*e82f7db8SAndroid Build Coastguard Worker                 tossGlobalRef(env, &(argument->l));
262*e82f7db8SAndroid Build Coastguard Worker             }
263*e82f7db8SAndroid Build Coastguard Worker         }
264*e82f7db8SAndroid Build Coastguard Worker         argument++;
265*e82f7db8SAndroid Build Coastguard Worker         argIndex++;
266*e82f7db8SAndroid Build Coastguard Worker         argumentTag = nextArgumentTypeTag(&cursor);
267*e82f7db8SAndroid Build Coastguard Worker     }
268*e82f7db8SAndroid Build Coastguard Worker }
269*e82f7db8SAndroid Build Coastguard Worker 
270*e82f7db8SAndroid Build Coastguard Worker static jvmtiError
fillInvokeRequest(JNIEnv * env,InvokeRequest * request,jbyte invokeType,jbyte options,jint id,jthread thread,jclass clazz,jmethodID method,jobject instance,jvalue * arguments,jint argumentCount)271*e82f7db8SAndroid Build Coastguard Worker fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
272*e82f7db8SAndroid Build Coastguard Worker                   jbyte invokeType, jbyte options, jint id,
273*e82f7db8SAndroid Build Coastguard Worker                   jthread thread, jclass clazz, jmethodID method,
274*e82f7db8SAndroid Build Coastguard Worker                   jobject instance,
275*e82f7db8SAndroid Build Coastguard Worker                   jvalue *arguments, jint argumentCount)
276*e82f7db8SAndroid Build Coastguard Worker {
277*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
278*e82f7db8SAndroid Build Coastguard Worker     if (!request->available) {
279*e82f7db8SAndroid Build Coastguard Worker         /*
280*e82f7db8SAndroid Build Coastguard Worker          * Thread is not at a point where it can invoke.
281*e82f7db8SAndroid Build Coastguard Worker          */
282*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INVALID_THREAD;
283*e82f7db8SAndroid Build Coastguard Worker     }
284*e82f7db8SAndroid Build Coastguard Worker     if (request->pending) {
285*e82f7db8SAndroid Build Coastguard Worker         /*
286*e82f7db8SAndroid Build Coastguard Worker          * Pending invoke
287*e82f7db8SAndroid Build Coastguard Worker          */
288*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_ALREADY_INVOKING;
289*e82f7db8SAndroid Build Coastguard Worker     }
290*e82f7db8SAndroid Build Coastguard Worker 
291*e82f7db8SAndroid Build Coastguard Worker     request->invokeType = invokeType;
292*e82f7db8SAndroid Build Coastguard Worker     request->options = options;
293*e82f7db8SAndroid Build Coastguard Worker     request->detached = JNI_FALSE;
294*e82f7db8SAndroid Build Coastguard Worker     request->id = id;
295*e82f7db8SAndroid Build Coastguard Worker     request->clazz = clazz;
296*e82f7db8SAndroid Build Coastguard Worker     request->method = method;
297*e82f7db8SAndroid Build Coastguard Worker     request->instance = instance;
298*e82f7db8SAndroid Build Coastguard Worker     request->arguments = arguments;
299*e82f7db8SAndroid Build Coastguard Worker     request->arguments = arguments;
300*e82f7db8SAndroid Build Coastguard Worker     request->argumentCount = argumentCount;
301*e82f7db8SAndroid Build Coastguard Worker 
302*e82f7db8SAndroid Build Coastguard Worker     request->returnValue.j = 0;
303*e82f7db8SAndroid Build Coastguard Worker     request->exception = 0;
304*e82f7db8SAndroid Build Coastguard Worker 
305*e82f7db8SAndroid Build Coastguard Worker     /*
306*e82f7db8SAndroid Build Coastguard Worker      * Squirrel away the method signature
307*e82f7db8SAndroid Build Coastguard Worker      */
308*e82f7db8SAndroid Build Coastguard Worker     error = methodSignature(method, NULL, &request->methodSignature,  NULL);
309*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
310*e82f7db8SAndroid Build Coastguard Worker         return error;
311*e82f7db8SAndroid Build Coastguard Worker     }
312*e82f7db8SAndroid Build Coastguard Worker 
313*e82f7db8SAndroid Build Coastguard Worker     /*
314*e82f7db8SAndroid Build Coastguard Worker      * The given references for class and instance are not guaranteed
315*e82f7db8SAndroid Build Coastguard Worker      * to be around long enough for invocation, so create new ones
316*e82f7db8SAndroid Build Coastguard Worker      * here.
317*e82f7db8SAndroid Build Coastguard Worker      */
318*e82f7db8SAndroid Build Coastguard Worker     error = createGlobalRefs(env, request);
319*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
320*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(request->methodSignature);
321*e82f7db8SAndroid Build Coastguard Worker         return error;
322*e82f7db8SAndroid Build Coastguard Worker     }
323*e82f7db8SAndroid Build Coastguard Worker 
324*e82f7db8SAndroid Build Coastguard Worker     request->pending = JNI_TRUE;
325*e82f7db8SAndroid Build Coastguard Worker     request->available = JNI_FALSE;
326*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_ERROR_NONE;
327*e82f7db8SAndroid Build Coastguard Worker }
328*e82f7db8SAndroid Build Coastguard Worker 
329*e82f7db8SAndroid Build Coastguard Worker void
invoker_enableInvokeRequests(jthread thread)330*e82f7db8SAndroid Build Coastguard Worker invoker_enableInvokeRequests(jthread thread)
331*e82f7db8SAndroid Build Coastguard Worker {
332*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
333*e82f7db8SAndroid Build Coastguard Worker 
334*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(thread);
335*e82f7db8SAndroid Build Coastguard Worker 
336*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
337*e82f7db8SAndroid Build Coastguard Worker     if (request == NULL) {
338*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
339*e82f7db8SAndroid Build Coastguard Worker     }
340*e82f7db8SAndroid Build Coastguard Worker 
341*e82f7db8SAndroid Build Coastguard Worker     request->available = JNI_TRUE;
342*e82f7db8SAndroid Build Coastguard Worker }
343*e82f7db8SAndroid Build Coastguard Worker 
344*e82f7db8SAndroid Build Coastguard Worker jvmtiError
invoker_requestInvoke(jbyte invokeType,jbyte options,jint id,jthread thread,jclass clazz,jmethodID method,jobject instance,jvalue * arguments,jint argumentCount)345*e82f7db8SAndroid Build Coastguard Worker invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,
346*e82f7db8SAndroid Build Coastguard Worker                       jthread thread, jclass clazz, jmethodID method,
347*e82f7db8SAndroid Build Coastguard Worker                       jobject instance,
348*e82f7db8SAndroid Build Coastguard Worker                       jvalue *arguments, jint argumentCount)
349*e82f7db8SAndroid Build Coastguard Worker {
350*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
351*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
352*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error = JVMTI_ERROR_NONE;
353*e82f7db8SAndroid Build Coastguard Worker 
354*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
355*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
356*e82f7db8SAndroid Build Coastguard Worker     if (request != NULL) {
357*e82f7db8SAndroid Build Coastguard Worker         error = fillInvokeRequest(env, request, invokeType, options, id,
358*e82f7db8SAndroid Build Coastguard Worker                                   thread, clazz, method, instance,
359*e82f7db8SAndroid Build Coastguard Worker                                   arguments, argumentCount);
360*e82f7db8SAndroid Build Coastguard Worker     }
361*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
362*e82f7db8SAndroid Build Coastguard Worker 
363*e82f7db8SAndroid Build Coastguard Worker     if (error == JVMTI_ERROR_NONE) {
364*e82f7db8SAndroid Build Coastguard Worker         if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED) ) {
365*e82f7db8SAndroid Build Coastguard Worker             /* true means it is okay to unblock the commandLoop thread */
366*e82f7db8SAndroid Build Coastguard Worker             (void)threadControl_resumeThread(thread, JNI_TRUE);
367*e82f7db8SAndroid Build Coastguard Worker         } else {
368*e82f7db8SAndroid Build Coastguard Worker             (void)threadControl_resumeAll();
369*e82f7db8SAndroid Build Coastguard Worker         }
370*e82f7db8SAndroid Build Coastguard Worker     }
371*e82f7db8SAndroid Build Coastguard Worker 
372*e82f7db8SAndroid Build Coastguard Worker     return error;
373*e82f7db8SAndroid Build Coastguard Worker }
374*e82f7db8SAndroid Build Coastguard Worker 
375*e82f7db8SAndroid Build Coastguard Worker static void
invokeConstructor(JNIEnv * env,InvokeRequest * request)376*e82f7db8SAndroid Build Coastguard Worker invokeConstructor(JNIEnv *env, InvokeRequest *request)
377*e82f7db8SAndroid Build Coastguard Worker {
378*e82f7db8SAndroid Build Coastguard Worker     jobject object;
379*e82f7db8SAndroid Build Coastguard Worker 
380*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT_MSG(request->clazz, "Request clazz null");
381*e82f7db8SAndroid Build Coastguard Worker     object = JNI_FUNC_PTR(env,NewObjectA)(env, request->clazz,
382*e82f7db8SAndroid Build Coastguard Worker                                      request->method,
383*e82f7db8SAndroid Build Coastguard Worker                                      request->arguments);
384*e82f7db8SAndroid Build Coastguard Worker     request->returnValue.l = NULL;
385*e82f7db8SAndroid Build Coastguard Worker     if (object != NULL) {
386*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, object, &(request->returnValue.l));
387*e82f7db8SAndroid Build Coastguard Worker     }
388*e82f7db8SAndroid Build Coastguard Worker }
389*e82f7db8SAndroid Build Coastguard Worker 
390*e82f7db8SAndroid Build Coastguard Worker static void
invokeStatic(JNIEnv * env,InvokeRequest * request)391*e82f7db8SAndroid Build Coastguard Worker invokeStatic(JNIEnv *env, InvokeRequest *request)
392*e82f7db8SAndroid Build Coastguard Worker {
393*e82f7db8SAndroid Build Coastguard Worker     switch(returnTypeTag(request->methodSignature)) {
394*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(OBJECT):
395*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(ARRAY): {
396*e82f7db8SAndroid Build Coastguard Worker             jobject object;
397*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT_MSG(request->clazz, "Request clazz null");
398*e82f7db8SAndroid Build Coastguard Worker             object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
399*e82f7db8SAndroid Build Coastguard Worker                                        request->clazz,
400*e82f7db8SAndroid Build Coastguard Worker                                        request->method,
401*e82f7db8SAndroid Build Coastguard Worker                                        request->arguments);
402*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.l = NULL;
403*e82f7db8SAndroid Build Coastguard Worker             if (object != NULL) {
404*e82f7db8SAndroid Build Coastguard Worker                 saveGlobalRef(env, object, &(request->returnValue.l));
405*e82f7db8SAndroid Build Coastguard Worker             }
406*e82f7db8SAndroid Build Coastguard Worker             break;
407*e82f7db8SAndroid Build Coastguard Worker         }
408*e82f7db8SAndroid Build Coastguard Worker 
409*e82f7db8SAndroid Build Coastguard Worker 
410*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BYTE):
411*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.b = JNI_FUNC_PTR(env,CallStaticByteMethodA)(env,
412*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
413*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
414*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
415*e82f7db8SAndroid Build Coastguard Worker             break;
416*e82f7db8SAndroid Build Coastguard Worker 
417*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(CHAR):
418*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.c = JNI_FUNC_PTR(env,CallStaticCharMethodA)(env,
419*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
420*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
421*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
422*e82f7db8SAndroid Build Coastguard Worker             break;
423*e82f7db8SAndroid Build Coastguard Worker 
424*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(FLOAT):
425*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.f = JNI_FUNC_PTR(env,CallStaticFloatMethodA)(env,
426*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
427*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
428*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
429*e82f7db8SAndroid Build Coastguard Worker             break;
430*e82f7db8SAndroid Build Coastguard Worker 
431*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(DOUBLE):
432*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.d = JNI_FUNC_PTR(env,CallStaticDoubleMethodA)(env,
433*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
434*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
435*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
436*e82f7db8SAndroid Build Coastguard Worker             break;
437*e82f7db8SAndroid Build Coastguard Worker 
438*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(INT):
439*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.i = JNI_FUNC_PTR(env,CallStaticIntMethodA)(env,
440*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
441*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
442*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
443*e82f7db8SAndroid Build Coastguard Worker             break;
444*e82f7db8SAndroid Build Coastguard Worker 
445*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(LONG):
446*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.j = JNI_FUNC_PTR(env,CallStaticLongMethodA)(env,
447*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
448*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
449*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
450*e82f7db8SAndroid Build Coastguard Worker             break;
451*e82f7db8SAndroid Build Coastguard Worker 
452*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(SHORT):
453*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.s = JNI_FUNC_PTR(env,CallStaticShortMethodA)(env,
454*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
455*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
456*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
457*e82f7db8SAndroid Build Coastguard Worker             break;
458*e82f7db8SAndroid Build Coastguard Worker 
459*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BOOLEAN):
460*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.z = JNI_FUNC_PTR(env,CallStaticBooleanMethodA)(env,
461*e82f7db8SAndroid Build Coastguard Worker                                                        request->clazz,
462*e82f7db8SAndroid Build Coastguard Worker                                                        request->method,
463*e82f7db8SAndroid Build Coastguard Worker                                                        request->arguments);
464*e82f7db8SAndroid Build Coastguard Worker             break;
465*e82f7db8SAndroid Build Coastguard Worker 
466*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(VOID):
467*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,CallStaticVoidMethodA)(env,
468*e82f7db8SAndroid Build Coastguard Worker                                           request->clazz,
469*e82f7db8SAndroid Build Coastguard Worker                                           request->method,
470*e82f7db8SAndroid Build Coastguard Worker                                           request->arguments);
471*e82f7db8SAndroid Build Coastguard Worker             break;
472*e82f7db8SAndroid Build Coastguard Worker 
473*e82f7db8SAndroid Build Coastguard Worker         default:
474*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature");
475*e82f7db8SAndroid Build Coastguard Worker             break;
476*e82f7db8SAndroid Build Coastguard Worker     }
477*e82f7db8SAndroid Build Coastguard Worker }
478*e82f7db8SAndroid Build Coastguard Worker 
479*e82f7db8SAndroid Build Coastguard Worker static void
invokeVirtual(JNIEnv * env,InvokeRequest * request)480*e82f7db8SAndroid Build Coastguard Worker invokeVirtual(JNIEnv *env, InvokeRequest *request)
481*e82f7db8SAndroid Build Coastguard Worker {
482*e82f7db8SAndroid Build Coastguard Worker     switch(returnTypeTag(request->methodSignature)) {
483*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(OBJECT):
484*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(ARRAY): {
485*e82f7db8SAndroid Build Coastguard Worker             jobject object;
486*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT_MSG(request->instance, "Request instance null");
487*e82f7db8SAndroid Build Coastguard Worker             object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
488*e82f7db8SAndroid Build Coastguard Worker                                  request->instance,
489*e82f7db8SAndroid Build Coastguard Worker                                  request->method,
490*e82f7db8SAndroid Build Coastguard Worker                                  request->arguments);
491*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.l = NULL;
492*e82f7db8SAndroid Build Coastguard Worker             if (object != NULL) {
493*e82f7db8SAndroid Build Coastguard Worker                 saveGlobalRef(env, object, &(request->returnValue.l));
494*e82f7db8SAndroid Build Coastguard Worker             }
495*e82f7db8SAndroid Build Coastguard Worker             break;
496*e82f7db8SAndroid Build Coastguard Worker         }
497*e82f7db8SAndroid Build Coastguard Worker 
498*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BYTE):
499*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.b = JNI_FUNC_PTR(env,CallByteMethodA)(env,
500*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
501*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
502*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
503*e82f7db8SAndroid Build Coastguard Worker             break;
504*e82f7db8SAndroid Build Coastguard Worker 
505*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(CHAR):
506*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.c = JNI_FUNC_PTR(env,CallCharMethodA)(env,
507*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
508*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
509*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
510*e82f7db8SAndroid Build Coastguard Worker             break;
511*e82f7db8SAndroid Build Coastguard Worker 
512*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(FLOAT):
513*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.f = JNI_FUNC_PTR(env,CallFloatMethodA)(env,
514*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
515*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
516*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
517*e82f7db8SAndroid Build Coastguard Worker             break;
518*e82f7db8SAndroid Build Coastguard Worker 
519*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(DOUBLE):
520*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.d = JNI_FUNC_PTR(env,CallDoubleMethodA)(env,
521*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
522*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
523*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
524*e82f7db8SAndroid Build Coastguard Worker             break;
525*e82f7db8SAndroid Build Coastguard Worker 
526*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(INT):
527*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.i = JNI_FUNC_PTR(env,CallIntMethodA)(env,
528*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
529*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
530*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
531*e82f7db8SAndroid Build Coastguard Worker             break;
532*e82f7db8SAndroid Build Coastguard Worker 
533*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(LONG):
534*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.j = JNI_FUNC_PTR(env,CallLongMethodA)(env,
535*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
536*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
537*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
538*e82f7db8SAndroid Build Coastguard Worker             break;
539*e82f7db8SAndroid Build Coastguard Worker 
540*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(SHORT):
541*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.s = JNI_FUNC_PTR(env,CallShortMethodA)(env,
542*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
543*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
544*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
545*e82f7db8SAndroid Build Coastguard Worker             break;
546*e82f7db8SAndroid Build Coastguard Worker 
547*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BOOLEAN):
548*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.z = JNI_FUNC_PTR(env,CallBooleanMethodA)(env,
549*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
550*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
551*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
552*e82f7db8SAndroid Build Coastguard Worker             break;
553*e82f7db8SAndroid Build Coastguard Worker 
554*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(VOID):
555*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,CallVoidMethodA)(env,
556*e82f7db8SAndroid Build Coastguard Worker                                     request->instance,
557*e82f7db8SAndroid Build Coastguard Worker                                     request->method,
558*e82f7db8SAndroid Build Coastguard Worker                                     request->arguments);
559*e82f7db8SAndroid Build Coastguard Worker             break;
560*e82f7db8SAndroid Build Coastguard Worker 
561*e82f7db8SAndroid Build Coastguard Worker         default:
562*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature");
563*e82f7db8SAndroid Build Coastguard Worker             break;
564*e82f7db8SAndroid Build Coastguard Worker     }
565*e82f7db8SAndroid Build Coastguard Worker }
566*e82f7db8SAndroid Build Coastguard Worker 
567*e82f7db8SAndroid Build Coastguard Worker static void
invokeNonvirtual(JNIEnv * env,InvokeRequest * request)568*e82f7db8SAndroid Build Coastguard Worker invokeNonvirtual(JNIEnv *env, InvokeRequest *request)
569*e82f7db8SAndroid Build Coastguard Worker {
570*e82f7db8SAndroid Build Coastguard Worker     switch(returnTypeTag(request->methodSignature)) {
571*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(OBJECT):
572*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(ARRAY): {
573*e82f7db8SAndroid Build Coastguard Worker             jobject object;
574*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT_MSG(request->clazz, "Request clazz null");
575*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT_MSG(request->instance, "Request instance null");
576*e82f7db8SAndroid Build Coastguard Worker             object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
577*e82f7db8SAndroid Build Coastguard Worker                                            request->instance,
578*e82f7db8SAndroid Build Coastguard Worker                                            request->clazz,
579*e82f7db8SAndroid Build Coastguard Worker                                            request->method,
580*e82f7db8SAndroid Build Coastguard Worker                                            request->arguments);
581*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.l = NULL;
582*e82f7db8SAndroid Build Coastguard Worker             if (object != NULL) {
583*e82f7db8SAndroid Build Coastguard Worker                 saveGlobalRef(env, object, &(request->returnValue.l));
584*e82f7db8SAndroid Build Coastguard Worker             }
585*e82f7db8SAndroid Build Coastguard Worker             break;
586*e82f7db8SAndroid Build Coastguard Worker         }
587*e82f7db8SAndroid Build Coastguard Worker 
588*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BYTE):
589*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.b = JNI_FUNC_PTR(env,CallNonvirtualByteMethodA)(env,
590*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
591*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
592*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
593*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
594*e82f7db8SAndroid Build Coastguard Worker             break;
595*e82f7db8SAndroid Build Coastguard Worker 
596*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(CHAR):
597*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.c = JNI_FUNC_PTR(env,CallNonvirtualCharMethodA)(env,
598*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
599*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
600*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
601*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
602*e82f7db8SAndroid Build Coastguard Worker             break;
603*e82f7db8SAndroid Build Coastguard Worker 
604*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(FLOAT):
605*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.f = JNI_FUNC_PTR(env,CallNonvirtualFloatMethodA)(env,
606*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
607*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
608*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
609*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
610*e82f7db8SAndroid Build Coastguard Worker             break;
611*e82f7db8SAndroid Build Coastguard Worker 
612*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(DOUBLE):
613*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.d = JNI_FUNC_PTR(env,CallNonvirtualDoubleMethodA)(env,
614*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
615*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
616*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
617*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
618*e82f7db8SAndroid Build Coastguard Worker             break;
619*e82f7db8SAndroid Build Coastguard Worker 
620*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(INT):
621*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.i = JNI_FUNC_PTR(env,CallNonvirtualIntMethodA)(env,
622*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
623*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
624*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
625*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
626*e82f7db8SAndroid Build Coastguard Worker             break;
627*e82f7db8SAndroid Build Coastguard Worker 
628*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(LONG):
629*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.j = JNI_FUNC_PTR(env,CallNonvirtualLongMethodA)(env,
630*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
631*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
632*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
633*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
634*e82f7db8SAndroid Build Coastguard Worker             break;
635*e82f7db8SAndroid Build Coastguard Worker 
636*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(SHORT):
637*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.s = JNI_FUNC_PTR(env,CallNonvirtualShortMethodA)(env,
638*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
639*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
640*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
641*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
642*e82f7db8SAndroid Build Coastguard Worker             break;
643*e82f7db8SAndroid Build Coastguard Worker 
644*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BOOLEAN):
645*e82f7db8SAndroid Build Coastguard Worker             request->returnValue.z = JNI_FUNC_PTR(env,CallNonvirtualBooleanMethodA)(env,
646*e82f7db8SAndroid Build Coastguard Worker                                                  request->instance,
647*e82f7db8SAndroid Build Coastguard Worker                                                  request->clazz,
648*e82f7db8SAndroid Build Coastguard Worker                                                  request->method,
649*e82f7db8SAndroid Build Coastguard Worker                                                  request->arguments);
650*e82f7db8SAndroid Build Coastguard Worker             break;
651*e82f7db8SAndroid Build Coastguard Worker 
652*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(VOID):
653*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,CallNonvirtualVoidMethodA)(env,
654*e82f7db8SAndroid Build Coastguard Worker                                     request->instance,
655*e82f7db8SAndroid Build Coastguard Worker                                     request->clazz,
656*e82f7db8SAndroid Build Coastguard Worker                                     request->method,
657*e82f7db8SAndroid Build Coastguard Worker                                     request->arguments);
658*e82f7db8SAndroid Build Coastguard Worker             break;
659*e82f7db8SAndroid Build Coastguard Worker 
660*e82f7db8SAndroid Build Coastguard Worker         default:
661*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature");
662*e82f7db8SAndroid Build Coastguard Worker             break;
663*e82f7db8SAndroid Build Coastguard Worker     }
664*e82f7db8SAndroid Build Coastguard Worker }
665*e82f7db8SAndroid Build Coastguard Worker 
666*e82f7db8SAndroid Build Coastguard Worker jboolean
invoker_doInvoke(jthread thread)667*e82f7db8SAndroid Build Coastguard Worker invoker_doInvoke(jthread thread)
668*e82f7db8SAndroid Build Coastguard Worker {
669*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env;
670*e82f7db8SAndroid Build Coastguard Worker     jboolean startNow;
671*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
672*e82f7db8SAndroid Build Coastguard Worker     jbyte options;
673*e82f7db8SAndroid Build Coastguard Worker     jbyte invokeType;
674*e82f7db8SAndroid Build Coastguard Worker 
675*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(thread);
676*e82f7db8SAndroid Build Coastguard Worker 
677*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
678*e82f7db8SAndroid Build Coastguard Worker 
679*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
680*e82f7db8SAndroid Build Coastguard Worker     if (request == NULL) {
681*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
682*e82f7db8SAndroid Build Coastguard Worker     }
683*e82f7db8SAndroid Build Coastguard Worker 
684*e82f7db8SAndroid Build Coastguard Worker     request->available = JNI_FALSE;
685*e82f7db8SAndroid Build Coastguard Worker     startNow = request->pending && !request->started;
686*e82f7db8SAndroid Build Coastguard Worker 
687*e82f7db8SAndroid Build Coastguard Worker     if (startNow) {
688*e82f7db8SAndroid Build Coastguard Worker         request->started = JNI_TRUE;
689*e82f7db8SAndroid Build Coastguard Worker     }
690*e82f7db8SAndroid Build Coastguard Worker     options = request->options;
691*e82f7db8SAndroid Build Coastguard Worker     invokeType = request->invokeType;
692*e82f7db8SAndroid Build Coastguard Worker 
693*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
694*e82f7db8SAndroid Build Coastguard Worker 
695*e82f7db8SAndroid Build Coastguard Worker     if (!startNow) {
696*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;
697*e82f7db8SAndroid Build Coastguard Worker     }
698*e82f7db8SAndroid Build Coastguard Worker 
699*e82f7db8SAndroid Build Coastguard Worker     env = getEnv();
700*e82f7db8SAndroid Build Coastguard Worker 
701*e82f7db8SAndroid Build Coastguard Worker     WITH_LOCAL_REFS(env, 2) {  /* 1 for obj return values, 1 for exception */
702*e82f7db8SAndroid Build Coastguard Worker 
703*e82f7db8SAndroid Build Coastguard Worker         jobject exception;
704*e82f7db8SAndroid Build Coastguard Worker 
705*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,ExceptionClear)(env);
706*e82f7db8SAndroid Build Coastguard Worker 
707*e82f7db8SAndroid Build Coastguard Worker         switch (invokeType) {
708*e82f7db8SAndroid Build Coastguard Worker             case INVOKE_CONSTRUCTOR:
709*e82f7db8SAndroid Build Coastguard Worker                 invokeConstructor(env, request);
710*e82f7db8SAndroid Build Coastguard Worker                 break;
711*e82f7db8SAndroid Build Coastguard Worker             case INVOKE_STATIC:
712*e82f7db8SAndroid Build Coastguard Worker                 invokeStatic(env, request);
713*e82f7db8SAndroid Build Coastguard Worker                 break;
714*e82f7db8SAndroid Build Coastguard Worker             case INVOKE_INSTANCE:
715*e82f7db8SAndroid Build Coastguard Worker                 if (options & JDWP_INVOKE_OPTIONS(NONVIRTUAL) ) {
716*e82f7db8SAndroid Build Coastguard Worker                     invokeNonvirtual(env, request);
717*e82f7db8SAndroid Build Coastguard Worker                 } else {
718*e82f7db8SAndroid Build Coastguard Worker                     invokeVirtual(env, request);
719*e82f7db8SAndroid Build Coastguard Worker                 }
720*e82f7db8SAndroid Build Coastguard Worker                 break;
721*e82f7db8SAndroid Build Coastguard Worker             default:
722*e82f7db8SAndroid Build Coastguard Worker                 JDI_ASSERT(JNI_FALSE);
723*e82f7db8SAndroid Build Coastguard Worker         }
724*e82f7db8SAndroid Build Coastguard Worker         request->exception = NULL;
725*e82f7db8SAndroid Build Coastguard Worker         exception = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
726*e82f7db8SAndroid Build Coastguard Worker         if (exception != NULL) {
727*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ExceptionClear)(env);
728*e82f7db8SAndroid Build Coastguard Worker             saveGlobalRef(env, exception, &(request->exception));
729*e82f7db8SAndroid Build Coastguard Worker         }
730*e82f7db8SAndroid Build Coastguard Worker 
731*e82f7db8SAndroid Build Coastguard Worker     } END_WITH_LOCAL_REFS(env);
732*e82f7db8SAndroid Build Coastguard Worker 
733*e82f7db8SAndroid Build Coastguard Worker     return JNI_TRUE;
734*e82f7db8SAndroid Build Coastguard Worker }
735*e82f7db8SAndroid Build Coastguard Worker 
736*e82f7db8SAndroid Build Coastguard Worker void
invoker_completeInvokeRequest(jthread thread)737*e82f7db8SAndroid Build Coastguard Worker invoker_completeInvokeRequest(jthread thread)
738*e82f7db8SAndroid Build Coastguard Worker {
739*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
740*e82f7db8SAndroid Build Coastguard Worker     PacketOutputStream out;
741*e82f7db8SAndroid Build Coastguard Worker     jbyte tag;
742*e82f7db8SAndroid Build Coastguard Worker     jobject exc;
743*e82f7db8SAndroid Build Coastguard Worker     jvalue returnValue;
744*e82f7db8SAndroid Build Coastguard Worker     jint id;
745*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
746*e82f7db8SAndroid Build Coastguard Worker     jboolean detached;
747*e82f7db8SAndroid Build Coastguard Worker 
748*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(thread);
749*e82f7db8SAndroid Build Coastguard Worker 
750*e82f7db8SAndroid Build Coastguard Worker     /* Prevent gcc errors on uninitialized variables. */
751*e82f7db8SAndroid Build Coastguard Worker     tag = 0;
752*e82f7db8SAndroid Build Coastguard Worker     exc = NULL;
753*e82f7db8SAndroid Build Coastguard Worker     id  = 0;
754*e82f7db8SAndroid Build Coastguard Worker 
755*e82f7db8SAndroid Build Coastguard Worker     eventHandler_lock(); /* for proper lock order */
756*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
757*e82f7db8SAndroid Build Coastguard Worker 
758*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
759*e82f7db8SAndroid Build Coastguard Worker     if (request == NULL) {
760*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
761*e82f7db8SAndroid Build Coastguard Worker     }
762*e82f7db8SAndroid Build Coastguard Worker 
763*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(request->pending);
764*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(request->started);
765*e82f7db8SAndroid Build Coastguard Worker 
766*e82f7db8SAndroid Build Coastguard Worker     request->pending = JNI_FALSE;
767*e82f7db8SAndroid Build Coastguard Worker     request->started = JNI_FALSE;
768*e82f7db8SAndroid Build Coastguard Worker     request->available = JNI_TRUE; /* For next time around */
769*e82f7db8SAndroid Build Coastguard Worker 
770*e82f7db8SAndroid Build Coastguard Worker     detached = request->detached;
771*e82f7db8SAndroid Build Coastguard Worker     if (!detached) {
772*e82f7db8SAndroid Build Coastguard Worker         if (request->options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED)) {
773*e82f7db8SAndroid Build Coastguard Worker             (void)threadControl_suspendThread(thread, JNI_FALSE);
774*e82f7db8SAndroid Build Coastguard Worker         } else {
775*e82f7db8SAndroid Build Coastguard Worker             (void)threadControl_suspendAll();
776*e82f7db8SAndroid Build Coastguard Worker         }
777*e82f7db8SAndroid Build Coastguard Worker 
778*e82f7db8SAndroid Build Coastguard Worker         if (request->invokeType == INVOKE_CONSTRUCTOR) {
779*e82f7db8SAndroid Build Coastguard Worker             /*
780*e82f7db8SAndroid Build Coastguard Worker              * Although constructors technically have a return type of
781*e82f7db8SAndroid Build Coastguard Worker              * void, we return the object created.
782*e82f7db8SAndroid Build Coastguard Worker              */
783*e82f7db8SAndroid Build Coastguard Worker             tag = specificTypeKey(env, request->returnValue.l);
784*e82f7db8SAndroid Build Coastguard Worker         } else {
785*e82f7db8SAndroid Build Coastguard Worker             tag = returnTypeTag(request->methodSignature);
786*e82f7db8SAndroid Build Coastguard Worker         }
787*e82f7db8SAndroid Build Coastguard Worker         id = request->id;
788*e82f7db8SAndroid Build Coastguard Worker         exc = request->exception;
789*e82f7db8SAndroid Build Coastguard Worker         returnValue = request->returnValue;
790*e82f7db8SAndroid Build Coastguard Worker     }
791*e82f7db8SAndroid Build Coastguard Worker 
792*e82f7db8SAndroid Build Coastguard Worker     /*
793*e82f7db8SAndroid Build Coastguard Worker      * At this time, there's no need to retain global references on
794*e82f7db8SAndroid Build Coastguard Worker      * arguments since the reply is processed. No one will deal with
795*e82f7db8SAndroid Build Coastguard Worker      * this request ID anymore, so we must call deleteGlobalArgumentRefs().
796*e82f7db8SAndroid Build Coastguard Worker      *
797*e82f7db8SAndroid Build Coastguard Worker      * We cannot delete saved exception or return value references
798*e82f7db8SAndroid Build Coastguard Worker      * since otherwise a deleted handle would escape when writing
799*e82f7db8SAndroid Build Coastguard Worker      * the response to the stream. Instead, we clean those refs up
800*e82f7db8SAndroid Build Coastguard Worker      * after writing the respone.
801*e82f7db8SAndroid Build Coastguard Worker      */
802*e82f7db8SAndroid Build Coastguard Worker     deleteGlobalArgumentRefs(env, request);
803*e82f7db8SAndroid Build Coastguard Worker 
804*e82f7db8SAndroid Build Coastguard Worker     /*
805*e82f7db8SAndroid Build Coastguard Worker      * Give up the lock before I/O operation
806*e82f7db8SAndroid Build Coastguard Worker      */
807*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
808*e82f7db8SAndroid Build Coastguard Worker     eventHandler_unlock();
809*e82f7db8SAndroid Build Coastguard Worker 
810*e82f7db8SAndroid Build Coastguard Worker     if (!detached) {
811*e82f7db8SAndroid Build Coastguard Worker         outStream_initReply(&out, id);
812*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeValue(env, &out, tag, returnValue);
813*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeObjectTag(env, &out, exc);
814*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeObjectRef(env, &out, exc);
815*e82f7db8SAndroid Build Coastguard Worker         outStream_sendReply(&out);
816*e82f7db8SAndroid Build Coastguard Worker     }
817*e82f7db8SAndroid Build Coastguard Worker 
818*e82f7db8SAndroid Build Coastguard Worker     /*
819*e82f7db8SAndroid Build Coastguard Worker      * Delete potentially saved global references of return value
820*e82f7db8SAndroid Build Coastguard Worker      * and exception
821*e82f7db8SAndroid Build Coastguard Worker      */
822*e82f7db8SAndroid Build Coastguard Worker     eventHandler_lock(); // for proper lock order
823*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
824*e82f7db8SAndroid Build Coastguard Worker     deletePotentiallySavedGlobalRefs(env, request);
825*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
826*e82f7db8SAndroid Build Coastguard Worker     eventHandler_unlock();
827*e82f7db8SAndroid Build Coastguard Worker }
828*e82f7db8SAndroid Build Coastguard Worker 
829*e82f7db8SAndroid Build Coastguard Worker jboolean
invoker_isPending(jthread thread)830*e82f7db8SAndroid Build Coastguard Worker invoker_isPending(jthread thread)
831*e82f7db8SAndroid Build Coastguard Worker {
832*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
833*e82f7db8SAndroid Build Coastguard Worker 
834*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(thread);
835*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
836*e82f7db8SAndroid Build Coastguard Worker     if (request == NULL) {
837*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
838*e82f7db8SAndroid Build Coastguard Worker     }
839*e82f7db8SAndroid Build Coastguard Worker     return request->pending;
840*e82f7db8SAndroid Build Coastguard Worker }
841*e82f7db8SAndroid Build Coastguard Worker 
842*e82f7db8SAndroid Build Coastguard Worker jboolean
invoker_isEnabled(jthread thread)843*e82f7db8SAndroid Build Coastguard Worker invoker_isEnabled(jthread thread)
844*e82f7db8SAndroid Build Coastguard Worker {
845*e82f7db8SAndroid Build Coastguard Worker     InvokeRequest *request;
846*e82f7db8SAndroid Build Coastguard Worker 
847*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(thread);
848*e82f7db8SAndroid Build Coastguard Worker     request = threadControl_getInvokeRequest(thread);
849*e82f7db8SAndroid Build Coastguard Worker     if (request == NULL) {
850*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
851*e82f7db8SAndroid Build Coastguard Worker     }
852*e82f7db8SAndroid Build Coastguard Worker     return request->available;
853*e82f7db8SAndroid Build Coastguard Worker }
854*e82f7db8SAndroid Build Coastguard Worker 
855*e82f7db8SAndroid Build Coastguard Worker void
invoker_detach(InvokeRequest * request)856*e82f7db8SAndroid Build Coastguard Worker invoker_detach(InvokeRequest *request)
857*e82f7db8SAndroid Build Coastguard Worker {
858*e82f7db8SAndroid Build Coastguard Worker     JDI_ASSERT(request);
859*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(invokerLock);
860*e82f7db8SAndroid Build Coastguard Worker     request->detached = JNI_TRUE;
861*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(invokerLock);
862*e82f7db8SAndroid Build Coastguard Worker }
863