xref: /aosp_15_r20/external/oj-libjdwp/src/share/back/util.c (revision e82f7db8c62aed3c168547abe4f9f4aeceaebfc7)
1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker  * Copyright (c) 1998, 2013, 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 <ctype.h>
27*e82f7db8SAndroid Build Coastguard Worker // ANDROID-CHANGED: Include time.h so we can use clock_gettime to implement milliTime.
28*e82f7db8SAndroid Build Coastguard Worker #include <time.h>
29*e82f7db8SAndroid Build Coastguard Worker 
30*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
31*e82f7db8SAndroid Build Coastguard Worker #include "transport.h"
32*e82f7db8SAndroid Build Coastguard Worker #include "eventHandler.h"
33*e82f7db8SAndroid Build Coastguard Worker #include "threadControl.h"
34*e82f7db8SAndroid Build Coastguard Worker #include "outStream.h"
35*e82f7db8SAndroid Build Coastguard Worker #include "inStream.h"
36*e82f7db8SAndroid Build Coastguard Worker #include "invoker.h"
37*e82f7db8SAndroid Build Coastguard Worker 
38*e82f7db8SAndroid Build Coastguard Worker /* Global data area */
39*e82f7db8SAndroid Build Coastguard Worker BackendGlobalData *gdata = NULL;
40*e82f7db8SAndroid Build Coastguard Worker 
41*e82f7db8SAndroid Build Coastguard Worker /* Forward declarations */
42*e82f7db8SAndroid Build Coastguard Worker static jboolean isInterface(jclass clazz);
43*e82f7db8SAndroid Build Coastguard Worker static char * getPropertyUTF8(JNIEnv *env, char *propertyName);
44*e82f7db8SAndroid Build Coastguard Worker 
45*e82f7db8SAndroid Build Coastguard Worker static jvmtiError (JNICALL *ext_RawMonitorEnterNoSuspend) (jvmtiEnv* env, jrawMonitorID monitor);
46*e82f7db8SAndroid Build Coastguard Worker static jvmtiError (JNICALL *ext_RawMonitorExitNoSuspend) (jvmtiEnv* env, jrawMonitorID monitor);
47*e82f7db8SAndroid Build Coastguard Worker 
48*e82f7db8SAndroid Build Coastguard Worker // ANDROID-CHANGED: Implement a helper to get the current time in milliseconds according to
49*e82f7db8SAndroid Build Coastguard Worker // CLOCK_MONOTONIC.
50*e82f7db8SAndroid Build Coastguard Worker jlong
milliTime(void)51*e82f7db8SAndroid Build Coastguard Worker milliTime(void)
52*e82f7db8SAndroid Build Coastguard Worker {
53*e82f7db8SAndroid Build Coastguard Worker     return nsTime() / 1000000L;
54*e82f7db8SAndroid Build Coastguard Worker }
55*e82f7db8SAndroid Build Coastguard Worker 
56*e82f7db8SAndroid Build Coastguard Worker // ANDROID-CHANGED: Implement a helper to get the current time in nanoseconds according to
57*e82f7db8SAndroid Build Coastguard Worker // CLOCK_MONOTONIC.
58*e82f7db8SAndroid Build Coastguard Worker jlong
nsTime(void)59*e82f7db8SAndroid Build Coastguard Worker nsTime(void)
60*e82f7db8SAndroid Build Coastguard Worker {
61*e82f7db8SAndroid Build Coastguard Worker   struct timespec now;
62*e82f7db8SAndroid Build Coastguard Worker   memset(&now, 0, sizeof(now));
63*e82f7db8SAndroid Build Coastguard Worker   (void)clock_gettime(CLOCK_MONOTONIC, &now);
64*e82f7db8SAndroid Build Coastguard Worker   return ((jlong)now.tv_sec) * 1000000000LL + ((jlong)now.tv_nsec);
65*e82f7db8SAndroid Build Coastguard Worker }
66*e82f7db8SAndroid Build Coastguard Worker 
67*e82f7db8SAndroid Build Coastguard Worker /* Save an object reference for use later (create a NewGlobalRef) */
68*e82f7db8SAndroid Build Coastguard Worker void
saveGlobalRef(JNIEnv * env,jobject obj,jobject * pobj)69*e82f7db8SAndroid Build Coastguard Worker saveGlobalRef(JNIEnv *env, jobject obj, jobject *pobj)
70*e82f7db8SAndroid Build Coastguard Worker {
71*e82f7db8SAndroid Build Coastguard Worker     jobject newobj;
72*e82f7db8SAndroid Build Coastguard Worker 
73*e82f7db8SAndroid Build Coastguard Worker     if ( pobj == NULL ) {
74*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef pobj");
75*e82f7db8SAndroid Build Coastguard Worker     }
76*e82f7db8SAndroid Build Coastguard Worker     if ( *pobj != NULL ) {
77*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef *pobj");
78*e82f7db8SAndroid Build Coastguard Worker     }
79*e82f7db8SAndroid Build Coastguard Worker     if ( env == NULL ) {
80*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef env");
81*e82f7db8SAndroid Build Coastguard Worker     }
82*e82f7db8SAndroid Build Coastguard Worker     if ( obj == NULL ) {
83*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef obj");
84*e82f7db8SAndroid Build Coastguard Worker     }
85*e82f7db8SAndroid Build Coastguard Worker     newobj = JNI_FUNC_PTR(env,NewGlobalRef)(env, obj);
86*e82f7db8SAndroid Build Coastguard Worker     if ( newobj == NULL ) {
87*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewGlobalRef");
88*e82f7db8SAndroid Build Coastguard Worker     }
89*e82f7db8SAndroid Build Coastguard Worker     *pobj = newobj;
90*e82f7db8SAndroid Build Coastguard Worker }
91*e82f7db8SAndroid Build Coastguard Worker 
92*e82f7db8SAndroid Build Coastguard Worker /* Toss a previously saved object reference */
93*e82f7db8SAndroid Build Coastguard Worker void
tossGlobalRef(JNIEnv * env,jobject * pobj)94*e82f7db8SAndroid Build Coastguard Worker tossGlobalRef(JNIEnv *env, jobject *pobj)
95*e82f7db8SAndroid Build Coastguard Worker {
96*e82f7db8SAndroid Build Coastguard Worker     jobject obj;
97*e82f7db8SAndroid Build Coastguard Worker 
98*e82f7db8SAndroid Build Coastguard Worker     if ( pobj == NULL ) {
99*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef pobj");
100*e82f7db8SAndroid Build Coastguard Worker     }
101*e82f7db8SAndroid Build Coastguard Worker     obj = *pobj;
102*e82f7db8SAndroid Build Coastguard Worker     if ( env == NULL ) {
103*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef env");
104*e82f7db8SAndroid Build Coastguard Worker     }
105*e82f7db8SAndroid Build Coastguard Worker     if ( obj == NULL ) {
106*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"tossGlobalRef obj");
107*e82f7db8SAndroid Build Coastguard Worker     }
108*e82f7db8SAndroid Build Coastguard Worker     JNI_FUNC_PTR(env,DeleteGlobalRef)(env, obj);
109*e82f7db8SAndroid Build Coastguard Worker     *pobj = NULL;
110*e82f7db8SAndroid Build Coastguard Worker }
111*e82f7db8SAndroid Build Coastguard Worker 
112*e82f7db8SAndroid Build Coastguard Worker static jclass
findClass(JNIEnv * env,const char * name)113*e82f7db8SAndroid Build Coastguard Worker findClass(JNIEnv *env, const char * name)
114*e82f7db8SAndroid Build Coastguard Worker {
115*e82f7db8SAndroid Build Coastguard Worker     jclass x;
116*e82f7db8SAndroid Build Coastguard Worker 
117*e82f7db8SAndroid Build Coastguard Worker     if ( env == NULL ) {
118*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass env");
119*e82f7db8SAndroid Build Coastguard Worker     }
120*e82f7db8SAndroid Build Coastguard Worker     if ( name == NULL || name[0] == 0 ) {
121*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass name");
122*e82f7db8SAndroid Build Coastguard Worker     }
123*e82f7db8SAndroid Build Coastguard Worker     x = JNI_FUNC_PTR(env,FindClass)(env, name);
124*e82f7db8SAndroid Build Coastguard Worker     if (x == NULL) {
125*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Can't find class %s", name));
126*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
127*e82f7db8SAndroid Build Coastguard Worker     }
128*e82f7db8SAndroid Build Coastguard Worker     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
129*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Exception occurred finding class %s", name));
130*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
131*e82f7db8SAndroid Build Coastguard Worker     }
132*e82f7db8SAndroid Build Coastguard Worker     return x;
133*e82f7db8SAndroid Build Coastguard Worker }
134*e82f7db8SAndroid Build Coastguard Worker 
135*e82f7db8SAndroid Build Coastguard Worker static jmethodID
getMethod(JNIEnv * env,jclass clazz,const char * name,const char * signature)136*e82f7db8SAndroid Build Coastguard Worker getMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
137*e82f7db8SAndroid Build Coastguard Worker {
138*e82f7db8SAndroid Build Coastguard Worker     jmethodID method;
139*e82f7db8SAndroid Build Coastguard Worker 
140*e82f7db8SAndroid Build Coastguard Worker     if ( env == NULL ) {
141*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod env");
142*e82f7db8SAndroid Build Coastguard Worker     }
143*e82f7db8SAndroid Build Coastguard Worker     if ( clazz == NULL ) {
144*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod clazz");
145*e82f7db8SAndroid Build Coastguard Worker     }
146*e82f7db8SAndroid Build Coastguard Worker     if ( name == NULL || name[0] == 0 ) {
147*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod name");
148*e82f7db8SAndroid Build Coastguard Worker     }
149*e82f7db8SAndroid Build Coastguard Worker     if ( signature == NULL || signature[0] == 0 ) {
150*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod signature");
151*e82f7db8SAndroid Build Coastguard Worker     }
152*e82f7db8SAndroid Build Coastguard Worker     method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, signature);
153*e82f7db8SAndroid Build Coastguard Worker     if (method == NULL) {
154*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
155*e82f7db8SAndroid Build Coastguard Worker                                 name, signature));
156*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
157*e82f7db8SAndroid Build Coastguard Worker     }
158*e82f7db8SAndroid Build Coastguard Worker     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
159*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
160*e82f7db8SAndroid Build Coastguard Worker                                 name, signature));
161*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
162*e82f7db8SAndroid Build Coastguard Worker     }
163*e82f7db8SAndroid Build Coastguard Worker     return method;
164*e82f7db8SAndroid Build Coastguard Worker }
165*e82f7db8SAndroid Build Coastguard Worker 
166*e82f7db8SAndroid Build Coastguard Worker static jmethodID
getStaticMethod(JNIEnv * env,jclass clazz,const char * name,const char * signature)167*e82f7db8SAndroid Build Coastguard Worker getStaticMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
168*e82f7db8SAndroid Build Coastguard Worker {
169*e82f7db8SAndroid Build Coastguard Worker     jmethodID method;
170*e82f7db8SAndroid Build Coastguard Worker 
171*e82f7db8SAndroid Build Coastguard Worker     if ( env == NULL ) {
172*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod env");
173*e82f7db8SAndroid Build Coastguard Worker     }
174*e82f7db8SAndroid Build Coastguard Worker     if ( clazz == NULL ) {
175*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod clazz");
176*e82f7db8SAndroid Build Coastguard Worker     }
177*e82f7db8SAndroid Build Coastguard Worker     if ( name == NULL || name[0] == 0 ) {
178*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod name");
179*e82f7db8SAndroid Build Coastguard Worker     }
180*e82f7db8SAndroid Build Coastguard Worker     if ( signature == NULL || signature[0] == 0 ) {
181*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod signature");
182*e82f7db8SAndroid Build Coastguard Worker     }
183*e82f7db8SAndroid Build Coastguard Worker     method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, signature);
184*e82f7db8SAndroid Build Coastguard Worker     if (method == NULL) {
185*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
186*e82f7db8SAndroid Build Coastguard Worker                                 name, signature));
187*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
188*e82f7db8SAndroid Build Coastguard Worker     }
189*e82f7db8SAndroid Build Coastguard Worker     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
190*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
191*e82f7db8SAndroid Build Coastguard Worker                                 name, signature));
192*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
193*e82f7db8SAndroid Build Coastguard Worker     }
194*e82f7db8SAndroid Build Coastguard Worker     return method;
195*e82f7db8SAndroid Build Coastguard Worker }
196*e82f7db8SAndroid Build Coastguard Worker 
197*e82f7db8SAndroid Build Coastguard Worker void
util_initialize(JNIEnv * env)198*e82f7db8SAndroid Build Coastguard Worker util_initialize(JNIEnv *env)
199*e82f7db8SAndroid Build Coastguard Worker {
200*e82f7db8SAndroid Build Coastguard Worker     WITH_LOCAL_REFS(env, 6) {
201*e82f7db8SAndroid Build Coastguard Worker 
202*e82f7db8SAndroid Build Coastguard Worker         jvmtiError error;
203*e82f7db8SAndroid Build Coastguard Worker         jclass localClassClass;
204*e82f7db8SAndroid Build Coastguard Worker         jclass localThreadClass;
205*e82f7db8SAndroid Build Coastguard Worker         jclass localThreadGroupClass;
206*e82f7db8SAndroid Build Coastguard Worker         jclass localClassLoaderClass;
207*e82f7db8SAndroid Build Coastguard Worker         jclass localStringClass;
208*e82f7db8SAndroid Build Coastguard Worker         jclass localSystemClass;
209*e82f7db8SAndroid Build Coastguard Worker         jclass localPropertiesClass;
210*e82f7db8SAndroid Build Coastguard Worker         jclass localVMSupportClass;
211*e82f7db8SAndroid Build Coastguard Worker         jobject localAgentProperties;
212*e82f7db8SAndroid Build Coastguard Worker         jmethodID getAgentProperties;
213*e82f7db8SAndroid Build Coastguard Worker         jint groupCount;
214*e82f7db8SAndroid Build Coastguard Worker         jthreadGroup *groups;
215*e82f7db8SAndroid Build Coastguard Worker         jthreadGroup localSystemThreadGroup;
216*e82f7db8SAndroid Build Coastguard Worker 
217*e82f7db8SAndroid Build Coastguard Worker         /* Find some standard classes */
218*e82f7db8SAndroid Build Coastguard Worker 
219*e82f7db8SAndroid Build Coastguard Worker         localClassClass         = findClass(env,"java/lang/Class");
220*e82f7db8SAndroid Build Coastguard Worker         localThreadClass        = findClass(env,"java/lang/Thread");
221*e82f7db8SAndroid Build Coastguard Worker         localThreadGroupClass   = findClass(env,"java/lang/ThreadGroup");
222*e82f7db8SAndroid Build Coastguard Worker         localClassLoaderClass   = findClass(env,"java/lang/ClassLoader");
223*e82f7db8SAndroid Build Coastguard Worker         localStringClass        = findClass(env,"java/lang/String");
224*e82f7db8SAndroid Build Coastguard Worker         localSystemClass        = findClass(env,"java/lang/System");
225*e82f7db8SAndroid Build Coastguard Worker         localPropertiesClass    = findClass(env,"java/util/Properties");
226*e82f7db8SAndroid Build Coastguard Worker 
227*e82f7db8SAndroid Build Coastguard Worker         /* Save references */
228*e82f7db8SAndroid Build Coastguard Worker 
229*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localClassClass,       &(gdata->classClass));
230*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localThreadClass,      &(gdata->threadClass));
231*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localThreadGroupClass, &(gdata->threadGroupClass));
232*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localClassLoaderClass, &(gdata->classLoaderClass));
233*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localStringClass,      &(gdata->stringClass));
234*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localSystemClass,      &(gdata->systemClass));
235*e82f7db8SAndroid Build Coastguard Worker 
236*e82f7db8SAndroid Build Coastguard Worker         /* Find some standard methods */
237*e82f7db8SAndroid Build Coastguard Worker 
238*e82f7db8SAndroid Build Coastguard Worker         gdata->threadConstructor =
239*e82f7db8SAndroid Build Coastguard Worker                 getMethod(env, gdata->threadClass,
240*e82f7db8SAndroid Build Coastguard Worker                     "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
241*e82f7db8SAndroid Build Coastguard Worker         gdata->threadSetDaemon =
242*e82f7db8SAndroid Build Coastguard Worker                 getMethod(env, gdata->threadClass, "setDaemon", "(Z)V");
243*e82f7db8SAndroid Build Coastguard Worker         gdata->threadResume =
244*e82f7db8SAndroid Build Coastguard Worker                 getMethod(env, gdata->threadClass, "resume", "()V");
245*e82f7db8SAndroid Build Coastguard Worker         gdata->systemGetProperty =
246*e82f7db8SAndroid Build Coastguard Worker                 getStaticMethod(env, gdata->systemClass,
247*e82f7db8SAndroid Build Coastguard Worker                     "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
248*e82f7db8SAndroid Build Coastguard Worker         gdata->setProperty =
249*e82f7db8SAndroid Build Coastguard Worker                 getMethod(env, localPropertiesClass,
250*e82f7db8SAndroid Build Coastguard Worker                     "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
251*e82f7db8SAndroid Build Coastguard Worker 
252*e82f7db8SAndroid Build Coastguard Worker         /* Find the system thread group */
253*e82f7db8SAndroid Build Coastguard Worker 
254*e82f7db8SAndroid Build Coastguard Worker         groups = NULL;
255*e82f7db8SAndroid Build Coastguard Worker         groupCount = 0;
256*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
257*e82f7db8SAndroid Build Coastguard Worker                     (gdata->jvmti, &groupCount, &groups);
258*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE ) {
259*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(error, "Can't get system thread group");
260*e82f7db8SAndroid Build Coastguard Worker         }
261*e82f7db8SAndroid Build Coastguard Worker         if ( groupCount == 0 ) {
262*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "Can't get system thread group");
263*e82f7db8SAndroid Build Coastguard Worker         }
264*e82f7db8SAndroid Build Coastguard Worker         localSystemThreadGroup = groups[0];
265*e82f7db8SAndroid Build Coastguard Worker         saveGlobalRef(env, localSystemThreadGroup, &(gdata->systemThreadGroup));
266*e82f7db8SAndroid Build Coastguard Worker 
267*e82f7db8SAndroid Build Coastguard Worker         /* Get some basic Java property values we will need at some point */
268*e82f7db8SAndroid Build Coastguard Worker         gdata->property_java_version
269*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "java.version");
270*e82f7db8SAndroid Build Coastguard Worker         gdata->property_java_vm_name
271*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "java.vm.name");
272*e82f7db8SAndroid Build Coastguard Worker         // ANDROID-CHANGED: Android doesn't provide the 'java.vm.info' property. Just provide the
273*e82f7db8SAndroid Build Coastguard Worker         //                  rest of the agent with an empty string to use for it.
274*e82f7db8SAndroid Build Coastguard Worker         gdata->property_java_vm_info = jvmtiAllocate(1);
275*e82f7db8SAndroid Build Coastguard Worker         gdata->property_java_vm_info[0] = '\0';
276*e82f7db8SAndroid Build Coastguard Worker         gdata->property_java_class_path
277*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "java.class.path");
278*e82f7db8SAndroid Build Coastguard Worker         // ANDROID-CHANGED: Android uses java.boot.class.path to store the bootclasspath.
279*e82f7db8SAndroid Build Coastguard Worker         gdata->property_sun_boot_class_path
280*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "java.boot.class.path");
281*e82f7db8SAndroid Build Coastguard Worker         // ANDROID-CHANGED: Android uses java.library.path to store all library path information.
282*e82f7db8SAndroid Build Coastguard Worker         gdata->property_sun_boot_library_path
283*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "java.library.path");
284*e82f7db8SAndroid Build Coastguard Worker         gdata->property_path_separator
285*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "path.separator");
286*e82f7db8SAndroid Build Coastguard Worker         gdata->property_user_dir
287*e82f7db8SAndroid Build Coastguard Worker                         = getPropertyUTF8(env, "user.dir");
288*e82f7db8SAndroid Build Coastguard Worker 
289*e82f7db8SAndroid Build Coastguard Worker         /* Get agent properties: invoke sun.misc.VMSupport.getAgentProperties */
290*e82f7db8SAndroid Build Coastguard Worker         localVMSupportClass = JNI_FUNC_PTR(env,FindClass)
291*e82f7db8SAndroid Build Coastguard Worker                                           (env, "sun/misc/VMSupport");
292*e82f7db8SAndroid Build Coastguard Worker         if (localVMSupportClass == NULL) {
293*e82f7db8SAndroid Build Coastguard Worker             gdata->agent_properties = NULL;
294*e82f7db8SAndroid Build Coastguard Worker             if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
295*e82f7db8SAndroid Build Coastguard Worker                 JNI_FUNC_PTR(env,ExceptionClear)(env);
296*e82f7db8SAndroid Build Coastguard Worker             }
297*e82f7db8SAndroid Build Coastguard Worker         } else {
298*e82f7db8SAndroid Build Coastguard Worker             getAgentProperties  =
299*e82f7db8SAndroid Build Coastguard Worker                 getStaticMethod(env, localVMSupportClass,
300*e82f7db8SAndroid Build Coastguard Worker                                 "getAgentProperties", "()Ljava/util/Properties;");
301*e82f7db8SAndroid Build Coastguard Worker             localAgentProperties =
302*e82f7db8SAndroid Build Coastguard Worker                 JNI_FUNC_PTR(env,CallStaticObjectMethod)
303*e82f7db8SAndroid Build Coastguard Worker                             (env, localVMSupportClass, getAgentProperties);
304*e82f7db8SAndroid Build Coastguard Worker             saveGlobalRef(env, localAgentProperties, &(gdata->agent_properties));
305*e82f7db8SAndroid Build Coastguard Worker             if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
306*e82f7db8SAndroid Build Coastguard Worker                 JNI_FUNC_PTR(env,ExceptionClear)(env);
307*e82f7db8SAndroid Build Coastguard Worker                 EXIT_ERROR(AGENT_ERROR_INTERNAL,
308*e82f7db8SAndroid Build Coastguard Worker                     "Exception occurred calling sun.misc.VMSupport.getAgentProperties");
309*e82f7db8SAndroid Build Coastguard Worker             }
310*e82f7db8SAndroid Build Coastguard Worker         }
311*e82f7db8SAndroid Build Coastguard Worker 
312*e82f7db8SAndroid Build Coastguard Worker     } END_WITH_LOCAL_REFS(env);
313*e82f7db8SAndroid Build Coastguard Worker 
314*e82f7db8SAndroid Build Coastguard Worker }
315*e82f7db8SAndroid Build Coastguard Worker 
316*e82f7db8SAndroid Build Coastguard Worker void
util_reset(void)317*e82f7db8SAndroid Build Coastguard Worker util_reset(void)
318*e82f7db8SAndroid Build Coastguard Worker {
319*e82f7db8SAndroid Build Coastguard Worker }
320*e82f7db8SAndroid Build Coastguard Worker 
321*e82f7db8SAndroid Build Coastguard Worker jboolean
isObjectTag(jbyte tag)322*e82f7db8SAndroid Build Coastguard Worker isObjectTag(jbyte tag) {
323*e82f7db8SAndroid Build Coastguard Worker     return (tag == JDWP_TAG(OBJECT)) ||
324*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(STRING)) ||
325*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(THREAD)) ||
326*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(THREAD_GROUP)) ||
327*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(CLASS_LOADER)) ||
328*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(CLASS_OBJECT)) ||
329*e82f7db8SAndroid Build Coastguard Worker            (tag == JDWP_TAG(ARRAY));
330*e82f7db8SAndroid Build Coastguard Worker }
331*e82f7db8SAndroid Build Coastguard Worker 
332*e82f7db8SAndroid Build Coastguard Worker jbyte
specificTypeKey(JNIEnv * env,jobject object)333*e82f7db8SAndroid Build Coastguard Worker specificTypeKey(JNIEnv *env, jobject object)
334*e82f7db8SAndroid Build Coastguard Worker {
335*e82f7db8SAndroid Build Coastguard Worker     if (object == NULL) {
336*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(OBJECT);
337*e82f7db8SAndroid Build Coastguard Worker     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass)) {
338*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(STRING);
339*e82f7db8SAndroid Build Coastguard Worker     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass)) {
340*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(THREAD);
341*e82f7db8SAndroid Build Coastguard Worker     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass)) {
342*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(THREAD_GROUP);
343*e82f7db8SAndroid Build Coastguard Worker     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass)) {
344*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(CLASS_LOADER);
345*e82f7db8SAndroid Build Coastguard Worker     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass)) {
346*e82f7db8SAndroid Build Coastguard Worker         return JDWP_TAG(CLASS_OBJECT);
347*e82f7db8SAndroid Build Coastguard Worker     } else {
348*e82f7db8SAndroid Build Coastguard Worker         jboolean classIsArray;
349*e82f7db8SAndroid Build Coastguard Worker 
350*e82f7db8SAndroid Build Coastguard Worker         WITH_LOCAL_REFS(env, 1) {
351*e82f7db8SAndroid Build Coastguard Worker             jclass clazz;
352*e82f7db8SAndroid Build Coastguard Worker             clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
353*e82f7db8SAndroid Build Coastguard Worker             classIsArray = isArrayClass(clazz);
354*e82f7db8SAndroid Build Coastguard Worker         } END_WITH_LOCAL_REFS(env);
355*e82f7db8SAndroid Build Coastguard Worker 
356*e82f7db8SAndroid Build Coastguard Worker         return (classIsArray ? JDWP_TAG(ARRAY) : JDWP_TAG(OBJECT));
357*e82f7db8SAndroid Build Coastguard Worker     }
358*e82f7db8SAndroid Build Coastguard Worker }
359*e82f7db8SAndroid Build Coastguard Worker 
360*e82f7db8SAndroid Build Coastguard Worker static void
writeFieldValue(JNIEnv * env,PacketOutputStream * out,jobject object,jfieldID field)361*e82f7db8SAndroid Build Coastguard Worker writeFieldValue(JNIEnv *env, PacketOutputStream *out, jobject object,
362*e82f7db8SAndroid Build Coastguard Worker                 jfieldID field)
363*e82f7db8SAndroid Build Coastguard Worker {
364*e82f7db8SAndroid Build Coastguard Worker     jclass clazz;
365*e82f7db8SAndroid Build Coastguard Worker     char *signature = NULL;
366*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
367*e82f7db8SAndroid Build Coastguard Worker     jbyte typeKey;
368*e82f7db8SAndroid Build Coastguard Worker 
369*e82f7db8SAndroid Build Coastguard Worker     clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
370*e82f7db8SAndroid Build Coastguard Worker     error = fieldSignature(clazz, field, NULL, &signature, NULL);
371*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
372*e82f7db8SAndroid Build Coastguard Worker         outStream_setError(out, map2jdwpError(error));
373*e82f7db8SAndroid Build Coastguard Worker         return;
374*e82f7db8SAndroid Build Coastguard Worker     }
375*e82f7db8SAndroid Build Coastguard Worker     typeKey = signature[0];
376*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(signature);
377*e82f7db8SAndroid Build Coastguard Worker 
378*e82f7db8SAndroid Build Coastguard Worker     /*
379*e82f7db8SAndroid Build Coastguard Worker      * For primitive types, the type key is bounced back as is. Objects
380*e82f7db8SAndroid Build Coastguard Worker      * are handled in the switch statement below.
381*e82f7db8SAndroid Build Coastguard Worker      */
382*e82f7db8SAndroid Build Coastguard Worker     if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
383*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeByte(out, typeKey);
384*e82f7db8SAndroid Build Coastguard Worker     }
385*e82f7db8SAndroid Build Coastguard Worker 
386*e82f7db8SAndroid Build Coastguard Worker     switch (typeKey) {
387*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(OBJECT):
388*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(ARRAY):   {
389*e82f7db8SAndroid Build Coastguard Worker             jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field);
390*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeByte(out, specificTypeKey(env, value));
391*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeObjectRef(env, out, value);
392*e82f7db8SAndroid Build Coastguard Worker             break;
393*e82f7db8SAndroid Build Coastguard Worker         }
394*e82f7db8SAndroid Build Coastguard Worker 
395*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BYTE):
396*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeByte(out,
397*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetByteField)(env, object, field));
398*e82f7db8SAndroid Build Coastguard Worker             break;
399*e82f7db8SAndroid Build Coastguard Worker 
400*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(CHAR):
401*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeChar(out,
402*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetCharField)(env, object, field));
403*e82f7db8SAndroid Build Coastguard Worker             break;
404*e82f7db8SAndroid Build Coastguard Worker 
405*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(FLOAT):
406*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeFloat(out,
407*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetFloatField)(env, object, field));
408*e82f7db8SAndroid Build Coastguard Worker             break;
409*e82f7db8SAndroid Build Coastguard Worker 
410*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(DOUBLE):
411*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeDouble(out,
412*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetDoubleField)(env, object, field));
413*e82f7db8SAndroid Build Coastguard Worker             break;
414*e82f7db8SAndroid Build Coastguard Worker 
415*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(INT):
416*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeInt(out,
417*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetIntField)(env, object, field));
418*e82f7db8SAndroid Build Coastguard Worker             break;
419*e82f7db8SAndroid Build Coastguard Worker 
420*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(LONG):
421*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeLong(out,
422*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetLongField)(env, object, field));
423*e82f7db8SAndroid Build Coastguard Worker             break;
424*e82f7db8SAndroid Build Coastguard Worker 
425*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(SHORT):
426*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeShort(out,
427*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetShortField)(env, object, field));
428*e82f7db8SAndroid Build Coastguard Worker             break;
429*e82f7db8SAndroid Build Coastguard Worker 
430*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BOOLEAN):
431*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeBoolean(out,
432*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetBooleanField)(env, object, field));
433*e82f7db8SAndroid Build Coastguard Worker             break;
434*e82f7db8SAndroid Build Coastguard Worker     }
435*e82f7db8SAndroid Build Coastguard Worker }
436*e82f7db8SAndroid Build Coastguard Worker 
437*e82f7db8SAndroid Build Coastguard Worker static void
writeStaticFieldValue(JNIEnv * env,PacketOutputStream * out,jclass clazz,jfieldID field)438*e82f7db8SAndroid Build Coastguard Worker writeStaticFieldValue(JNIEnv *env, PacketOutputStream *out, jclass clazz,
439*e82f7db8SAndroid Build Coastguard Worker                       jfieldID field)
440*e82f7db8SAndroid Build Coastguard Worker {
441*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
442*e82f7db8SAndroid Build Coastguard Worker     char *signature = NULL;
443*e82f7db8SAndroid Build Coastguard Worker     jbyte typeKey;
444*e82f7db8SAndroid Build Coastguard Worker 
445*e82f7db8SAndroid Build Coastguard Worker     error = fieldSignature(clazz, field, NULL, &signature, NULL);
446*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
447*e82f7db8SAndroid Build Coastguard Worker         outStream_setError(out, map2jdwpError(error));
448*e82f7db8SAndroid Build Coastguard Worker         return;
449*e82f7db8SAndroid Build Coastguard Worker     }
450*e82f7db8SAndroid Build Coastguard Worker     typeKey = signature[0];
451*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(signature);
452*e82f7db8SAndroid Build Coastguard Worker 
453*e82f7db8SAndroid Build Coastguard Worker     /*
454*e82f7db8SAndroid Build Coastguard Worker      * For primitive types, the type key is bounced back as is. Objects
455*e82f7db8SAndroid Build Coastguard Worker      * are handled in the switch statement below.
456*e82f7db8SAndroid Build Coastguard Worker      */
457*e82f7db8SAndroid Build Coastguard Worker     if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
458*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeByte(out, typeKey);
459*e82f7db8SAndroid Build Coastguard Worker     }
460*e82f7db8SAndroid Build Coastguard Worker 
461*e82f7db8SAndroid Build Coastguard Worker     switch (typeKey) {
462*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(OBJECT):
463*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(ARRAY):   {
464*e82f7db8SAndroid Build Coastguard Worker             jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field);
465*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeByte(out, specificTypeKey(env, value));
466*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeObjectRef(env, out, value);
467*e82f7db8SAndroid Build Coastguard Worker             break;
468*e82f7db8SAndroid Build Coastguard Worker         }
469*e82f7db8SAndroid Build Coastguard Worker 
470*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BYTE):
471*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeByte(out,
472*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field));
473*e82f7db8SAndroid Build Coastguard Worker             break;
474*e82f7db8SAndroid Build Coastguard Worker 
475*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(CHAR):
476*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeChar(out,
477*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticCharField)(env, clazz, field));
478*e82f7db8SAndroid Build Coastguard Worker             break;
479*e82f7db8SAndroid Build Coastguard Worker 
480*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(FLOAT):
481*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeFloat(out,
482*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticFloatField)(env, clazz, field));
483*e82f7db8SAndroid Build Coastguard Worker             break;
484*e82f7db8SAndroid Build Coastguard Worker 
485*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(DOUBLE):
486*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeDouble(out,
487*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticDoubleField)(env, clazz, field));
488*e82f7db8SAndroid Build Coastguard Worker             break;
489*e82f7db8SAndroid Build Coastguard Worker 
490*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(INT):
491*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeInt(out,
492*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticIntField)(env, clazz, field));
493*e82f7db8SAndroid Build Coastguard Worker             break;
494*e82f7db8SAndroid Build Coastguard Worker 
495*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(LONG):
496*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeLong(out,
497*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticLongField)(env, clazz, field));
498*e82f7db8SAndroid Build Coastguard Worker             break;
499*e82f7db8SAndroid Build Coastguard Worker 
500*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(SHORT):
501*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeShort(out,
502*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticShortField)(env, clazz, field));
503*e82f7db8SAndroid Build Coastguard Worker             break;
504*e82f7db8SAndroid Build Coastguard Worker 
505*e82f7db8SAndroid Build Coastguard Worker         case JDWP_TAG(BOOLEAN):
506*e82f7db8SAndroid Build Coastguard Worker             (void)outStream_writeBoolean(out,
507*e82f7db8SAndroid Build Coastguard Worker                       JNI_FUNC_PTR(env,GetStaticBooleanField)(env, clazz, field));
508*e82f7db8SAndroid Build Coastguard Worker             break;
509*e82f7db8SAndroid Build Coastguard Worker     }
510*e82f7db8SAndroid Build Coastguard Worker }
511*e82f7db8SAndroid Build Coastguard Worker 
512*e82f7db8SAndroid Build Coastguard Worker void
sharedGetFieldValues(PacketInputStream * in,PacketOutputStream * out,jboolean isStatic)513*e82f7db8SAndroid Build Coastguard Worker sharedGetFieldValues(PacketInputStream *in, PacketOutputStream *out,
514*e82f7db8SAndroid Build Coastguard Worker                      jboolean isStatic)
515*e82f7db8SAndroid Build Coastguard Worker {
516*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
517*e82f7db8SAndroid Build Coastguard Worker     jint length;
518*e82f7db8SAndroid Build Coastguard Worker     jobject object;
519*e82f7db8SAndroid Build Coastguard Worker     jclass clazz;
520*e82f7db8SAndroid Build Coastguard Worker 
521*e82f7db8SAndroid Build Coastguard Worker     object = NULL;
522*e82f7db8SAndroid Build Coastguard Worker     clazz  = NULL;
523*e82f7db8SAndroid Build Coastguard Worker 
524*e82f7db8SAndroid Build Coastguard Worker     if (isStatic) {
525*e82f7db8SAndroid Build Coastguard Worker         clazz = inStream_readClassRef(env, in);
526*e82f7db8SAndroid Build Coastguard Worker     } else {
527*e82f7db8SAndroid Build Coastguard Worker         object = inStream_readObjectRef(env, in);
528*e82f7db8SAndroid Build Coastguard Worker     }
529*e82f7db8SAndroid Build Coastguard Worker 
530*e82f7db8SAndroid Build Coastguard Worker     length = inStream_readInt(in);
531*e82f7db8SAndroid Build Coastguard Worker     if (inStream_error(in)) {
532*e82f7db8SAndroid Build Coastguard Worker         return;
533*e82f7db8SAndroid Build Coastguard Worker     }
534*e82f7db8SAndroid Build Coastguard Worker 
535*e82f7db8SAndroid Build Coastguard Worker     WITH_LOCAL_REFS(env, length + 1) { /* +1 for class with instance fields */
536*e82f7db8SAndroid Build Coastguard Worker 
537*e82f7db8SAndroid Build Coastguard Worker         int i;
538*e82f7db8SAndroid Build Coastguard Worker 
539*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeInt(out, length);
540*e82f7db8SAndroid Build Coastguard Worker         for (i = 0; (i < length) && !outStream_error(out); i++) {
541*e82f7db8SAndroid Build Coastguard Worker             jfieldID field = inStream_readFieldID(in);
542*e82f7db8SAndroid Build Coastguard Worker 
543*e82f7db8SAndroid Build Coastguard Worker             if (isStatic) {
544*e82f7db8SAndroid Build Coastguard Worker                 writeStaticFieldValue(env, out, clazz, field);
545*e82f7db8SAndroid Build Coastguard Worker             } else {
546*e82f7db8SAndroid Build Coastguard Worker                 writeFieldValue(env, out, object, field);
547*e82f7db8SAndroid Build Coastguard Worker             }
548*e82f7db8SAndroid Build Coastguard Worker         }
549*e82f7db8SAndroid Build Coastguard Worker 
550*e82f7db8SAndroid Build Coastguard Worker     } END_WITH_LOCAL_REFS(env);
551*e82f7db8SAndroid Build Coastguard Worker }
552*e82f7db8SAndroid Build Coastguard Worker 
553*e82f7db8SAndroid Build Coastguard Worker jboolean
sharedInvoke(PacketInputStream * in,PacketOutputStream * out)554*e82f7db8SAndroid Build Coastguard Worker sharedInvoke(PacketInputStream *in, PacketOutputStream *out)
555*e82f7db8SAndroid Build Coastguard Worker {
556*e82f7db8SAndroid Build Coastguard Worker     jvalue *arguments = NULL;
557*e82f7db8SAndroid Build Coastguard Worker     jint options;
558*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
559*e82f7db8SAndroid Build Coastguard Worker     jbyte invokeType;
560*e82f7db8SAndroid Build Coastguard Worker     jclass clazz;
561*e82f7db8SAndroid Build Coastguard Worker     jmethodID method;
562*e82f7db8SAndroid Build Coastguard Worker     jint argumentCount;
563*e82f7db8SAndroid Build Coastguard Worker     jobject instance;
564*e82f7db8SAndroid Build Coastguard Worker     jthread thread;
565*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env;
566*e82f7db8SAndroid Build Coastguard Worker 
567*e82f7db8SAndroid Build Coastguard Worker     /*
568*e82f7db8SAndroid Build Coastguard Worker      * Instance methods start with the instance, thread and class,
569*e82f7db8SAndroid Build Coastguard Worker      * and statics and constructors start with the class and then the
570*e82f7db8SAndroid Build Coastguard Worker      * thread.
571*e82f7db8SAndroid Build Coastguard Worker      */
572*e82f7db8SAndroid Build Coastguard Worker     env = getEnv();
573*e82f7db8SAndroid Build Coastguard Worker     if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
574*e82f7db8SAndroid Build Coastguard Worker         instance = inStream_readObjectRef(env, in);
575*e82f7db8SAndroid Build Coastguard Worker         thread = inStream_readThreadRef(env, in);
576*e82f7db8SAndroid Build Coastguard Worker         clazz = inStream_readClassRef(env, in);
577*e82f7db8SAndroid Build Coastguard Worker     } else { /* static method or constructor */
578*e82f7db8SAndroid Build Coastguard Worker         instance = NULL;
579*e82f7db8SAndroid Build Coastguard Worker         clazz = inStream_readClassRef(env, in);
580*e82f7db8SAndroid Build Coastguard Worker         thread = inStream_readThreadRef(env, in);
581*e82f7db8SAndroid Build Coastguard Worker     }
582*e82f7db8SAndroid Build Coastguard Worker 
583*e82f7db8SAndroid Build Coastguard Worker     /*
584*e82f7db8SAndroid Build Coastguard Worker      * ... and the rest of the packet is identical for all commands
585*e82f7db8SAndroid Build Coastguard Worker      */
586*e82f7db8SAndroid Build Coastguard Worker     method = inStream_readMethodID(in);
587*e82f7db8SAndroid Build Coastguard Worker     argumentCount = inStream_readInt(in);
588*e82f7db8SAndroid Build Coastguard Worker     if (inStream_error(in)) {
589*e82f7db8SAndroid Build Coastguard Worker         return JNI_TRUE;
590*e82f7db8SAndroid Build Coastguard Worker     }
591*e82f7db8SAndroid Build Coastguard Worker 
592*e82f7db8SAndroid Build Coastguard Worker     /* If count == 0, don't try and allocate 0 bytes, you'll get NULL */
593*e82f7db8SAndroid Build Coastguard Worker     if ( argumentCount > 0 ) {
594*e82f7db8SAndroid Build Coastguard Worker         int i;
595*e82f7db8SAndroid Build Coastguard Worker         /*LINTED*/
596*e82f7db8SAndroid Build Coastguard Worker         arguments = jvmtiAllocate(argumentCount * (jint)sizeof(*arguments));
597*e82f7db8SAndroid Build Coastguard Worker         if (arguments == NULL) {
598*e82f7db8SAndroid Build Coastguard Worker             outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
599*e82f7db8SAndroid Build Coastguard Worker             return JNI_TRUE;
600*e82f7db8SAndroid Build Coastguard Worker         }
601*e82f7db8SAndroid Build Coastguard Worker         for (i = 0; (i < argumentCount) && !inStream_error(in); i++) {
602*e82f7db8SAndroid Build Coastguard Worker             arguments[i] = inStream_readValue(in, NULL);
603*e82f7db8SAndroid Build Coastguard Worker         }
604*e82f7db8SAndroid Build Coastguard Worker         if (inStream_error(in)) {
605*e82f7db8SAndroid Build Coastguard Worker             return JNI_TRUE;
606*e82f7db8SAndroid Build Coastguard Worker         }
607*e82f7db8SAndroid Build Coastguard Worker     }
608*e82f7db8SAndroid Build Coastguard Worker 
609*e82f7db8SAndroid Build Coastguard Worker     options = inStream_readInt(in);
610*e82f7db8SAndroid Build Coastguard Worker     if (inStream_error(in)) {
611*e82f7db8SAndroid Build Coastguard Worker         if ( arguments != NULL ) {
612*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(arguments);
613*e82f7db8SAndroid Build Coastguard Worker         }
614*e82f7db8SAndroid Build Coastguard Worker         return JNI_TRUE;
615*e82f7db8SAndroid Build Coastguard Worker     }
616*e82f7db8SAndroid Build Coastguard Worker 
617*e82f7db8SAndroid Build Coastguard Worker     if (inStream_command(in) == JDWP_COMMAND(ClassType, NewInstance)) {
618*e82f7db8SAndroid Build Coastguard Worker         invokeType = INVOKE_CONSTRUCTOR;
619*e82f7db8SAndroid Build Coastguard Worker     } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) {
620*e82f7db8SAndroid Build Coastguard Worker         invokeType = INVOKE_STATIC;
621*e82f7db8SAndroid Build Coastguard Worker     } else if (inStream_command(in) == JDWP_COMMAND(InterfaceType, InvokeMethod)) {
622*e82f7db8SAndroid Build Coastguard Worker         invokeType = INVOKE_STATIC;
623*e82f7db8SAndroid Build Coastguard Worker     } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
624*e82f7db8SAndroid Build Coastguard Worker         invokeType = INVOKE_INSTANCE;
625*e82f7db8SAndroid Build Coastguard Worker     } else {
626*e82f7db8SAndroid Build Coastguard Worker         outStream_setError(out, JDWP_ERROR(INTERNAL));
627*e82f7db8SAndroid Build Coastguard Worker         if ( arguments != NULL ) {
628*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(arguments);
629*e82f7db8SAndroid Build Coastguard Worker         }
630*e82f7db8SAndroid Build Coastguard Worker         return JNI_TRUE;
631*e82f7db8SAndroid Build Coastguard Worker     }
632*e82f7db8SAndroid Build Coastguard Worker 
633*e82f7db8SAndroid Build Coastguard Worker     /*
634*e82f7db8SAndroid Build Coastguard Worker      * Request the invoke. If there are no errors in the request,
635*e82f7db8SAndroid Build Coastguard Worker      * the interrupting thread will actually do the invoke and a
636*e82f7db8SAndroid Build Coastguard Worker      * reply will be generated subsequently, so we don't reply here.
637*e82f7db8SAndroid Build Coastguard Worker      */
638*e82f7db8SAndroid Build Coastguard Worker     error = invoker_requestInvoke(invokeType, (jbyte)options, inStream_id(in),
639*e82f7db8SAndroid Build Coastguard Worker                                   thread, clazz, method,
640*e82f7db8SAndroid Build Coastguard Worker                                   instance, arguments, argumentCount);
641*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
642*e82f7db8SAndroid Build Coastguard Worker         outStream_setError(out, map2jdwpError(error));
643*e82f7db8SAndroid Build Coastguard Worker         if ( arguments != NULL ) {
644*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(arguments);
645*e82f7db8SAndroid Build Coastguard Worker         }
646*e82f7db8SAndroid Build Coastguard Worker         return JNI_TRUE;
647*e82f7db8SAndroid Build Coastguard Worker     }
648*e82f7db8SAndroid Build Coastguard Worker 
649*e82f7db8SAndroid Build Coastguard Worker     return JNI_FALSE;   /* Don't reply */
650*e82f7db8SAndroid Build Coastguard Worker }
651*e82f7db8SAndroid Build Coastguard Worker 
652*e82f7db8SAndroid Build Coastguard Worker jint
uniqueID(void)653*e82f7db8SAndroid Build Coastguard Worker uniqueID(void)
654*e82f7db8SAndroid Build Coastguard Worker {
655*e82f7db8SAndroid Build Coastguard Worker     static jint currentID = 0;
656*e82f7db8SAndroid Build Coastguard Worker     // ANDROID-CHANGED: on android we sometimes need to share these id's with DDMS traffic that is
657*e82f7db8SAndroid Build Coastguard Worker     // multiplexed on the same connection. Since we don't have any way to know which id's are taken
658*e82f7db8SAndroid Build Coastguard Worker     // by DDMS we will instead partition the ids between them. All positive ids (sign-bit == 0) are
659*e82f7db8SAndroid Build Coastguard Worker     // reserved for libjdwp. DDMS will take ids with sign-bit == 1. This condition is not expected
660*e82f7db8SAndroid Build Coastguard Worker     // to ever be true on a normal debugging session.
661*e82f7db8SAndroid Build Coastguard Worker     if (currentID < 0) {
662*e82f7db8SAndroid Build Coastguard Worker       currentID = 0;
663*e82f7db8SAndroid Build Coastguard Worker     }
664*e82f7db8SAndroid Build Coastguard Worker     return currentID++;
665*e82f7db8SAndroid Build Coastguard Worker }
666*e82f7db8SAndroid Build Coastguard Worker 
667*e82f7db8SAndroid Build Coastguard Worker int
filterDebugThreads(jthread * threads,int count)668*e82f7db8SAndroid Build Coastguard Worker filterDebugThreads(jthread *threads, int count)
669*e82f7db8SAndroid Build Coastguard Worker {
670*e82f7db8SAndroid Build Coastguard Worker     int i;
671*e82f7db8SAndroid Build Coastguard Worker     int current;
672*e82f7db8SAndroid Build Coastguard Worker 
673*e82f7db8SAndroid Build Coastguard Worker     /* Squish out all of the debugger-spawned threads */
674*e82f7db8SAndroid Build Coastguard Worker     for (i = 0, current = 0; i < count; i++) {
675*e82f7db8SAndroid Build Coastguard Worker         jthread thread = threads[i];
676*e82f7db8SAndroid Build Coastguard Worker         if (!threadControl_isDebugThread(thread)) {
677*e82f7db8SAndroid Build Coastguard Worker             if (i > current) {
678*e82f7db8SAndroid Build Coastguard Worker                 threads[current] = thread;
679*e82f7db8SAndroid Build Coastguard Worker             }
680*e82f7db8SAndroid Build Coastguard Worker             current++;
681*e82f7db8SAndroid Build Coastguard Worker         }
682*e82f7db8SAndroid Build Coastguard Worker     }
683*e82f7db8SAndroid Build Coastguard Worker     return current;
684*e82f7db8SAndroid Build Coastguard Worker }
685*e82f7db8SAndroid Build Coastguard Worker 
686*e82f7db8SAndroid Build Coastguard Worker jbyte
referenceTypeTag(jclass clazz)687*e82f7db8SAndroid Build Coastguard Worker referenceTypeTag(jclass clazz)
688*e82f7db8SAndroid Build Coastguard Worker {
689*e82f7db8SAndroid Build Coastguard Worker     jbyte tag;
690*e82f7db8SAndroid Build Coastguard Worker 
691*e82f7db8SAndroid Build Coastguard Worker     if (isInterface(clazz)) {
692*e82f7db8SAndroid Build Coastguard Worker         tag = JDWP_TYPE_TAG(INTERFACE);
693*e82f7db8SAndroid Build Coastguard Worker     } else if (isArrayClass(clazz)) {
694*e82f7db8SAndroid Build Coastguard Worker         tag = JDWP_TYPE_TAG(ARRAY);
695*e82f7db8SAndroid Build Coastguard Worker     } else {
696*e82f7db8SAndroid Build Coastguard Worker         tag = JDWP_TYPE_TAG(CLASS);
697*e82f7db8SAndroid Build Coastguard Worker     }
698*e82f7db8SAndroid Build Coastguard Worker 
699*e82f7db8SAndroid Build Coastguard Worker     return tag;
700*e82f7db8SAndroid Build Coastguard Worker }
701*e82f7db8SAndroid Build Coastguard Worker 
702*e82f7db8SAndroid Build Coastguard Worker /**
703*e82f7db8SAndroid Build Coastguard Worker  * Get field modifiers
704*e82f7db8SAndroid Build Coastguard Worker  */
705*e82f7db8SAndroid Build Coastguard Worker jvmtiError
fieldModifiers(jclass clazz,jfieldID field,jint * pmodifiers)706*e82f7db8SAndroid Build Coastguard Worker fieldModifiers(jclass clazz, jfieldID field, jint *pmodifiers)
707*e82f7db8SAndroid Build Coastguard Worker {
708*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
709*e82f7db8SAndroid Build Coastguard Worker 
710*e82f7db8SAndroid Build Coastguard Worker     *pmodifiers = 0;
711*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
712*e82f7db8SAndroid Build Coastguard Worker             (gdata->jvmti, clazz, field, pmodifiers);
713*e82f7db8SAndroid Build Coastguard Worker     return error;
714*e82f7db8SAndroid Build Coastguard Worker }
715*e82f7db8SAndroid Build Coastguard Worker 
716*e82f7db8SAndroid Build Coastguard Worker /**
717*e82f7db8SAndroid Build Coastguard Worker  * Get method modifiers
718*e82f7db8SAndroid Build Coastguard Worker  */
719*e82f7db8SAndroid Build Coastguard Worker jvmtiError
methodModifiers(jmethodID method,jint * pmodifiers)720*e82f7db8SAndroid Build Coastguard Worker methodModifiers(jmethodID method, jint *pmodifiers)
721*e82f7db8SAndroid Build Coastguard Worker {
722*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
723*e82f7db8SAndroid Build Coastguard Worker 
724*e82f7db8SAndroid Build Coastguard Worker     *pmodifiers = 0;
725*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodModifiers)
726*e82f7db8SAndroid Build Coastguard Worker             (gdata->jvmti, method, pmodifiers);
727*e82f7db8SAndroid Build Coastguard Worker     return error;
728*e82f7db8SAndroid Build Coastguard Worker }
729*e82f7db8SAndroid Build Coastguard Worker 
730*e82f7db8SAndroid Build Coastguard Worker /* Returns a local ref to the declaring class for a method, or NULL. */
731*e82f7db8SAndroid Build Coastguard Worker jvmtiError
methodClass(jmethodID method,jclass * pclazz)732*e82f7db8SAndroid Build Coastguard Worker methodClass(jmethodID method, jclass *pclazz)
733*e82f7db8SAndroid Build Coastguard Worker {
734*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
735*e82f7db8SAndroid Build Coastguard Worker 
736*e82f7db8SAndroid Build Coastguard Worker     *pclazz = NULL;
737*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
738*e82f7db8SAndroid Build Coastguard Worker                                 (gdata->jvmti, method, pclazz);
739*e82f7db8SAndroid Build Coastguard Worker     return error;
740*e82f7db8SAndroid Build Coastguard Worker }
741*e82f7db8SAndroid Build Coastguard Worker 
742*e82f7db8SAndroid Build Coastguard Worker /* Returns a local ref to the declaring class for a method, or NULL. */
743*e82f7db8SAndroid Build Coastguard Worker jvmtiError
methodLocation(jmethodID method,jlocation * ploc1,jlocation * ploc2)744*e82f7db8SAndroid Build Coastguard Worker methodLocation(jmethodID method, jlocation *ploc1, jlocation *ploc2)
745*e82f7db8SAndroid Build Coastguard Worker {
746*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
747*e82f7db8SAndroid Build Coastguard Worker 
748*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodLocation)
749*e82f7db8SAndroid Build Coastguard Worker                                 (gdata->jvmti, method, ploc1, ploc2);
750*e82f7db8SAndroid Build Coastguard Worker     return error;
751*e82f7db8SAndroid Build Coastguard Worker }
752*e82f7db8SAndroid Build Coastguard Worker 
753*e82f7db8SAndroid Build Coastguard Worker /**
754*e82f7db8SAndroid Build Coastguard Worker  * Get method signature
755*e82f7db8SAndroid Build Coastguard Worker  */
756*e82f7db8SAndroid Build Coastguard Worker jvmtiError
methodSignature(jmethodID method,char ** pname,char ** psignature,char ** pgeneric_signature)757*e82f7db8SAndroid Build Coastguard Worker methodSignature(jmethodID method,
758*e82f7db8SAndroid Build Coastguard Worker         char **pname, char **psignature, char **pgeneric_signature)
759*e82f7db8SAndroid Build Coastguard Worker {
760*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
761*e82f7db8SAndroid Build Coastguard Worker     char *name = NULL;
762*e82f7db8SAndroid Build Coastguard Worker     char *signature = NULL;
763*e82f7db8SAndroid Build Coastguard Worker     char *generic_signature = NULL;
764*e82f7db8SAndroid Build Coastguard Worker 
765*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,GetMethodName)
766*e82f7db8SAndroid Build Coastguard Worker             (gdata->jvmti, method, &name, &signature, &generic_signature);
767*e82f7db8SAndroid Build Coastguard Worker 
768*e82f7db8SAndroid Build Coastguard Worker     if ( pname != NULL ) {
769*e82f7db8SAndroid Build Coastguard Worker         *pname = name;
770*e82f7db8SAndroid Build Coastguard Worker     } else if ( name != NULL )  {
771*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(name);
772*e82f7db8SAndroid Build Coastguard Worker     }
773*e82f7db8SAndroid Build Coastguard Worker     if ( psignature != NULL ) {
774*e82f7db8SAndroid Build Coastguard Worker         *psignature = signature;
775*e82f7db8SAndroid Build Coastguard Worker     } else if ( signature != NULL ) {
776*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(signature);
777*e82f7db8SAndroid Build Coastguard Worker     }
778*e82f7db8SAndroid Build Coastguard Worker     if ( pgeneric_signature != NULL ) {
779*e82f7db8SAndroid Build Coastguard Worker         *pgeneric_signature = generic_signature;
780*e82f7db8SAndroid Build Coastguard Worker     } else if ( generic_signature != NULL )  {
781*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(generic_signature);
782*e82f7db8SAndroid Build Coastguard Worker     }
783*e82f7db8SAndroid Build Coastguard Worker     return error;
784*e82f7db8SAndroid Build Coastguard Worker }
785*e82f7db8SAndroid Build Coastguard Worker 
786*e82f7db8SAndroid Build Coastguard Worker /*
787*e82f7db8SAndroid Build Coastguard Worker  * Get the return type key of the method
788*e82f7db8SAndroid Build Coastguard Worker  *     V or B C D F I J S Z L  [
789*e82f7db8SAndroid Build Coastguard Worker  */
790*e82f7db8SAndroid Build Coastguard Worker jvmtiError
methodReturnType(jmethodID method,char * typeKey)791*e82f7db8SAndroid Build Coastguard Worker methodReturnType(jmethodID method, char *typeKey)
792*e82f7db8SAndroid Build Coastguard Worker {
793*e82f7db8SAndroid Build Coastguard Worker     char       *signature;
794*e82f7db8SAndroid Build Coastguard Worker     jvmtiError  error;
795*e82f7db8SAndroid Build Coastguard Worker 
796*e82f7db8SAndroid Build Coastguard Worker     signature = NULL;
797*e82f7db8SAndroid Build Coastguard Worker     error     = methodSignature(method, NULL, &signature, NULL);
798*e82f7db8SAndroid Build Coastguard Worker     if (error == JVMTI_ERROR_NONE) {
799*e82f7db8SAndroid Build Coastguard Worker         if (signature == NULL ) {
800*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_INVALID_TAG;
801*e82f7db8SAndroid Build Coastguard Worker         } else {
802*e82f7db8SAndroid Build Coastguard Worker             char * xx;
803*e82f7db8SAndroid Build Coastguard Worker 
804*e82f7db8SAndroid Build Coastguard Worker             xx = strchr(signature, ')');
805*e82f7db8SAndroid Build Coastguard Worker             if (xx == NULL || *(xx + 1) == 0) {
806*e82f7db8SAndroid Build Coastguard Worker                 error = AGENT_ERROR_INVALID_TAG;
807*e82f7db8SAndroid Build Coastguard Worker             } else {
808*e82f7db8SAndroid Build Coastguard Worker                *typeKey = *(xx + 1);
809*e82f7db8SAndroid Build Coastguard Worker             }
810*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(signature);
811*e82f7db8SAndroid Build Coastguard Worker         }
812*e82f7db8SAndroid Build Coastguard Worker     }
813*e82f7db8SAndroid Build Coastguard Worker     return error;
814*e82f7db8SAndroid Build Coastguard Worker }
815*e82f7db8SAndroid Build Coastguard Worker 
816*e82f7db8SAndroid Build Coastguard Worker 
817*e82f7db8SAndroid Build Coastguard Worker /**
818*e82f7db8SAndroid Build Coastguard Worker  * Return class loader for a class (must be inside a WITH_LOCAL_REFS)
819*e82f7db8SAndroid Build Coastguard Worker  */
820*e82f7db8SAndroid Build Coastguard Worker jvmtiError
classLoader(jclass clazz,jobject * pclazz)821*e82f7db8SAndroid Build Coastguard Worker classLoader(jclass clazz, jobject *pclazz)
822*e82f7db8SAndroid Build Coastguard Worker {
823*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
824*e82f7db8SAndroid Build Coastguard Worker 
825*e82f7db8SAndroid Build Coastguard Worker     *pclazz = NULL;
826*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
827*e82f7db8SAndroid Build Coastguard Worker             (gdata->jvmti, clazz, pclazz);
828*e82f7db8SAndroid Build Coastguard Worker     return error;
829*e82f7db8SAndroid Build Coastguard Worker }
830*e82f7db8SAndroid Build Coastguard Worker 
831*e82f7db8SAndroid Build Coastguard Worker /**
832*e82f7db8SAndroid Build Coastguard Worker  * Get field signature
833*e82f7db8SAndroid Build Coastguard Worker  */
834*e82f7db8SAndroid Build Coastguard Worker jvmtiError
fieldSignature(jclass clazz,jfieldID field,char ** pname,char ** psignature,char ** pgeneric_signature)835*e82f7db8SAndroid Build Coastguard Worker fieldSignature(jclass clazz, jfieldID field,
836*e82f7db8SAndroid Build Coastguard Worker         char **pname, char **psignature, char **pgeneric_signature)
837*e82f7db8SAndroid Build Coastguard Worker {
838*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
839*e82f7db8SAndroid Build Coastguard Worker     char *name = NULL;
840*e82f7db8SAndroid Build Coastguard Worker     char *signature = NULL;
841*e82f7db8SAndroid Build Coastguard Worker     char *generic_signature = NULL;
842*e82f7db8SAndroid Build Coastguard Worker 
843*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
844*e82f7db8SAndroid Build Coastguard Worker             (gdata->jvmti, clazz, field, &name, &signature, &generic_signature);
845*e82f7db8SAndroid Build Coastguard Worker 
846*e82f7db8SAndroid Build Coastguard Worker     if ( pname != NULL ) {
847*e82f7db8SAndroid Build Coastguard Worker         *pname = name;
848*e82f7db8SAndroid Build Coastguard Worker     } else if ( name != NULL )  {
849*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(name);
850*e82f7db8SAndroid Build Coastguard Worker     }
851*e82f7db8SAndroid Build Coastguard Worker     if ( psignature != NULL ) {
852*e82f7db8SAndroid Build Coastguard Worker         *psignature = signature;
853*e82f7db8SAndroid Build Coastguard Worker     } else if ( signature != NULL )  {
854*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(signature);
855*e82f7db8SAndroid Build Coastguard Worker     }
856*e82f7db8SAndroid Build Coastguard Worker     if ( pgeneric_signature != NULL ) {
857*e82f7db8SAndroid Build Coastguard Worker         *pgeneric_signature = generic_signature;
858*e82f7db8SAndroid Build Coastguard Worker     } else if ( generic_signature != NULL )  {
859*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(generic_signature);
860*e82f7db8SAndroid Build Coastguard Worker     }
861*e82f7db8SAndroid Build Coastguard Worker     return error;
862*e82f7db8SAndroid Build Coastguard Worker }
863*e82f7db8SAndroid Build Coastguard Worker 
864*e82f7db8SAndroid Build Coastguard Worker JNIEnv *
getEnv(void)865*e82f7db8SAndroid Build Coastguard Worker getEnv(void)
866*e82f7db8SAndroid Build Coastguard Worker {
867*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = NULL;
868*e82f7db8SAndroid Build Coastguard Worker     jint rc;
869*e82f7db8SAndroid Build Coastguard Worker 
870*e82f7db8SAndroid Build Coastguard Worker     rc = FUNC_PTR(gdata->jvm,GetEnv)
871*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
872*e82f7db8SAndroid Build Coastguard Worker     if (rc != JNI_OK) {
873*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = %d",
874*e82f7db8SAndroid Build Coastguard Worker                 rc));
875*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NO_JNI_ENV,NULL);
876*e82f7db8SAndroid Build Coastguard Worker     }
877*e82f7db8SAndroid Build Coastguard Worker     return env;
878*e82f7db8SAndroid Build Coastguard Worker }
879*e82f7db8SAndroid Build Coastguard Worker 
880*e82f7db8SAndroid Build Coastguard Worker jvmtiError
spawnNewThread(jvmtiStartFunction func,void * arg,char * name)881*e82f7db8SAndroid Build Coastguard Worker spawnNewThread(jvmtiStartFunction func, void *arg, char *name)
882*e82f7db8SAndroid Build Coastguard Worker {
883*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
884*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
885*e82f7db8SAndroid Build Coastguard Worker 
886*e82f7db8SAndroid Build Coastguard Worker     LOG_MISC(("Spawning new thread: %s", name));
887*e82f7db8SAndroid Build Coastguard Worker 
888*e82f7db8SAndroid Build Coastguard Worker     WITH_LOCAL_REFS(env, 3) {
889*e82f7db8SAndroid Build Coastguard Worker 
890*e82f7db8SAndroid Build Coastguard Worker         jthread thread;
891*e82f7db8SAndroid Build Coastguard Worker         jstring nameString;
892*e82f7db8SAndroid Build Coastguard Worker 
893*e82f7db8SAndroid Build Coastguard Worker         nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
894*e82f7db8SAndroid Build Coastguard Worker         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
895*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ExceptionClear)(env);
896*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_OUT_OF_MEMORY;
897*e82f7db8SAndroid Build Coastguard Worker             goto err;
898*e82f7db8SAndroid Build Coastguard Worker         }
899*e82f7db8SAndroid Build Coastguard Worker 
900*e82f7db8SAndroid Build Coastguard Worker         thread = JNI_FUNC_PTR(env,NewObject)
901*e82f7db8SAndroid Build Coastguard Worker                         (env, gdata->threadClass, gdata->threadConstructor,
902*e82f7db8SAndroid Build Coastguard Worker                                    gdata->systemThreadGroup, nameString);
903*e82f7db8SAndroid Build Coastguard Worker         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
904*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ExceptionClear)(env);
905*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_OUT_OF_MEMORY;
906*e82f7db8SAndroid Build Coastguard Worker             goto err;
907*e82f7db8SAndroid Build Coastguard Worker         }
908*e82f7db8SAndroid Build Coastguard Worker 
909*e82f7db8SAndroid Build Coastguard Worker         /*
910*e82f7db8SAndroid Build Coastguard Worker          * Make the debugger thread a daemon
911*e82f7db8SAndroid Build Coastguard Worker          */
912*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,CallVoidMethod)
913*e82f7db8SAndroid Build Coastguard Worker                         (env, thread, gdata->threadSetDaemon, JNI_TRUE);
914*e82f7db8SAndroid Build Coastguard Worker         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
915*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ExceptionClear)(env);
916*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_JNI_EXCEPTION;
917*e82f7db8SAndroid Build Coastguard Worker             goto err;
918*e82f7db8SAndroid Build Coastguard Worker         }
919*e82f7db8SAndroid Build Coastguard Worker 
920*e82f7db8SAndroid Build Coastguard Worker         error = threadControl_addDebugThread(thread);
921*e82f7db8SAndroid Build Coastguard Worker         if (error == JVMTI_ERROR_NONE) {
922*e82f7db8SAndroid Build Coastguard Worker             /*
923*e82f7db8SAndroid Build Coastguard Worker              * Debugger threads need cycles in all sorts of strange
924*e82f7db8SAndroid Build Coastguard Worker              * situations (e.g. infinite cpu-bound loops), so give the
925*e82f7db8SAndroid Build Coastguard Worker              * thread a high priority. Note that if the VM has an application
926*e82f7db8SAndroid Build Coastguard Worker              * thread running at the max priority, there is still a chance
927*e82f7db8SAndroid Build Coastguard Worker              * that debugger threads will be starved. (There needs to be
928*e82f7db8SAndroid Build Coastguard Worker              * a way to give debugger threads a priority higher than any
929*e82f7db8SAndroid Build Coastguard Worker              * application thread).
930*e82f7db8SAndroid Build Coastguard Worker              */
931*e82f7db8SAndroid Build Coastguard Worker             error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
932*e82f7db8SAndroid Build Coastguard Worker                         (gdata->jvmti, thread, func, arg,
933*e82f7db8SAndroid Build Coastguard Worker                                         JVMTI_THREAD_MAX_PRIORITY);
934*e82f7db8SAndroid Build Coastguard Worker         }
935*e82f7db8SAndroid Build Coastguard Worker 
936*e82f7db8SAndroid Build Coastguard Worker         err: ;
937*e82f7db8SAndroid Build Coastguard Worker 
938*e82f7db8SAndroid Build Coastguard Worker     } END_WITH_LOCAL_REFS(env);
939*e82f7db8SAndroid Build Coastguard Worker 
940*e82f7db8SAndroid Build Coastguard Worker     return error;
941*e82f7db8SAndroid Build Coastguard Worker }
942*e82f7db8SAndroid Build Coastguard Worker 
943*e82f7db8SAndroid Build Coastguard Worker jvmtiError
jvmtiGetCapabilities(jvmtiCapabilities * caps)944*e82f7db8SAndroid Build Coastguard Worker jvmtiGetCapabilities(jvmtiCapabilities *caps)
945*e82f7db8SAndroid Build Coastguard Worker {
946*e82f7db8SAndroid Build Coastguard Worker     if ( gdata->vmDead ) {
947*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_VM_DEAD;
948*e82f7db8SAndroid Build Coastguard Worker     }
949*e82f7db8SAndroid Build Coastguard Worker     if (!gdata->haveCachedJvmtiCapabilities) {
950*e82f7db8SAndroid Build Coastguard Worker         jvmtiError error;
951*e82f7db8SAndroid Build Coastguard Worker 
952*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(gdata->jvmti,GetCapabilities)
953*e82f7db8SAndroid Build Coastguard Worker                         (gdata->jvmti, &(gdata->cachedJvmtiCapabilities));
954*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
955*e82f7db8SAndroid Build Coastguard Worker             return error;
956*e82f7db8SAndroid Build Coastguard Worker         }
957*e82f7db8SAndroid Build Coastguard Worker         gdata->haveCachedJvmtiCapabilities = JNI_TRUE;
958*e82f7db8SAndroid Build Coastguard Worker     }
959*e82f7db8SAndroid Build Coastguard Worker 
960*e82f7db8SAndroid Build Coastguard Worker     *caps = gdata->cachedJvmtiCapabilities;
961*e82f7db8SAndroid Build Coastguard Worker 
962*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_ERROR_NONE;
963*e82f7db8SAndroid Build Coastguard Worker }
964*e82f7db8SAndroid Build Coastguard Worker 
965*e82f7db8SAndroid Build Coastguard Worker static jint
jvmtiVersion(void)966*e82f7db8SAndroid Build Coastguard Worker jvmtiVersion(void)
967*e82f7db8SAndroid Build Coastguard Worker {
968*e82f7db8SAndroid Build Coastguard Worker     if (gdata->cachedJvmtiVersion == 0) {
969*e82f7db8SAndroid Build Coastguard Worker         jvmtiError error;
970*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
971*e82f7db8SAndroid Build Coastguard Worker                         (gdata->jvmti, &(gdata->cachedJvmtiVersion));
972*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
973*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(error, "on getting the JVMTI version number");
974*e82f7db8SAndroid Build Coastguard Worker         }
975*e82f7db8SAndroid Build Coastguard Worker     }
976*e82f7db8SAndroid Build Coastguard Worker     return gdata->cachedJvmtiVersion;
977*e82f7db8SAndroid Build Coastguard Worker }
978*e82f7db8SAndroid Build Coastguard Worker 
979*e82f7db8SAndroid Build Coastguard Worker jint
jvmtiMajorVersion(void)980*e82f7db8SAndroid Build Coastguard Worker jvmtiMajorVersion(void)
981*e82f7db8SAndroid Build Coastguard Worker {
982*e82f7db8SAndroid Build Coastguard Worker     return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
983*e82f7db8SAndroid Build Coastguard Worker                     >> JVMTI_VERSION_SHIFT_MAJOR;
984*e82f7db8SAndroid Build Coastguard Worker }
985*e82f7db8SAndroid Build Coastguard Worker 
986*e82f7db8SAndroid Build Coastguard Worker jint
jvmtiMinorVersion(void)987*e82f7db8SAndroid Build Coastguard Worker jvmtiMinorVersion(void)
988*e82f7db8SAndroid Build Coastguard Worker {
989*e82f7db8SAndroid Build Coastguard Worker     return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
990*e82f7db8SAndroid Build Coastguard Worker                     >> JVMTI_VERSION_SHIFT_MINOR;
991*e82f7db8SAndroid Build Coastguard Worker }
992*e82f7db8SAndroid Build Coastguard Worker 
993*e82f7db8SAndroid Build Coastguard Worker jint
jvmtiMicroVersion(void)994*e82f7db8SAndroid Build Coastguard Worker jvmtiMicroVersion(void)
995*e82f7db8SAndroid Build Coastguard Worker {
996*e82f7db8SAndroid Build Coastguard Worker     return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
997*e82f7db8SAndroid Build Coastguard Worker                     >> JVMTI_VERSION_SHIFT_MICRO;
998*e82f7db8SAndroid Build Coastguard Worker }
999*e82f7db8SAndroid Build Coastguard Worker 
1000*e82f7db8SAndroid Build Coastguard Worker jboolean
canSuspendResumeThreadLists(void)1001*e82f7db8SAndroid Build Coastguard Worker canSuspendResumeThreadLists(void)
1002*e82f7db8SAndroid Build Coastguard Worker {
1003*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1004*e82f7db8SAndroid Build Coastguard Worker     jvmtiCapabilities cap;
1005*e82f7db8SAndroid Build Coastguard Worker 
1006*e82f7db8SAndroid Build Coastguard Worker     error = jvmtiGetCapabilities(&cap);
1007*e82f7db8SAndroid Build Coastguard Worker     return (error == JVMTI_ERROR_NONE && cap.can_suspend);
1008*e82f7db8SAndroid Build Coastguard Worker }
1009*e82f7db8SAndroid Build Coastguard Worker 
1010*e82f7db8SAndroid Build Coastguard Worker jvmtiError
getSourceDebugExtension(jclass clazz,char ** extensionPtr)1011*e82f7db8SAndroid Build Coastguard Worker getSourceDebugExtension(jclass clazz, char **extensionPtr)
1012*e82f7db8SAndroid Build Coastguard Worker {
1013*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_FUNC_PTR(gdata->jvmti,GetSourceDebugExtension)
1014*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, extensionPtr);
1015*e82f7db8SAndroid Build Coastguard Worker }
1016*e82f7db8SAndroid Build Coastguard Worker 
1017*e82f7db8SAndroid Build Coastguard Worker /*
1018*e82f7db8SAndroid Build Coastguard Worker  * Convert the signature "Ljava/lang/Foo;" to a
1019*e82f7db8SAndroid Build Coastguard Worker  * classname "java.lang.Foo" compatible with the pattern.
1020*e82f7db8SAndroid Build Coastguard Worker  * Signature is overwritten in-place.
1021*e82f7db8SAndroid Build Coastguard Worker  */
1022*e82f7db8SAndroid Build Coastguard Worker void
convertSignatureToClassname(char * convert)1023*e82f7db8SAndroid Build Coastguard Worker convertSignatureToClassname(char *convert)
1024*e82f7db8SAndroid Build Coastguard Worker {
1025*e82f7db8SAndroid Build Coastguard Worker     char *p;
1026*e82f7db8SAndroid Build Coastguard Worker 
1027*e82f7db8SAndroid Build Coastguard Worker     p = convert + 1;
1028*e82f7db8SAndroid Build Coastguard Worker     while ((*p != ';') && (*p != '\0')) {
1029*e82f7db8SAndroid Build Coastguard Worker         char c = *p;
1030*e82f7db8SAndroid Build Coastguard Worker         if (c == '/') {
1031*e82f7db8SAndroid Build Coastguard Worker             *(p-1) = '.';
1032*e82f7db8SAndroid Build Coastguard Worker         } else {
1033*e82f7db8SAndroid Build Coastguard Worker             *(p-1) = c;
1034*e82f7db8SAndroid Build Coastguard Worker         }
1035*e82f7db8SAndroid Build Coastguard Worker         p++;
1036*e82f7db8SAndroid Build Coastguard Worker     }
1037*e82f7db8SAndroid Build Coastguard Worker     *(p-1) = '\0';
1038*e82f7db8SAndroid Build Coastguard Worker }
1039*e82f7db8SAndroid Build Coastguard Worker 
1040*e82f7db8SAndroid Build Coastguard Worker static void
handleInterrupt(void)1041*e82f7db8SAndroid Build Coastguard Worker handleInterrupt(void)
1042*e82f7db8SAndroid Build Coastguard Worker {
1043*e82f7db8SAndroid Build Coastguard Worker     /*
1044*e82f7db8SAndroid Build Coastguard Worker      * An interrupt is handled:
1045*e82f7db8SAndroid Build Coastguard Worker      *
1046*e82f7db8SAndroid Build Coastguard Worker      * 1) for running application threads by deferring the interrupt
1047*e82f7db8SAndroid Build Coastguard Worker      * until the current event handler has concluded.
1048*e82f7db8SAndroid Build Coastguard Worker      *
1049*e82f7db8SAndroid Build Coastguard Worker      * 2) for debugger threads by ignoring the interrupt; this is the
1050*e82f7db8SAndroid Build Coastguard Worker      * most robust solution since debugger threads don't use interrupts
1051*e82f7db8SAndroid Build Coastguard Worker      * to signal any condition.
1052*e82f7db8SAndroid Build Coastguard Worker      *
1053*e82f7db8SAndroid Build Coastguard Worker      * 3) for application threads that have not started or already
1054*e82f7db8SAndroid Build Coastguard Worker      * ended by ignoring the interrupt. In the former case, the application
1055*e82f7db8SAndroid Build Coastguard Worker      * is relying on timing to determine whether or not the thread sees
1056*e82f7db8SAndroid Build Coastguard Worker      * the interrupt; in the latter case, the interrupt is meaningless.
1057*e82f7db8SAndroid Build Coastguard Worker      */
1058*e82f7db8SAndroid Build Coastguard Worker     jthread thread = threadControl_currentThread();
1059*e82f7db8SAndroid Build Coastguard Worker     if ((thread != NULL) && (!threadControl_isDebugThread(thread))) {
1060*e82f7db8SAndroid Build Coastguard Worker         threadControl_setPendingInterrupt(thread);
1061*e82f7db8SAndroid Build Coastguard Worker     }
1062*e82f7db8SAndroid Build Coastguard Worker }
1063*e82f7db8SAndroid Build Coastguard Worker 
1064*e82f7db8SAndroid Build Coastguard Worker static jvmtiError
ignore_vm_death(jvmtiError error)1065*e82f7db8SAndroid Build Coastguard Worker ignore_vm_death(jvmtiError error)
1066*e82f7db8SAndroid Build Coastguard Worker {
1067*e82f7db8SAndroid Build Coastguard Worker     if (error == JVMTI_ERROR_WRONG_PHASE) {
1068*e82f7db8SAndroid Build Coastguard Worker         LOG_MISC(("VM_DEAD, in debugMonitor*()?"));
1069*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_ERROR_NONE; /* JVMTI does this, not JVMDI? */
1070*e82f7db8SAndroid Build Coastguard Worker     }
1071*e82f7db8SAndroid Build Coastguard Worker     return error;
1072*e82f7db8SAndroid Build Coastguard Worker }
1073*e82f7db8SAndroid Build Coastguard Worker 
1074*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorEnter(jrawMonitorID monitor)1075*e82f7db8SAndroid Build Coastguard Worker debugMonitorEnter(jrawMonitorID monitor)
1076*e82f7db8SAndroid Build Coastguard Worker {
1077*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1078*e82f7db8SAndroid Build Coastguard Worker     while (JNI_TRUE) {
1079*e82f7db8SAndroid Build Coastguard Worker         error = FUNC_PTR(gdata->jvmti,RawMonitorEnter)
1080*e82f7db8SAndroid Build Coastguard Worker                         (gdata->jvmti, monitor);
1081*e82f7db8SAndroid Build Coastguard Worker         error = ignore_vm_death(error);
1082*e82f7db8SAndroid Build Coastguard Worker         if (error == JVMTI_ERROR_INTERRUPT) {
1083*e82f7db8SAndroid Build Coastguard Worker             handleInterrupt();
1084*e82f7db8SAndroid Build Coastguard Worker         } else {
1085*e82f7db8SAndroid Build Coastguard Worker             break;
1086*e82f7db8SAndroid Build Coastguard Worker         }
1087*e82f7db8SAndroid Build Coastguard Worker     }
1088*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1089*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor enter");
1090*e82f7db8SAndroid Build Coastguard Worker     }
1091*e82f7db8SAndroid Build Coastguard Worker }
1092*e82f7db8SAndroid Build Coastguard Worker 
1093*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorExit(jrawMonitorID monitor)1094*e82f7db8SAndroid Build Coastguard Worker debugMonitorExit(jrawMonitorID monitor)
1095*e82f7db8SAndroid Build Coastguard Worker {
1096*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1097*e82f7db8SAndroid Build Coastguard Worker 
1098*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,RawMonitorExit)
1099*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, monitor);
1100*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1101*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1102*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor exit");
1103*e82f7db8SAndroid Build Coastguard Worker     }
1104*e82f7db8SAndroid Build Coastguard Worker }
1105*e82f7db8SAndroid Build Coastguard Worker 
1106*e82f7db8SAndroid Build Coastguard Worker /* ANDROID-CHANGED: Add suspension ignoring raw-monitor enter. */
debugMonitorEnterNoSuspend(jrawMonitorID monitor)1107*e82f7db8SAndroid Build Coastguard Worker void debugMonitorEnterNoSuspend(jrawMonitorID monitor)
1108*e82f7db8SAndroid Build Coastguard Worker {
1109*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1110*e82f7db8SAndroid Build Coastguard Worker     while (JNI_TRUE) {
1111*e82f7db8SAndroid Build Coastguard Worker         error = FUNC_PTR(&gdata,raw_monitor_enter_no_suspend)(gdata->jvmti, monitor);
1112*e82f7db8SAndroid Build Coastguard Worker         error = ignore_vm_death(error);
1113*e82f7db8SAndroid Build Coastguard Worker         if (error == JVMTI_ERROR_INTERRUPT) {
1114*e82f7db8SAndroid Build Coastguard Worker             handleInterrupt();
1115*e82f7db8SAndroid Build Coastguard Worker         } else {
1116*e82f7db8SAndroid Build Coastguard Worker             break;
1117*e82f7db8SAndroid Build Coastguard Worker         }
1118*e82f7db8SAndroid Build Coastguard Worker     }
1119*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1120*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor enter no suspend");
1121*e82f7db8SAndroid Build Coastguard Worker     }
1122*e82f7db8SAndroid Build Coastguard Worker }
1123*e82f7db8SAndroid Build Coastguard Worker 
1124*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorWait(jrawMonitorID monitor)1125*e82f7db8SAndroid Build Coastguard Worker debugMonitorWait(jrawMonitorID monitor)
1126*e82f7db8SAndroid Build Coastguard Worker {
1127*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1128*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
1129*e82f7db8SAndroid Build Coastguard Worker         (gdata->jvmti, monitor, ((jlong)(-1)));
1130*e82f7db8SAndroid Build Coastguard Worker 
1131*e82f7db8SAndroid Build Coastguard Worker     /*
1132*e82f7db8SAndroid Build Coastguard Worker      * According to the JLS (17.8), here we have
1133*e82f7db8SAndroid Build Coastguard Worker      * either :
1134*e82f7db8SAndroid Build Coastguard Worker      * a- been notified
1135*e82f7db8SAndroid Build Coastguard Worker      * b- gotten a suprious wakeup
1136*e82f7db8SAndroid Build Coastguard Worker      * c- been interrupted
1137*e82f7db8SAndroid Build Coastguard Worker      * If both a and c have happened, the VM must choose
1138*e82f7db8SAndroid Build Coastguard Worker      * which way to return - a or c.  If it chooses c
1139*e82f7db8SAndroid Build Coastguard Worker      * then the notify is gone - either to some other
1140*e82f7db8SAndroid Build Coastguard Worker      * thread that is also waiting, or it is dropped
1141*e82f7db8SAndroid Build Coastguard Worker      * on the floor.
1142*e82f7db8SAndroid Build Coastguard Worker      *
1143*e82f7db8SAndroid Build Coastguard Worker      * a is what we expect.  b won't hurt us any -
1144*e82f7db8SAndroid Build Coastguard Worker      * callers should be programmed to handle
1145*e82f7db8SAndroid Build Coastguard Worker      * spurious wakeups.  In case of c,
1146*e82f7db8SAndroid Build Coastguard Worker      * then the interrupt has been cleared, but
1147*e82f7db8SAndroid Build Coastguard Worker      * we don't want to consume it.  It came from
1148*e82f7db8SAndroid Build Coastguard Worker      * user code and is intended for user code, not us.
1149*e82f7db8SAndroid Build Coastguard Worker      * So, we will remember that the interrupt has
1150*e82f7db8SAndroid Build Coastguard Worker      * occurred and re-activate it when this thread
1151*e82f7db8SAndroid Build Coastguard Worker      * goes back into user code.
1152*e82f7db8SAndroid Build Coastguard Worker      * That being said, what do we do here?  Since
1153*e82f7db8SAndroid Build Coastguard Worker      * we could have been notified too, here we will
1154*e82f7db8SAndroid Build Coastguard Worker      * just pretend that we have been.  It won't hurt
1155*e82f7db8SAndroid Build Coastguard Worker      * anything to return in the same way as if
1156*e82f7db8SAndroid Build Coastguard Worker      * we were notified since callers have to be able to
1157*e82f7db8SAndroid Build Coastguard Worker      * handle spurious wakeups anyway.
1158*e82f7db8SAndroid Build Coastguard Worker      */
1159*e82f7db8SAndroid Build Coastguard Worker     if (error == JVMTI_ERROR_INTERRUPT) {
1160*e82f7db8SAndroid Build Coastguard Worker         handleInterrupt();
1161*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_ERROR_NONE;
1162*e82f7db8SAndroid Build Coastguard Worker     }
1163*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1164*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1165*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor wait");
1166*e82f7db8SAndroid Build Coastguard Worker     }
1167*e82f7db8SAndroid Build Coastguard Worker }
1168*e82f7db8SAndroid Build Coastguard Worker 
1169*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorTimedWait(jrawMonitorID monitor,jlong millis)1170*e82f7db8SAndroid Build Coastguard Worker debugMonitorTimedWait(jrawMonitorID monitor, jlong millis)
1171*e82f7db8SAndroid Build Coastguard Worker {
1172*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1173*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
1174*e82f7db8SAndroid Build Coastguard Worker         (gdata->jvmti, monitor, millis);
1175*e82f7db8SAndroid Build Coastguard Worker     if (error == JVMTI_ERROR_INTERRUPT) {
1176*e82f7db8SAndroid Build Coastguard Worker         /* See comment above */
1177*e82f7db8SAndroid Build Coastguard Worker         handleInterrupt();
1178*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_ERROR_NONE;
1179*e82f7db8SAndroid Build Coastguard Worker     }
1180*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1181*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1182*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor timed wait");
1183*e82f7db8SAndroid Build Coastguard Worker     }
1184*e82f7db8SAndroid Build Coastguard Worker }
1185*e82f7db8SAndroid Build Coastguard Worker 
1186*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorNotify(jrawMonitorID monitor)1187*e82f7db8SAndroid Build Coastguard Worker debugMonitorNotify(jrawMonitorID monitor)
1188*e82f7db8SAndroid Build Coastguard Worker {
1189*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1190*e82f7db8SAndroid Build Coastguard Worker 
1191*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,RawMonitorNotify)
1192*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, monitor);
1193*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1194*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1195*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor notify");
1196*e82f7db8SAndroid Build Coastguard Worker     }
1197*e82f7db8SAndroid Build Coastguard Worker }
1198*e82f7db8SAndroid Build Coastguard Worker 
1199*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorNotifyAll(jrawMonitorID monitor)1200*e82f7db8SAndroid Build Coastguard Worker debugMonitorNotifyAll(jrawMonitorID monitor)
1201*e82f7db8SAndroid Build Coastguard Worker {
1202*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1203*e82f7db8SAndroid Build Coastguard Worker 
1204*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
1205*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, monitor);
1206*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1207*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1208*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on raw monitor notify all");
1209*e82f7db8SAndroid Build Coastguard Worker     }
1210*e82f7db8SAndroid Build Coastguard Worker }
1211*e82f7db8SAndroid Build Coastguard Worker 
1212*e82f7db8SAndroid Build Coastguard Worker jrawMonitorID
debugMonitorCreate(char * name)1213*e82f7db8SAndroid Build Coastguard Worker debugMonitorCreate(char *name)
1214*e82f7db8SAndroid Build Coastguard Worker {
1215*e82f7db8SAndroid Build Coastguard Worker     jrawMonitorID monitor;
1216*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1217*e82f7db8SAndroid Build Coastguard Worker 
1218*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,CreateRawMonitor)
1219*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, name, &monitor);
1220*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1221*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on creation of a raw monitor");
1222*e82f7db8SAndroid Build Coastguard Worker     }
1223*e82f7db8SAndroid Build Coastguard Worker     return monitor;
1224*e82f7db8SAndroid Build Coastguard Worker }
1225*e82f7db8SAndroid Build Coastguard Worker 
1226*e82f7db8SAndroid Build Coastguard Worker void
debugMonitorDestroy(jrawMonitorID monitor)1227*e82f7db8SAndroid Build Coastguard Worker debugMonitorDestroy(jrawMonitorID monitor)
1228*e82f7db8SAndroid Build Coastguard Worker {
1229*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1230*e82f7db8SAndroid Build Coastguard Worker 
1231*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
1232*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, monitor);
1233*e82f7db8SAndroid Build Coastguard Worker     error = ignore_vm_death(error);
1234*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1235*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on destruction of raw monitor");
1236*e82f7db8SAndroid Build Coastguard Worker     }
1237*e82f7db8SAndroid Build Coastguard Worker }
1238*e82f7db8SAndroid Build Coastguard Worker 
1239*e82f7db8SAndroid Build Coastguard Worker /**
1240*e82f7db8SAndroid Build Coastguard Worker  * Return array of all threads (must be inside a WITH_LOCAL_REFS)
1241*e82f7db8SAndroid Build Coastguard Worker  */
1242*e82f7db8SAndroid Build Coastguard Worker jthread *
allThreads(jint * count)1243*e82f7db8SAndroid Build Coastguard Worker allThreads(jint *count)
1244*e82f7db8SAndroid Build Coastguard Worker {
1245*e82f7db8SAndroid Build Coastguard Worker     jthread *threads;
1246*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1247*e82f7db8SAndroid Build Coastguard Worker 
1248*e82f7db8SAndroid Build Coastguard Worker     *count = 0;
1249*e82f7db8SAndroid Build Coastguard Worker     threads = NULL;
1250*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetAllThreads)
1251*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, count, &threads);
1252*e82f7db8SAndroid Build Coastguard Worker     if (error == AGENT_ERROR_OUT_OF_MEMORY) {
1253*e82f7db8SAndroid Build Coastguard Worker         return NULL; /* Let caller deal with no memory? */
1254*e82f7db8SAndroid Build Coastguard Worker     }
1255*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1256*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "getting all threads");
1257*e82f7db8SAndroid Build Coastguard Worker     }
1258*e82f7db8SAndroid Build Coastguard Worker     return threads;
1259*e82f7db8SAndroid Build Coastguard Worker }
1260*e82f7db8SAndroid Build Coastguard Worker 
1261*e82f7db8SAndroid Build Coastguard Worker /**
1262*e82f7db8SAndroid Build Coastguard Worker  * Fill the passed in structure with thread group info.
1263*e82f7db8SAndroid Build Coastguard Worker  * name field is JVMTI allocated.  parent is global ref.
1264*e82f7db8SAndroid Build Coastguard Worker  */
1265*e82f7db8SAndroid Build Coastguard Worker void
threadGroupInfo(jthreadGroup group,jvmtiThreadGroupInfo * info)1266*e82f7db8SAndroid Build Coastguard Worker threadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo *info)
1267*e82f7db8SAndroid Build Coastguard Worker {
1268*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1269*e82f7db8SAndroid Build Coastguard Worker 
1270*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
1271*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, group, info);
1272*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1273*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on getting thread group info");
1274*e82f7db8SAndroid Build Coastguard Worker     }
1275*e82f7db8SAndroid Build Coastguard Worker }
1276*e82f7db8SAndroid Build Coastguard Worker 
1277*e82f7db8SAndroid Build Coastguard Worker /**
1278*e82f7db8SAndroid Build Coastguard Worker  * Return class signature string
1279*e82f7db8SAndroid Build Coastguard Worker  */
1280*e82f7db8SAndroid Build Coastguard Worker jvmtiError
classSignature(jclass clazz,char ** psignature,char ** pgeneric_signature)1281*e82f7db8SAndroid Build Coastguard Worker classSignature(jclass clazz, char **psignature, char **pgeneric_signature)
1282*e82f7db8SAndroid Build Coastguard Worker {
1283*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1284*e82f7db8SAndroid Build Coastguard Worker     char *signature = NULL;
1285*e82f7db8SAndroid Build Coastguard Worker 
1286*e82f7db8SAndroid Build Coastguard Worker     /*
1287*e82f7db8SAndroid Build Coastguard Worker      * pgeneric_signature can be NULL, and GetClassSignature
1288*e82f7db8SAndroid Build Coastguard Worker      * accepts NULL.
1289*e82f7db8SAndroid Build Coastguard Worker      */
1290*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,GetClassSignature)
1291*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, &signature, pgeneric_signature);
1292*e82f7db8SAndroid Build Coastguard Worker 
1293*e82f7db8SAndroid Build Coastguard Worker     if ( psignature != NULL ) {
1294*e82f7db8SAndroid Build Coastguard Worker         *psignature = signature;
1295*e82f7db8SAndroid Build Coastguard Worker     } else if ( signature != NULL )  {
1296*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(signature);
1297*e82f7db8SAndroid Build Coastguard Worker     }
1298*e82f7db8SAndroid Build Coastguard Worker     return error;
1299*e82f7db8SAndroid Build Coastguard Worker }
1300*e82f7db8SAndroid Build Coastguard Worker 
1301*e82f7db8SAndroid Build Coastguard Worker /* Get class name (not signature) */
1302*e82f7db8SAndroid Build Coastguard Worker char *
getClassname(jclass clazz)1303*e82f7db8SAndroid Build Coastguard Worker getClassname(jclass clazz)
1304*e82f7db8SAndroid Build Coastguard Worker {
1305*e82f7db8SAndroid Build Coastguard Worker     char *classname;
1306*e82f7db8SAndroid Build Coastguard Worker 
1307*e82f7db8SAndroid Build Coastguard Worker     classname = NULL;
1308*e82f7db8SAndroid Build Coastguard Worker     if ( clazz != NULL ) {
1309*e82f7db8SAndroid Build Coastguard Worker         if (classSignature(clazz, &classname, NULL) != JVMTI_ERROR_NONE) {
1310*e82f7db8SAndroid Build Coastguard Worker             classname = NULL;
1311*e82f7db8SAndroid Build Coastguard Worker         } else {
1312*e82f7db8SAndroid Build Coastguard Worker             /* Convert in place */
1313*e82f7db8SAndroid Build Coastguard Worker             convertSignatureToClassname(classname);
1314*e82f7db8SAndroid Build Coastguard Worker         }
1315*e82f7db8SAndroid Build Coastguard Worker     }
1316*e82f7db8SAndroid Build Coastguard Worker     return classname; /* Caller must free this memory */
1317*e82f7db8SAndroid Build Coastguard Worker }
1318*e82f7db8SAndroid Build Coastguard Worker 
1319*e82f7db8SAndroid Build Coastguard Worker void
writeGenericSignature(PacketOutputStream * out,char * genericSignature)1320*e82f7db8SAndroid Build Coastguard Worker writeGenericSignature(PacketOutputStream *out, char *genericSignature)
1321*e82f7db8SAndroid Build Coastguard Worker {
1322*e82f7db8SAndroid Build Coastguard Worker     if (genericSignature == NULL) {
1323*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeString(out, "");
1324*e82f7db8SAndroid Build Coastguard Worker     } else {
1325*e82f7db8SAndroid Build Coastguard Worker         (void)outStream_writeString(out, genericSignature);
1326*e82f7db8SAndroid Build Coastguard Worker     }
1327*e82f7db8SAndroid Build Coastguard Worker }
1328*e82f7db8SAndroid Build Coastguard Worker 
1329*e82f7db8SAndroid Build Coastguard Worker jint
classStatus(jclass clazz)1330*e82f7db8SAndroid Build Coastguard Worker classStatus(jclass clazz)
1331*e82f7db8SAndroid Build Coastguard Worker {
1332*e82f7db8SAndroid Build Coastguard Worker     jint status;
1333*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1334*e82f7db8SAndroid Build Coastguard Worker 
1335*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
1336*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, &status);
1337*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1338*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on getting class status");
1339*e82f7db8SAndroid Build Coastguard Worker     }
1340*e82f7db8SAndroid Build Coastguard Worker     return status;
1341*e82f7db8SAndroid Build Coastguard Worker }
1342*e82f7db8SAndroid Build Coastguard Worker 
1343*e82f7db8SAndroid Build Coastguard Worker /* ANDROID-CHANGED: Make isArrayClass public */
1344*e82f7db8SAndroid Build Coastguard Worker jboolean
isArrayClass(jclass clazz)1345*e82f7db8SAndroid Build Coastguard Worker isArrayClass(jclass clazz)
1346*e82f7db8SAndroid Build Coastguard Worker {
1347*e82f7db8SAndroid Build Coastguard Worker     jboolean isArray = JNI_FALSE;
1348*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1349*e82f7db8SAndroid Build Coastguard Worker 
1350*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,IsArrayClass)
1351*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, &isArray);
1352*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1353*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on checking for an array class");
1354*e82f7db8SAndroid Build Coastguard Worker     }
1355*e82f7db8SAndroid Build Coastguard Worker     return isArray;
1356*e82f7db8SAndroid Build Coastguard Worker }
1357*e82f7db8SAndroid Build Coastguard Worker 
1358*e82f7db8SAndroid Build Coastguard Worker static jboolean
isInterface(jclass clazz)1359*e82f7db8SAndroid Build Coastguard Worker isInterface(jclass clazz)
1360*e82f7db8SAndroid Build Coastguard Worker {
1361*e82f7db8SAndroid Build Coastguard Worker     jboolean isInterface = JNI_FALSE;
1362*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1363*e82f7db8SAndroid Build Coastguard Worker 
1364*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
1365*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, &isInterface);
1366*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1367*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on checking for an interface");
1368*e82f7db8SAndroid Build Coastguard Worker     }
1369*e82f7db8SAndroid Build Coastguard Worker     return isInterface;
1370*e82f7db8SAndroid Build Coastguard Worker }
1371*e82f7db8SAndroid Build Coastguard Worker 
1372*e82f7db8SAndroid Build Coastguard Worker jvmtiError
isFieldSynthetic(jclass clazz,jfieldID field,jboolean * psynthetic)1373*e82f7db8SAndroid Build Coastguard Worker isFieldSynthetic(jclass clazz, jfieldID field, jboolean *psynthetic)
1374*e82f7db8SAndroid Build Coastguard Worker {
1375*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1376*e82f7db8SAndroid Build Coastguard Worker 
1377*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,IsFieldSynthetic)
1378*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, field, psynthetic);
1379*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
1380*e82f7db8SAndroid Build Coastguard Worker         /* If the query is not supported, we assume it is not synthetic. */
1381*e82f7db8SAndroid Build Coastguard Worker         *psynthetic = JNI_FALSE;
1382*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_ERROR_NONE;
1383*e82f7db8SAndroid Build Coastguard Worker     }
1384*e82f7db8SAndroid Build Coastguard Worker     return error;
1385*e82f7db8SAndroid Build Coastguard Worker }
1386*e82f7db8SAndroid Build Coastguard Worker 
1387*e82f7db8SAndroid Build Coastguard Worker jvmtiError
isMethodSynthetic(jmethodID method,jboolean * psynthetic)1388*e82f7db8SAndroid Build Coastguard Worker isMethodSynthetic(jmethodID method, jboolean *psynthetic)
1389*e82f7db8SAndroid Build Coastguard Worker {
1390*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1391*e82f7db8SAndroid Build Coastguard Worker 
1392*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodSynthetic)
1393*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, method, psynthetic);
1394*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
1395*e82f7db8SAndroid Build Coastguard Worker         /* If the query is not supported, we assume it is not synthetic. */
1396*e82f7db8SAndroid Build Coastguard Worker         *psynthetic = JNI_FALSE;
1397*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_ERROR_NONE;
1398*e82f7db8SAndroid Build Coastguard Worker     }
1399*e82f7db8SAndroid Build Coastguard Worker     return error;
1400*e82f7db8SAndroid Build Coastguard Worker }
1401*e82f7db8SAndroid Build Coastguard Worker 
1402*e82f7db8SAndroid Build Coastguard Worker jboolean
isMethodNative(jmethodID method)1403*e82f7db8SAndroid Build Coastguard Worker isMethodNative(jmethodID method)
1404*e82f7db8SAndroid Build Coastguard Worker {
1405*e82f7db8SAndroid Build Coastguard Worker     jboolean isNative = JNI_FALSE;
1406*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1407*e82f7db8SAndroid Build Coastguard Worker 
1408*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
1409*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, method, &isNative);
1410*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1411*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "on checking for a native interface");
1412*e82f7db8SAndroid Build Coastguard Worker     }
1413*e82f7db8SAndroid Build Coastguard Worker     return isNative;
1414*e82f7db8SAndroid Build Coastguard Worker }
1415*e82f7db8SAndroid Build Coastguard Worker 
1416*e82f7db8SAndroid Build Coastguard Worker jboolean
isSameObject(JNIEnv * env,jobject o1,jobject o2)1417*e82f7db8SAndroid Build Coastguard Worker isSameObject(JNIEnv *env, jobject o1, jobject o2)
1418*e82f7db8SAndroid Build Coastguard Worker {
1419*e82f7db8SAndroid Build Coastguard Worker     if ( o1==o2 ) {
1420*e82f7db8SAndroid Build Coastguard Worker         return JNI_TRUE;
1421*e82f7db8SAndroid Build Coastguard Worker     }
1422*e82f7db8SAndroid Build Coastguard Worker     return FUNC_PTR(env,IsSameObject)(env, o1, o2);
1423*e82f7db8SAndroid Build Coastguard Worker }
1424*e82f7db8SAndroid Build Coastguard Worker 
1425*e82f7db8SAndroid Build Coastguard Worker jint
objectHashCode(jobject object)1426*e82f7db8SAndroid Build Coastguard Worker objectHashCode(jobject object)
1427*e82f7db8SAndroid Build Coastguard Worker {
1428*e82f7db8SAndroid Build Coastguard Worker     jint hashCode = 0;
1429*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1430*e82f7db8SAndroid Build Coastguard Worker 
1431*e82f7db8SAndroid Build Coastguard Worker     if ( object!=NULL ) {
1432*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectHashCode)
1433*e82f7db8SAndroid Build Coastguard Worker                     (gdata->jvmti, object, &hashCode);
1434*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
1435*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(error, "on getting an object hash code");
1436*e82f7db8SAndroid Build Coastguard Worker         }
1437*e82f7db8SAndroid Build Coastguard Worker     }
1438*e82f7db8SAndroid Build Coastguard Worker     return hashCode;
1439*e82f7db8SAndroid Build Coastguard Worker }
1440*e82f7db8SAndroid Build Coastguard Worker 
1441*e82f7db8SAndroid Build Coastguard Worker /* Get all implemented interfaces (must be inside a WITH_LOCAL_REFS) */
1442*e82f7db8SAndroid Build Coastguard Worker jvmtiError
allInterfaces(jclass clazz,jclass ** ppinterfaces,jint * pcount)1443*e82f7db8SAndroid Build Coastguard Worker allInterfaces(jclass clazz, jclass **ppinterfaces, jint *pcount)
1444*e82f7db8SAndroid Build Coastguard Worker {
1445*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1446*e82f7db8SAndroid Build Coastguard Worker 
1447*e82f7db8SAndroid Build Coastguard Worker     *pcount = 0;
1448*e82f7db8SAndroid Build Coastguard Worker     *ppinterfaces = NULL;
1449*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
1450*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, clazz, pcount, ppinterfaces);
1451*e82f7db8SAndroid Build Coastguard Worker     return error;
1452*e82f7db8SAndroid Build Coastguard Worker }
1453*e82f7db8SAndroid Build Coastguard Worker 
1454*e82f7db8SAndroid Build Coastguard Worker /* Get all loaded classes (must be inside a WITH_LOCAL_REFS) */
1455*e82f7db8SAndroid Build Coastguard Worker jvmtiError
allLoadedClasses(jclass ** ppclasses,jint * pcount)1456*e82f7db8SAndroid Build Coastguard Worker allLoadedClasses(jclass **ppclasses, jint *pcount)
1457*e82f7db8SAndroid Build Coastguard Worker {
1458*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1459*e82f7db8SAndroid Build Coastguard Worker 
1460*e82f7db8SAndroid Build Coastguard Worker     *pcount = 0;
1461*e82f7db8SAndroid Build Coastguard Worker     *ppclasses = NULL;
1462*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
1463*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, pcount, ppclasses);
1464*e82f7db8SAndroid Build Coastguard Worker     return error;
1465*e82f7db8SAndroid Build Coastguard Worker }
1466*e82f7db8SAndroid Build Coastguard Worker 
1467*e82f7db8SAndroid Build Coastguard Worker /* Get all loaded classes for a loader (must be inside a WITH_LOCAL_REFS) */
1468*e82f7db8SAndroid Build Coastguard Worker jvmtiError
allClassLoaderClasses(jobject loader,jclass ** ppclasses,jint * pcount)1469*e82f7db8SAndroid Build Coastguard Worker allClassLoaderClasses(jobject loader, jclass **ppclasses, jint *pcount)
1470*e82f7db8SAndroid Build Coastguard Worker {
1471*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1472*e82f7db8SAndroid Build Coastguard Worker 
1473*e82f7db8SAndroid Build Coastguard Worker     *pcount = 0;
1474*e82f7db8SAndroid Build Coastguard Worker     *ppclasses = NULL;
1475*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoaderClasses)
1476*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, loader, pcount, ppclasses);
1477*e82f7db8SAndroid Build Coastguard Worker     return error;
1478*e82f7db8SAndroid Build Coastguard Worker }
1479*e82f7db8SAndroid Build Coastguard Worker 
1480*e82f7db8SAndroid Build Coastguard Worker static jboolean
is_a_nested_class(char * outer_sig,int outer_sig_len,char * sig,int sep)1481*e82f7db8SAndroid Build Coastguard Worker is_a_nested_class(char *outer_sig, int outer_sig_len, char *sig, int sep)
1482*e82f7db8SAndroid Build Coastguard Worker {
1483*e82f7db8SAndroid Build Coastguard Worker     char *inner;
1484*e82f7db8SAndroid Build Coastguard Worker 
1485*e82f7db8SAndroid Build Coastguard Worker     /* Assumed outer class signature is  "LOUTERCLASSNAME;"
1486*e82f7db8SAndroid Build Coastguard Worker      *         inner class signature is  "LOUTERCLASSNAME$INNERNAME;"
1487*e82f7db8SAndroid Build Coastguard Worker      *
1488*e82f7db8SAndroid Build Coastguard Worker      * INNERNAME can take the form:
1489*e82f7db8SAndroid Build Coastguard Worker      *    [0-9][1-9]*        anonymous class somewhere in the file
1490*e82f7db8SAndroid Build Coastguard Worker      *    [0-9][1-9]*NAME    local class somewhere in the OUTER class
1491*e82f7db8SAndroid Build Coastguard Worker      *    NAME               nested class in OUTER
1492*e82f7db8SAndroid Build Coastguard Worker      *
1493*e82f7db8SAndroid Build Coastguard Worker      * If NAME itself contains a $ (sep) then classname is further nested
1494*e82f7db8SAndroid Build Coastguard Worker      *    inside another class.
1495*e82f7db8SAndroid Build Coastguard Worker      *
1496*e82f7db8SAndroid Build Coastguard Worker      */
1497*e82f7db8SAndroid Build Coastguard Worker 
1498*e82f7db8SAndroid Build Coastguard Worker     /* Check prefix first */
1499*e82f7db8SAndroid Build Coastguard Worker     if ( strncmp(sig, outer_sig, outer_sig_len-1) != 0 ) {
1500*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;
1501*e82f7db8SAndroid Build Coastguard Worker     }
1502*e82f7db8SAndroid Build Coastguard Worker 
1503*e82f7db8SAndroid Build Coastguard Worker     /* Prefix must be followed by a $ (sep) */
1504*e82f7db8SAndroid Build Coastguard Worker     if ( sig[outer_sig_len-1] != sep ) {
1505*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;  /* No sep follows the match, must not be nested. */
1506*e82f7db8SAndroid Build Coastguard Worker     }
1507*e82f7db8SAndroid Build Coastguard Worker 
1508*e82f7db8SAndroid Build Coastguard Worker     /* Walk past any digits, if we reach the end, must be pure anonymous */
1509*e82f7db8SAndroid Build Coastguard Worker     inner = sig + outer_sig_len;
1510*e82f7db8SAndroid Build Coastguard Worker #if 1 /* We want to return local classes */
1511*e82f7db8SAndroid Build Coastguard Worker     while ( *inner && isdigit(*inner) ) {
1512*e82f7db8SAndroid Build Coastguard Worker         inner++;
1513*e82f7db8SAndroid Build Coastguard Worker     }
1514*e82f7db8SAndroid Build Coastguard Worker     /* But anonymous class names can't be trusted. */
1515*e82f7db8SAndroid Build Coastguard Worker     if ( *inner == ';' ) {
1516*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;  /* A pure anonymous class */
1517*e82f7db8SAndroid Build Coastguard Worker     }
1518*e82f7db8SAndroid Build Coastguard Worker #else
1519*e82f7db8SAndroid Build Coastguard Worker     if ( *inner && isdigit(*inner) ) {
1520*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;  /* A pure anonymous or local class */
1521*e82f7db8SAndroid Build Coastguard Worker     }
1522*e82f7db8SAndroid Build Coastguard Worker #endif
1523*e82f7db8SAndroid Build Coastguard Worker 
1524*e82f7db8SAndroid Build Coastguard Worker     /* Nested deeper? */
1525*e82f7db8SAndroid Build Coastguard Worker     if ( strchr(inner, sep) != NULL ) {
1526*e82f7db8SAndroid Build Coastguard Worker         return JNI_FALSE;  /* Nested deeper than we want? */
1527*e82f7db8SAndroid Build Coastguard Worker     }
1528*e82f7db8SAndroid Build Coastguard Worker     return JNI_TRUE;
1529*e82f7db8SAndroid Build Coastguard Worker }
1530*e82f7db8SAndroid Build Coastguard Worker 
1531*e82f7db8SAndroid Build Coastguard Worker /* Get all nested classes for a class (must be inside a WITH_LOCAL_REFS) */
1532*e82f7db8SAndroid Build Coastguard Worker jvmtiError
allNestedClasses(jclass parent_clazz,jclass ** ppnested,jint * pcount)1533*e82f7db8SAndroid Build Coastguard Worker allNestedClasses(jclass parent_clazz, jclass **ppnested, jint *pcount)
1534*e82f7db8SAndroid Build Coastguard Worker {
1535*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1536*e82f7db8SAndroid Build Coastguard Worker     jobject parent_loader;
1537*e82f7db8SAndroid Build Coastguard Worker     jclass *classes;
1538*e82f7db8SAndroid Build Coastguard Worker     char *signature;
1539*e82f7db8SAndroid Build Coastguard Worker     size_t len;
1540*e82f7db8SAndroid Build Coastguard Worker     jint count;
1541*e82f7db8SAndroid Build Coastguard Worker     jint ncount;
1542*e82f7db8SAndroid Build Coastguard Worker     int i;
1543*e82f7db8SAndroid Build Coastguard Worker 
1544*e82f7db8SAndroid Build Coastguard Worker     *ppnested   = NULL;
1545*e82f7db8SAndroid Build Coastguard Worker     *pcount     = 0;
1546*e82f7db8SAndroid Build Coastguard Worker 
1547*e82f7db8SAndroid Build Coastguard Worker     parent_loader = NULL;
1548*e82f7db8SAndroid Build Coastguard Worker     classes       = NULL;
1549*e82f7db8SAndroid Build Coastguard Worker     signature     = NULL;
1550*e82f7db8SAndroid Build Coastguard Worker     count         = 0;
1551*e82f7db8SAndroid Build Coastguard Worker     ncount        = 0;
1552*e82f7db8SAndroid Build Coastguard Worker 
1553*e82f7db8SAndroid Build Coastguard Worker     error = classLoader(parent_clazz, &parent_loader);
1554*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1555*e82f7db8SAndroid Build Coastguard Worker         return error;
1556*e82f7db8SAndroid Build Coastguard Worker     }
1557*e82f7db8SAndroid Build Coastguard Worker     error = classSignature(parent_clazz, &signature, NULL);
1558*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1559*e82f7db8SAndroid Build Coastguard Worker         return error;
1560*e82f7db8SAndroid Build Coastguard Worker     }
1561*e82f7db8SAndroid Build Coastguard Worker     len = strlen(signature);
1562*e82f7db8SAndroid Build Coastguard Worker 
1563*e82f7db8SAndroid Build Coastguard Worker     error = allClassLoaderClasses(parent_loader, &classes, &count);
1564*e82f7db8SAndroid Build Coastguard Worker     if ( error != JVMTI_ERROR_NONE ) {
1565*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(signature);
1566*e82f7db8SAndroid Build Coastguard Worker         return error;
1567*e82f7db8SAndroid Build Coastguard Worker     }
1568*e82f7db8SAndroid Build Coastguard Worker 
1569*e82f7db8SAndroid Build Coastguard Worker     for (i=0; i<count; i++) {
1570*e82f7db8SAndroid Build Coastguard Worker         jclass clazz;
1571*e82f7db8SAndroid Build Coastguard Worker         char *candidate_signature;
1572*e82f7db8SAndroid Build Coastguard Worker 
1573*e82f7db8SAndroid Build Coastguard Worker         clazz = classes[i];
1574*e82f7db8SAndroid Build Coastguard Worker         candidate_signature = NULL;
1575*e82f7db8SAndroid Build Coastguard Worker         error = classSignature(clazz, &candidate_signature, NULL);
1576*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
1577*e82f7db8SAndroid Build Coastguard Worker             break;
1578*e82f7db8SAndroid Build Coastguard Worker         }
1579*e82f7db8SAndroid Build Coastguard Worker 
1580*e82f7db8SAndroid Build Coastguard Worker         if ( is_a_nested_class(signature, (int)len, candidate_signature, '$') ||
1581*e82f7db8SAndroid Build Coastguard Worker              is_a_nested_class(signature, (int)len, candidate_signature, '#') ) {
1582*e82f7db8SAndroid Build Coastguard Worker             /* Float nested classes to top */
1583*e82f7db8SAndroid Build Coastguard Worker             classes[i] = classes[ncount];
1584*e82f7db8SAndroid Build Coastguard Worker             classes[ncount++] = clazz;
1585*e82f7db8SAndroid Build Coastguard Worker         }
1586*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(candidate_signature);
1587*e82f7db8SAndroid Build Coastguard Worker     }
1588*e82f7db8SAndroid Build Coastguard Worker 
1589*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(signature);
1590*e82f7db8SAndroid Build Coastguard Worker 
1591*e82f7db8SAndroid Build Coastguard Worker     if ( count != 0 &&  ncount == 0 ) {
1592*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(classes);
1593*e82f7db8SAndroid Build Coastguard Worker         classes = NULL;
1594*e82f7db8SAndroid Build Coastguard Worker     }
1595*e82f7db8SAndroid Build Coastguard Worker 
1596*e82f7db8SAndroid Build Coastguard Worker     *ppnested = classes;
1597*e82f7db8SAndroid Build Coastguard Worker     *pcount = ncount;
1598*e82f7db8SAndroid Build Coastguard Worker     return error;
1599*e82f7db8SAndroid Build Coastguard Worker }
1600*e82f7db8SAndroid Build Coastguard Worker 
1601*e82f7db8SAndroid Build Coastguard Worker void
createLocalRefSpace(JNIEnv * env,jint capacity)1602*e82f7db8SAndroid Build Coastguard Worker createLocalRefSpace(JNIEnv *env, jint capacity)
1603*e82f7db8SAndroid Build Coastguard Worker {
1604*e82f7db8SAndroid Build Coastguard Worker     /*
1605*e82f7db8SAndroid Build Coastguard Worker      * Save current exception since it might get overwritten by
1606*e82f7db8SAndroid Build Coastguard Worker      * the calls below. Note we must depend on space in the existing
1607*e82f7db8SAndroid Build Coastguard Worker      * frame because asking for a new frame may generate an exception.
1608*e82f7db8SAndroid Build Coastguard Worker      */
1609*e82f7db8SAndroid Build Coastguard Worker     jobject throwable = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
1610*e82f7db8SAndroid Build Coastguard Worker 
1611*e82f7db8SAndroid Build Coastguard Worker     /*
1612*e82f7db8SAndroid Build Coastguard Worker      * Use the current frame if necessary; otherwise create a new one
1613*e82f7db8SAndroid Build Coastguard Worker      */
1614*e82f7db8SAndroid Build Coastguard Worker     if (JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity) < 0) {
1615*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"PushLocalFrame: Unable to push JNI frame");
1616*e82f7db8SAndroid Build Coastguard Worker     }
1617*e82f7db8SAndroid Build Coastguard Worker 
1618*e82f7db8SAndroid Build Coastguard Worker     /*
1619*e82f7db8SAndroid Build Coastguard Worker      * TO DO: This could be more efficient if it used EnsureLocalCapacity,
1620*e82f7db8SAndroid Build Coastguard Worker      * but that would not work if two functions on the call stack
1621*e82f7db8SAndroid Build Coastguard Worker      * use this function. We would need to either track reserved
1622*e82f7db8SAndroid Build Coastguard Worker      * references on a per-thread basis or come up with a convention
1623*e82f7db8SAndroid Build Coastguard Worker      * that would prevent two functions from depending on this function
1624*e82f7db8SAndroid Build Coastguard Worker      * at the same time.
1625*e82f7db8SAndroid Build Coastguard Worker      */
1626*e82f7db8SAndroid Build Coastguard Worker 
1627*e82f7db8SAndroid Build Coastguard Worker     /*
1628*e82f7db8SAndroid Build Coastguard Worker      * Restore exception state from before call
1629*e82f7db8SAndroid Build Coastguard Worker      */
1630*e82f7db8SAndroid Build Coastguard Worker     if (throwable != NULL) {
1631*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,Throw)(env, throwable);
1632*e82f7db8SAndroid Build Coastguard Worker     } else {
1633*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,ExceptionClear)(env);
1634*e82f7db8SAndroid Build Coastguard Worker     }
1635*e82f7db8SAndroid Build Coastguard Worker }
1636*e82f7db8SAndroid Build Coastguard Worker 
1637*e82f7db8SAndroid Build Coastguard Worker jboolean
isClass(jobject object)1638*e82f7db8SAndroid Build Coastguard Worker isClass(jobject object)
1639*e82f7db8SAndroid Build Coastguard Worker {
1640*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1641*e82f7db8SAndroid Build Coastguard Worker     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass);
1642*e82f7db8SAndroid Build Coastguard Worker }
1643*e82f7db8SAndroid Build Coastguard Worker 
1644*e82f7db8SAndroid Build Coastguard Worker jboolean
isThread(jobject object)1645*e82f7db8SAndroid Build Coastguard Worker isThread(jobject object)
1646*e82f7db8SAndroid Build Coastguard Worker {
1647*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1648*e82f7db8SAndroid Build Coastguard Worker     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass);
1649*e82f7db8SAndroid Build Coastguard Worker }
1650*e82f7db8SAndroid Build Coastguard Worker 
1651*e82f7db8SAndroid Build Coastguard Worker jboolean
isThreadGroup(jobject object)1652*e82f7db8SAndroid Build Coastguard Worker isThreadGroup(jobject object)
1653*e82f7db8SAndroid Build Coastguard Worker {
1654*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1655*e82f7db8SAndroid Build Coastguard Worker     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass);
1656*e82f7db8SAndroid Build Coastguard Worker }
1657*e82f7db8SAndroid Build Coastguard Worker 
1658*e82f7db8SAndroid Build Coastguard Worker jboolean
isString(jobject object)1659*e82f7db8SAndroid Build Coastguard Worker isString(jobject object)
1660*e82f7db8SAndroid Build Coastguard Worker {
1661*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1662*e82f7db8SAndroid Build Coastguard Worker     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass);
1663*e82f7db8SAndroid Build Coastguard Worker }
1664*e82f7db8SAndroid Build Coastguard Worker 
1665*e82f7db8SAndroid Build Coastguard Worker jboolean
isClassLoader(jobject object)1666*e82f7db8SAndroid Build Coastguard Worker isClassLoader(jobject object)
1667*e82f7db8SAndroid Build Coastguard Worker {
1668*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1669*e82f7db8SAndroid Build Coastguard Worker     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass);
1670*e82f7db8SAndroid Build Coastguard Worker }
1671*e82f7db8SAndroid Build Coastguard Worker 
1672*e82f7db8SAndroid Build Coastguard Worker jboolean
isArray(jobject object)1673*e82f7db8SAndroid Build Coastguard Worker isArray(jobject object)
1674*e82f7db8SAndroid Build Coastguard Worker {
1675*e82f7db8SAndroid Build Coastguard Worker     JNIEnv *env = getEnv();
1676*e82f7db8SAndroid Build Coastguard Worker     jboolean is;
1677*e82f7db8SAndroid Build Coastguard Worker 
1678*e82f7db8SAndroid Build Coastguard Worker     WITH_LOCAL_REFS(env, 1) {
1679*e82f7db8SAndroid Build Coastguard Worker         jclass clazz;
1680*e82f7db8SAndroid Build Coastguard Worker         clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
1681*e82f7db8SAndroid Build Coastguard Worker         is = isArrayClass(clazz);
1682*e82f7db8SAndroid Build Coastguard Worker     } END_WITH_LOCAL_REFS(env);
1683*e82f7db8SAndroid Build Coastguard Worker 
1684*e82f7db8SAndroid Build Coastguard Worker     return is;
1685*e82f7db8SAndroid Build Coastguard Worker }
1686*e82f7db8SAndroid Build Coastguard Worker 
1687*e82f7db8SAndroid Build Coastguard Worker /**
1688*e82f7db8SAndroid Build Coastguard Worker  * Return property value as jstring
1689*e82f7db8SAndroid Build Coastguard Worker  */
1690*e82f7db8SAndroid Build Coastguard Worker static jstring
getPropertyValue(JNIEnv * env,char * propertyName)1691*e82f7db8SAndroid Build Coastguard Worker getPropertyValue(JNIEnv *env, char *propertyName)
1692*e82f7db8SAndroid Build Coastguard Worker {
1693*e82f7db8SAndroid Build Coastguard Worker     jstring valueString;
1694*e82f7db8SAndroid Build Coastguard Worker     jstring nameString;
1695*e82f7db8SAndroid Build Coastguard Worker 
1696*e82f7db8SAndroid Build Coastguard Worker     valueString = NULL;
1697*e82f7db8SAndroid Build Coastguard Worker 
1698*e82f7db8SAndroid Build Coastguard Worker     /* Create new String object to hold the property name */
1699*e82f7db8SAndroid Build Coastguard Worker     nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
1700*e82f7db8SAndroid Build Coastguard Worker     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1701*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,ExceptionClear)(env);
1702*e82f7db8SAndroid Build Coastguard Worker         /* NULL will be returned below */
1703*e82f7db8SAndroid Build Coastguard Worker     } else {
1704*e82f7db8SAndroid Build Coastguard Worker         /* Call valueString = System.getProperty(nameString) */
1705*e82f7db8SAndroid Build Coastguard Worker         valueString = JNI_FUNC_PTR(env,CallStaticObjectMethod)
1706*e82f7db8SAndroid Build Coastguard Worker             (env, gdata->systemClass, gdata->systemGetProperty, nameString);
1707*e82f7db8SAndroid Build Coastguard Worker         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1708*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ExceptionClear)(env);
1709*e82f7db8SAndroid Build Coastguard Worker             valueString = NULL;
1710*e82f7db8SAndroid Build Coastguard Worker         }
1711*e82f7db8SAndroid Build Coastguard Worker     }
1712*e82f7db8SAndroid Build Coastguard Worker     return valueString;
1713*e82f7db8SAndroid Build Coastguard Worker }
1714*e82f7db8SAndroid Build Coastguard Worker 
1715*e82f7db8SAndroid Build Coastguard Worker /**
1716*e82f7db8SAndroid Build Coastguard Worker  * Set an agent property
1717*e82f7db8SAndroid Build Coastguard Worker  */
1718*e82f7db8SAndroid Build Coastguard Worker void
setAgentPropertyValue(JNIEnv * env,char * propertyName,char * propertyValue)1719*e82f7db8SAndroid Build Coastguard Worker setAgentPropertyValue(JNIEnv *env, char *propertyName, char* propertyValue)
1720*e82f7db8SAndroid Build Coastguard Worker {
1721*e82f7db8SAndroid Build Coastguard Worker     jstring nameString;
1722*e82f7db8SAndroid Build Coastguard Worker     jstring valueString;
1723*e82f7db8SAndroid Build Coastguard Worker 
1724*e82f7db8SAndroid Build Coastguard Worker     if (gdata->agent_properties == NULL) {
1725*e82f7db8SAndroid Build Coastguard Worker         /* VMSupport doesn't exist; so ignore */
1726*e82f7db8SAndroid Build Coastguard Worker         return;
1727*e82f7db8SAndroid Build Coastguard Worker     }
1728*e82f7db8SAndroid Build Coastguard Worker 
1729*e82f7db8SAndroid Build Coastguard Worker     /* Create jstrings for property name and value */
1730*e82f7db8SAndroid Build Coastguard Worker     nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
1731*e82f7db8SAndroid Build Coastguard Worker     if (nameString != NULL) {
1732*e82f7db8SAndroid Build Coastguard Worker         valueString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyValue);
1733*e82f7db8SAndroid Build Coastguard Worker         if (valueString != NULL) {
1734*e82f7db8SAndroid Build Coastguard Worker             /* invoke Properties.setProperty */
1735*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,CallObjectMethod)
1736*e82f7db8SAndroid Build Coastguard Worker                 (env, gdata->agent_properties,
1737*e82f7db8SAndroid Build Coastguard Worker                  gdata->setProperty,
1738*e82f7db8SAndroid Build Coastguard Worker                  nameString, valueString);
1739*e82f7db8SAndroid Build Coastguard Worker         }
1740*e82f7db8SAndroid Build Coastguard Worker     }
1741*e82f7db8SAndroid Build Coastguard Worker     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1742*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,ExceptionClear)(env);
1743*e82f7db8SAndroid Build Coastguard Worker     }
1744*e82f7db8SAndroid Build Coastguard Worker }
1745*e82f7db8SAndroid Build Coastguard Worker 
1746*e82f7db8SAndroid Build Coastguard Worker /**
1747*e82f7db8SAndroid Build Coastguard Worker  * Return property value as JDWP allocated string in UTF8 encoding
1748*e82f7db8SAndroid Build Coastguard Worker  */
1749*e82f7db8SAndroid Build Coastguard Worker static char *
getPropertyUTF8(JNIEnv * env,char * propertyName)1750*e82f7db8SAndroid Build Coastguard Worker getPropertyUTF8(JNIEnv *env, char *propertyName)
1751*e82f7db8SAndroid Build Coastguard Worker {
1752*e82f7db8SAndroid Build Coastguard Worker     jvmtiError  error;
1753*e82f7db8SAndroid Build Coastguard Worker     char       *value;
1754*e82f7db8SAndroid Build Coastguard Worker 
1755*e82f7db8SAndroid Build Coastguard Worker     value = NULL;
1756*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
1757*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, (const char *)propertyName, &value);
1758*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE) {
1759*e82f7db8SAndroid Build Coastguard Worker         jstring valueString;
1760*e82f7db8SAndroid Build Coastguard Worker 
1761*e82f7db8SAndroid Build Coastguard Worker         value = NULL;
1762*e82f7db8SAndroid Build Coastguard Worker         valueString = getPropertyValue(env, propertyName);
1763*e82f7db8SAndroid Build Coastguard Worker 
1764*e82f7db8SAndroid Build Coastguard Worker         if (valueString != NULL) {
1765*e82f7db8SAndroid Build Coastguard Worker             const char *utf;
1766*e82f7db8SAndroid Build Coastguard Worker 
1767*e82f7db8SAndroid Build Coastguard Worker             /* Get the UTF8 encoding for this property value string */
1768*e82f7db8SAndroid Build Coastguard Worker             utf = JNI_FUNC_PTR(env,GetStringUTFChars)(env, valueString, NULL);
1769*e82f7db8SAndroid Build Coastguard Worker             /* Make a copy for returning, release the JNI copy */
1770*e82f7db8SAndroid Build Coastguard Worker             value = jvmtiAllocate((int)strlen(utf) + 1);
1771*e82f7db8SAndroid Build Coastguard Worker             if (value != NULL) {
1772*e82f7db8SAndroid Build Coastguard Worker                 (void)strcpy(value, utf);
1773*e82f7db8SAndroid Build Coastguard Worker             }
1774*e82f7db8SAndroid Build Coastguard Worker             JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, valueString, utf);
1775*e82f7db8SAndroid Build Coastguard Worker         }
1776*e82f7db8SAndroid Build Coastguard Worker     }
1777*e82f7db8SAndroid Build Coastguard Worker     if ( value == NULL ) {
1778*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("JDWP Can't get property value for %s", propertyName));
1779*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
1780*e82f7db8SAndroid Build Coastguard Worker     }
1781*e82f7db8SAndroid Build Coastguard Worker     return value;
1782*e82f7db8SAndroid Build Coastguard Worker }
1783*e82f7db8SAndroid Build Coastguard Worker 
1784*e82f7db8SAndroid Build Coastguard Worker jboolean
isMethodObsolete(jmethodID method)1785*e82f7db8SAndroid Build Coastguard Worker isMethodObsolete(jmethodID method)
1786*e82f7db8SAndroid Build Coastguard Worker {
1787*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1788*e82f7db8SAndroid Build Coastguard Worker     jboolean obsolete = JNI_TRUE;
1789*e82f7db8SAndroid Build Coastguard Worker 
1790*e82f7db8SAndroid Build Coastguard Worker     if ( method != NULL ) {
1791*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodObsolete)
1792*e82f7db8SAndroid Build Coastguard Worker                     (gdata->jvmti, method, &obsolete);
1793*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
1794*e82f7db8SAndroid Build Coastguard Worker             obsolete = JNI_TRUE;
1795*e82f7db8SAndroid Build Coastguard Worker         }
1796*e82f7db8SAndroid Build Coastguard Worker     }
1797*e82f7db8SAndroid Build Coastguard Worker     return obsolete;
1798*e82f7db8SAndroid Build Coastguard Worker }
1799*e82f7db8SAndroid Build Coastguard Worker 
1800*e82f7db8SAndroid Build Coastguard Worker /* Get the jvmti environment to be used with tags
1801*e82f7db8SAndroid Build Coastguard Worker  * ANDROID_CHANGED: Expose this function publicly for use with class-track and other places.
1802*e82f7db8SAndroid Build Coastguard Worker  */
1803*e82f7db8SAndroid Build Coastguard Worker jvmtiEnv *
getSpecialJvmti(void)1804*e82f7db8SAndroid Build Coastguard Worker getSpecialJvmti(void)
1805*e82f7db8SAndroid Build Coastguard Worker {
1806*e82f7db8SAndroid Build Coastguard Worker     jvmtiEnv  *jvmti;
1807*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1808*e82f7db8SAndroid Build Coastguard Worker     int        rc;
1809*e82f7db8SAndroid Build Coastguard Worker 
1810*e82f7db8SAndroid Build Coastguard Worker     /* Get one time use JVMTI Env */
1811*e82f7db8SAndroid Build Coastguard Worker     jvmtiCapabilities caps;
1812*e82f7db8SAndroid Build Coastguard Worker 
1813*e82f7db8SAndroid Build Coastguard Worker     // ANDROID-CHANGED: Always get a new jvmti-env using the same version as the main env. This
1814*e82f7db8SAndroid Build Coastguard Worker     // means that everything will still work even when using a best-effort ArtTiEnv.
1815*e82f7db8SAndroid Build Coastguard Worker     rc = JVM_FUNC_PTR(gdata->jvm,GetEnv)
1816*e82f7db8SAndroid Build Coastguard Worker                      (gdata->jvm, (void **)&jvmti, jvmtiVersion());
1817*e82f7db8SAndroid Build Coastguard Worker     if (rc != JNI_OK) {
1818*e82f7db8SAndroid Build Coastguard Worker         return NULL;
1819*e82f7db8SAndroid Build Coastguard Worker     }
1820*e82f7db8SAndroid Build Coastguard Worker     (void)memset(&caps, 0, (int)sizeof(caps));
1821*e82f7db8SAndroid Build Coastguard Worker     caps.can_tag_objects = 1;
1822*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(jvmti,AddCapabilities)(jvmti, &caps);
1823*e82f7db8SAndroid Build Coastguard Worker     if ( error != JVMTI_ERROR_NONE ) {
1824*e82f7db8SAndroid Build Coastguard Worker         return NULL;
1825*e82f7db8SAndroid Build Coastguard Worker     }
1826*e82f7db8SAndroid Build Coastguard Worker     return jvmti;
1827*e82f7db8SAndroid Build Coastguard Worker }
1828*e82f7db8SAndroid Build Coastguard Worker 
1829*e82f7db8SAndroid Build Coastguard Worker void
writeCodeLocation(PacketOutputStream * out,jclass clazz,jmethodID method,jlocation location)1830*e82f7db8SAndroid Build Coastguard Worker writeCodeLocation(PacketOutputStream *out, jclass clazz,
1831*e82f7db8SAndroid Build Coastguard Worker                        jmethodID method, jlocation location)
1832*e82f7db8SAndroid Build Coastguard Worker {
1833*e82f7db8SAndroid Build Coastguard Worker     jbyte tag;
1834*e82f7db8SAndroid Build Coastguard Worker 
1835*e82f7db8SAndroid Build Coastguard Worker     if (clazz != NULL) {
1836*e82f7db8SAndroid Build Coastguard Worker         tag = referenceTypeTag(clazz);
1837*e82f7db8SAndroid Build Coastguard Worker     } else {
1838*e82f7db8SAndroid Build Coastguard Worker         tag = JDWP_TYPE_TAG(CLASS);
1839*e82f7db8SAndroid Build Coastguard Worker     }
1840*e82f7db8SAndroid Build Coastguard Worker     (void)outStream_writeByte(out, tag);
1841*e82f7db8SAndroid Build Coastguard Worker     (void)outStream_writeObjectRef(getEnv(), out, clazz);
1842*e82f7db8SAndroid Build Coastguard Worker     (void)outStream_writeMethodID(out, isMethodObsolete(method)?NULL:method);
1843*e82f7db8SAndroid Build Coastguard Worker     (void)outStream_writeLocation(out, location);
1844*e82f7db8SAndroid Build Coastguard Worker }
1845*e82f7db8SAndroid Build Coastguard Worker 
1846*e82f7db8SAndroid Build Coastguard Worker void *
jvmtiAllocate(jint numBytes)1847*e82f7db8SAndroid Build Coastguard Worker jvmtiAllocate(jint numBytes)
1848*e82f7db8SAndroid Build Coastguard Worker {
1849*e82f7db8SAndroid Build Coastguard Worker     void *ptr;
1850*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1851*e82f7db8SAndroid Build Coastguard Worker     if ( numBytes == 0 ) {
1852*e82f7db8SAndroid Build Coastguard Worker         return NULL;
1853*e82f7db8SAndroid Build Coastguard Worker     }
1854*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,Allocate)
1855*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, numBytes, (unsigned char**)&ptr);
1856*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE ) {
1857*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "Can't allocate jvmti memory");
1858*e82f7db8SAndroid Build Coastguard Worker     }
1859*e82f7db8SAndroid Build Coastguard Worker     return ptr;
1860*e82f7db8SAndroid Build Coastguard Worker }
1861*e82f7db8SAndroid Build Coastguard Worker 
1862*e82f7db8SAndroid Build Coastguard Worker void
jvmtiDeallocate(void * ptr)1863*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(void *ptr)
1864*e82f7db8SAndroid Build Coastguard Worker {
1865*e82f7db8SAndroid Build Coastguard Worker     jvmtiError error;
1866*e82f7db8SAndroid Build Coastguard Worker     if ( ptr == NULL ) {
1867*e82f7db8SAndroid Build Coastguard Worker         return;
1868*e82f7db8SAndroid Build Coastguard Worker     }
1869*e82f7db8SAndroid Build Coastguard Worker     error = FUNC_PTR(gdata->jvmti,Deallocate)
1870*e82f7db8SAndroid Build Coastguard Worker                 (gdata->jvmti, ptr);
1871*e82f7db8SAndroid Build Coastguard Worker     if (error != JVMTI_ERROR_NONE ) {
1872*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(error, "Can't deallocate jvmti memory");
1873*e82f7db8SAndroid Build Coastguard Worker     }
1874*e82f7db8SAndroid Build Coastguard Worker }
1875*e82f7db8SAndroid Build Coastguard Worker 
1876*e82f7db8SAndroid Build Coastguard Worker /* Rarely needed, transport library uses JDWP errors, only use? */
1877*e82f7db8SAndroid Build Coastguard Worker jvmtiError
map2jvmtiError(jdwpError error)1878*e82f7db8SAndroid Build Coastguard Worker map2jvmtiError(jdwpError error)
1879*e82f7db8SAndroid Build Coastguard Worker {
1880*e82f7db8SAndroid Build Coastguard Worker     switch ( error ) {
1881*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NONE):
1882*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NONE;
1883*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_THREAD):
1884*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_THREAD;
1885*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_THREAD_GROUP):
1886*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_THREAD_GROUP;
1887*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_PRIORITY):
1888*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_PRIORITY;
1889*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(THREAD_NOT_SUSPENDED):
1890*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1891*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(THREAD_SUSPENDED):
1892*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_THREAD_SUSPENDED;
1893*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_OBJECT):
1894*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_OBJECT;
1895*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_CLASS):
1896*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_CLASS;
1897*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(CLASS_NOT_PREPARED):
1898*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_CLASS_NOT_PREPARED;
1899*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_METHODID):
1900*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_METHODID;
1901*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_LOCATION):
1902*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_LOCATION;
1903*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_FIELDID):
1904*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_FIELDID;
1905*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_FRAMEID):
1906*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_FRAMEID;
1907*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NO_MORE_FRAMES):
1908*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NO_MORE_FRAMES;
1909*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(OPAQUE_FRAME):
1910*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_OPAQUE_FRAME;
1911*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NOT_CURRENT_FRAME):
1912*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_NOT_CURRENT_FRAME;
1913*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(TYPE_MISMATCH):
1914*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_TYPE_MISMATCH;
1915*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_SLOT):
1916*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_SLOT;
1917*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(DUPLICATE):
1918*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_DUPLICATE;
1919*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NOT_FOUND):
1920*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NOT_FOUND;
1921*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_MONITOR):
1922*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_MONITOR;
1923*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NOT_MONITOR_OWNER):
1924*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NOT_MONITOR_OWNER;
1925*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INTERRUPT):
1926*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INTERRUPT;
1927*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_CLASS_FORMAT):
1928*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_CLASS_FORMAT;
1929*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(CIRCULAR_CLASS_DEFINITION):
1930*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
1931*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(FAILS_VERIFICATION):
1932*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_FAILS_VERIFICATION;
1933*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED):
1934*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
1935*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED):
1936*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
1937*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_TYPESTATE):
1938*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_TYPESTATE;
1939*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED):
1940*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
1941*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED):
1942*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
1943*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(UNSUPPORTED_VERSION):
1944*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_VERSION;
1945*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NAMES_DONT_MATCH):
1946*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NAMES_DONT_MATCH;
1947*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
1948*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
1949*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
1950*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
1951*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NOT_IMPLEMENTED):
1952*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NOT_AVAILABLE;
1953*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NULL_POINTER):
1954*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_NULL_POINTER;
1955*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(ABSENT_INFORMATION):
1956*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_ABSENT_INFORMATION;
1957*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_EVENT_TYPE):
1958*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_INVALID_EVENT_TYPE;
1959*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(ILLEGAL_ARGUMENT):
1960*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1961*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(OUT_OF_MEMORY):
1962*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_OUT_OF_MEMORY;
1963*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(ACCESS_DENIED):
1964*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_ACCESS_DENIED;
1965*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(VM_DEAD):
1966*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_WRONG_PHASE;
1967*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(UNATTACHED_THREAD):
1968*e82f7db8SAndroid Build Coastguard Worker             return JVMTI_ERROR_UNATTACHED_THREAD;
1969*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_TAG):
1970*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_TAG;
1971*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(ALREADY_INVOKING):
1972*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_ALREADY_INVOKING;
1973*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_INDEX):
1974*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_INDEX;
1975*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_LENGTH):
1976*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_LENGTH;
1977*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_STRING):
1978*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_STRING;
1979*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_CLASS_LOADER):
1980*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_CLASS_LOADER;
1981*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_ARRAY):
1982*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_ARRAY;
1983*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(TRANSPORT_LOAD):
1984*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_TRANSPORT_LOAD;
1985*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(TRANSPORT_INIT):
1986*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_TRANSPORT_INIT;
1987*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(NATIVE_METHOD):
1988*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_NATIVE_METHOD;
1989*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INVALID_COUNT):
1990*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_INVALID_COUNT;
1991*e82f7db8SAndroid Build Coastguard Worker         case JDWP_ERROR(INTERNAL):
1992*e82f7db8SAndroid Build Coastguard Worker             return AGENT_ERROR_JDWP_INTERNAL;
1993*e82f7db8SAndroid Build Coastguard Worker     }
1994*e82f7db8SAndroid Build Coastguard Worker     return AGENT_ERROR_INTERNAL;
1995*e82f7db8SAndroid Build Coastguard Worker }
1996*e82f7db8SAndroid Build Coastguard Worker 
1997*e82f7db8SAndroid Build Coastguard Worker static jvmtiEvent index2jvmti[EI_max-EI_min+1];
1998*e82f7db8SAndroid Build Coastguard Worker static jdwpEvent  index2jdwp [EI_max-EI_min+1];
1999*e82f7db8SAndroid Build Coastguard Worker 
2000*e82f7db8SAndroid Build Coastguard Worker void
eventIndexInit(void)2001*e82f7db8SAndroid Build Coastguard Worker eventIndexInit(void)
2002*e82f7db8SAndroid Build Coastguard Worker {
2003*e82f7db8SAndroid Build Coastguard Worker     (void)memset(index2jvmti, 0, (int)sizeof(index2jvmti));
2004*e82f7db8SAndroid Build Coastguard Worker     (void)memset(index2jdwp,  0, (int)sizeof(index2jdwp));
2005*e82f7db8SAndroid Build Coastguard Worker 
2006*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_SINGLE_STEP        -EI_min] = JVMTI_EVENT_SINGLE_STEP;
2007*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_BREAKPOINT         -EI_min] = JVMTI_EVENT_BREAKPOINT;
2008*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_FRAME_POP          -EI_min] = JVMTI_EVENT_FRAME_POP;
2009*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_EXCEPTION          -EI_min] = JVMTI_EVENT_EXCEPTION;
2010*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_THREAD_START       -EI_min] = JVMTI_EVENT_THREAD_START;
2011*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_THREAD_END         -EI_min] = JVMTI_EVENT_THREAD_END;
2012*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_CLASS_PREPARE      -EI_min] = JVMTI_EVENT_CLASS_PREPARE;
2013*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_GC_FINISH          -EI_min] = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH;
2014*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_CLASS_LOAD         -EI_min] = JVMTI_EVENT_CLASS_LOAD;
2015*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_FIELD_ACCESS       -EI_min] = JVMTI_EVENT_FIELD_ACCESS;
2016*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_FIELD_MODIFICATION -EI_min] = JVMTI_EVENT_FIELD_MODIFICATION;
2017*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_EXCEPTION_CATCH    -EI_min] = JVMTI_EVENT_EXCEPTION_CATCH;
2018*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_METHOD_ENTRY       -EI_min] = JVMTI_EVENT_METHOD_ENTRY;
2019*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_METHOD_EXIT        -EI_min] = JVMTI_EVENT_METHOD_EXIT;
2020*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_MONITOR_CONTENDED_ENTER      -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTER;
2021*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_MONITOR_CONTENDED_ENTERED    -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED;
2022*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_MONITOR_WAIT       -EI_min] = JVMTI_EVENT_MONITOR_WAIT;
2023*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_MONITOR_WAITED     -EI_min] = JVMTI_EVENT_MONITOR_WAITED;
2024*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_VM_INIT            -EI_min] = JVMTI_EVENT_VM_INIT;
2025*e82f7db8SAndroid Build Coastguard Worker     index2jvmti[EI_VM_DEATH           -EI_min] = JVMTI_EVENT_VM_DEATH;
2026*e82f7db8SAndroid Build Coastguard Worker 
2027*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_SINGLE_STEP         -EI_min] = JDWP_EVENT(SINGLE_STEP);
2028*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_BREAKPOINT          -EI_min] = JDWP_EVENT(BREAKPOINT);
2029*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_FRAME_POP           -EI_min] = JDWP_EVENT(FRAME_POP);
2030*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_EXCEPTION           -EI_min] = JDWP_EVENT(EXCEPTION);
2031*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_THREAD_START        -EI_min] = JDWP_EVENT(THREAD_START);
2032*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_THREAD_END          -EI_min] = JDWP_EVENT(THREAD_END);
2033*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_CLASS_PREPARE       -EI_min] = JDWP_EVENT(CLASS_PREPARE);
2034*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_GC_FINISH           -EI_min] = JDWP_EVENT(CLASS_UNLOAD);
2035*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_CLASS_LOAD          -EI_min] = JDWP_EVENT(CLASS_LOAD);
2036*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_FIELD_ACCESS        -EI_min] = JDWP_EVENT(FIELD_ACCESS);
2037*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_FIELD_MODIFICATION  -EI_min] = JDWP_EVENT(FIELD_MODIFICATION);
2038*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_EXCEPTION_CATCH     -EI_min] = JDWP_EVENT(EXCEPTION_CATCH);
2039*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_METHOD_ENTRY        -EI_min] = JDWP_EVENT(METHOD_ENTRY);
2040*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_METHOD_EXIT         -EI_min] = JDWP_EVENT(METHOD_EXIT);
2041*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_MONITOR_CONTENDED_ENTER             -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTER);
2042*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_MONITOR_CONTENDED_ENTERED           -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTERED);
2043*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_MONITOR_WAIT        -EI_min] = JDWP_EVENT(MONITOR_WAIT);
2044*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_MONITOR_WAITED      -EI_min] = JDWP_EVENT(MONITOR_WAITED);
2045*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_VM_INIT             -EI_min] = JDWP_EVENT(VM_INIT);
2046*e82f7db8SAndroid Build Coastguard Worker     index2jdwp[EI_VM_DEATH            -EI_min] = JDWP_EVENT(VM_DEATH);
2047*e82f7db8SAndroid Build Coastguard Worker }
2048*e82f7db8SAndroid Build Coastguard Worker 
2049*e82f7db8SAndroid Build Coastguard Worker jdwpEvent
eventIndex2jdwp(EventIndex i)2050*e82f7db8SAndroid Build Coastguard Worker eventIndex2jdwp(EventIndex i)
2051*e82f7db8SAndroid Build Coastguard Worker {
2052*e82f7db8SAndroid Build Coastguard Worker     if ( i < EI_min || i > EI_max ) {
2053*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
2054*e82f7db8SAndroid Build Coastguard Worker     }
2055*e82f7db8SAndroid Build Coastguard Worker     return index2jdwp[i-EI_min];
2056*e82f7db8SAndroid Build Coastguard Worker }
2057*e82f7db8SAndroid Build Coastguard Worker 
2058*e82f7db8SAndroid Build Coastguard Worker jvmtiEvent
eventIndex2jvmti(EventIndex i)2059*e82f7db8SAndroid Build Coastguard Worker eventIndex2jvmti(EventIndex i)
2060*e82f7db8SAndroid Build Coastguard Worker {
2061*e82f7db8SAndroid Build Coastguard Worker     if ( i < EI_min || i > EI_max ) {
2062*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
2063*e82f7db8SAndroid Build Coastguard Worker     }
2064*e82f7db8SAndroid Build Coastguard Worker     return index2jvmti[i-EI_min];
2065*e82f7db8SAndroid Build Coastguard Worker }
2066*e82f7db8SAndroid Build Coastguard Worker 
2067*e82f7db8SAndroid Build Coastguard Worker EventIndex
jdwp2EventIndex(jdwpEvent eventType)2068*e82f7db8SAndroid Build Coastguard Worker jdwp2EventIndex(jdwpEvent eventType)
2069*e82f7db8SAndroid Build Coastguard Worker {
2070*e82f7db8SAndroid Build Coastguard Worker     switch ( eventType ) {
2071*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(SINGLE_STEP):
2072*e82f7db8SAndroid Build Coastguard Worker             return EI_SINGLE_STEP;
2073*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(BREAKPOINT):
2074*e82f7db8SAndroid Build Coastguard Worker             return EI_BREAKPOINT;
2075*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(FRAME_POP):
2076*e82f7db8SAndroid Build Coastguard Worker             return EI_FRAME_POP;
2077*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(EXCEPTION):
2078*e82f7db8SAndroid Build Coastguard Worker             return EI_EXCEPTION;
2079*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(THREAD_START):
2080*e82f7db8SAndroid Build Coastguard Worker             return EI_THREAD_START;
2081*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(THREAD_END):
2082*e82f7db8SAndroid Build Coastguard Worker             return EI_THREAD_END;
2083*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(CLASS_PREPARE):
2084*e82f7db8SAndroid Build Coastguard Worker             return EI_CLASS_PREPARE;
2085*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(CLASS_UNLOAD):
2086*e82f7db8SAndroid Build Coastguard Worker             return EI_GC_FINISH;
2087*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(CLASS_LOAD):
2088*e82f7db8SAndroid Build Coastguard Worker             return EI_CLASS_LOAD;
2089*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(FIELD_ACCESS):
2090*e82f7db8SAndroid Build Coastguard Worker             return EI_FIELD_ACCESS;
2091*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(FIELD_MODIFICATION):
2092*e82f7db8SAndroid Build Coastguard Worker             return EI_FIELD_MODIFICATION;
2093*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(EXCEPTION_CATCH):
2094*e82f7db8SAndroid Build Coastguard Worker             return EI_EXCEPTION_CATCH;
2095*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(METHOD_ENTRY):
2096*e82f7db8SAndroid Build Coastguard Worker             return EI_METHOD_ENTRY;
2097*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(METHOD_EXIT):
2098*e82f7db8SAndroid Build Coastguard Worker             return EI_METHOD_EXIT;
2099*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE):
2100*e82f7db8SAndroid Build Coastguard Worker             return EI_METHOD_EXIT;
2101*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(MONITOR_CONTENDED_ENTER):
2102*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_CONTENDED_ENTER;
2103*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(MONITOR_CONTENDED_ENTERED):
2104*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_CONTENDED_ENTERED;
2105*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(MONITOR_WAIT):
2106*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_WAIT;
2107*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(MONITOR_WAITED):
2108*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_WAITED;
2109*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(VM_INIT):
2110*e82f7db8SAndroid Build Coastguard Worker             return EI_VM_INIT;
2111*e82f7db8SAndroid Build Coastguard Worker         case JDWP_EVENT(VM_DEATH):
2112*e82f7db8SAndroid Build Coastguard Worker             return EI_VM_DEATH;
2113*e82f7db8SAndroid Build Coastguard Worker         default:
2114*e82f7db8SAndroid Build Coastguard Worker             break;
2115*e82f7db8SAndroid Build Coastguard Worker     }
2116*e82f7db8SAndroid Build Coastguard Worker 
2117*e82f7db8SAndroid Build Coastguard Worker     /*
2118*e82f7db8SAndroid Build Coastguard Worker      * Event type not recognized - don't exit with error as caller
2119*e82f7db8SAndroid Build Coastguard Worker      * may wish to return error to debugger.
2120*e82f7db8SAndroid Build Coastguard Worker      */
2121*e82f7db8SAndroid Build Coastguard Worker     return (EventIndex)0;
2122*e82f7db8SAndroid Build Coastguard Worker }
2123*e82f7db8SAndroid Build Coastguard Worker 
2124*e82f7db8SAndroid Build Coastguard Worker EventIndex
jvmti2EventIndex(jvmtiEvent kind)2125*e82f7db8SAndroid Build Coastguard Worker jvmti2EventIndex(jvmtiEvent kind)
2126*e82f7db8SAndroid Build Coastguard Worker {
2127*e82f7db8SAndroid Build Coastguard Worker     switch ( kind ) {
2128*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_SINGLE_STEP:
2129*e82f7db8SAndroid Build Coastguard Worker             return EI_SINGLE_STEP;
2130*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_BREAKPOINT:
2131*e82f7db8SAndroid Build Coastguard Worker             return EI_BREAKPOINT;
2132*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_FRAME_POP:
2133*e82f7db8SAndroid Build Coastguard Worker             return EI_FRAME_POP;
2134*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_EXCEPTION:
2135*e82f7db8SAndroid Build Coastguard Worker             return EI_EXCEPTION;
2136*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_THREAD_START:
2137*e82f7db8SAndroid Build Coastguard Worker             return EI_THREAD_START;
2138*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_THREAD_END:
2139*e82f7db8SAndroid Build Coastguard Worker             return EI_THREAD_END;
2140*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_CLASS_PREPARE:
2141*e82f7db8SAndroid Build Coastguard Worker             return EI_CLASS_PREPARE;
2142*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2143*e82f7db8SAndroid Build Coastguard Worker             return EI_GC_FINISH;
2144*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_CLASS_LOAD:
2145*e82f7db8SAndroid Build Coastguard Worker             return EI_CLASS_LOAD;
2146*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_FIELD_ACCESS:
2147*e82f7db8SAndroid Build Coastguard Worker             return EI_FIELD_ACCESS;
2148*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_FIELD_MODIFICATION:
2149*e82f7db8SAndroid Build Coastguard Worker             return EI_FIELD_MODIFICATION;
2150*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_EXCEPTION_CATCH:
2151*e82f7db8SAndroid Build Coastguard Worker             return EI_EXCEPTION_CATCH;
2152*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_METHOD_ENTRY:
2153*e82f7db8SAndroid Build Coastguard Worker             return EI_METHOD_ENTRY;
2154*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_METHOD_EXIT:
2155*e82f7db8SAndroid Build Coastguard Worker             return EI_METHOD_EXIT;
2156*e82f7db8SAndroid Build Coastguard Worker         /*
2157*e82f7db8SAndroid Build Coastguard Worker          * There is no JVMTI_EVENT_METHOD_EXIT_WITH_RETURN_VALUE.
2158*e82f7db8SAndroid Build Coastguard Worker          * The normal JVMTI_EVENT_METHOD_EXIT always contains the return value.
2159*e82f7db8SAndroid Build Coastguard Worker          */
2160*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2161*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_CONTENDED_ENTER;
2162*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2163*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_CONTENDED_ENTERED;
2164*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_MONITOR_WAIT:
2165*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_WAIT;
2166*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_MONITOR_WAITED:
2167*e82f7db8SAndroid Build Coastguard Worker             return EI_MONITOR_WAITED;
2168*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_VM_INIT:
2169*e82f7db8SAndroid Build Coastguard Worker             return EI_VM_INIT;
2170*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_EVENT_VM_DEATH:
2171*e82f7db8SAndroid Build Coastguard Worker             return EI_VM_DEATH;
2172*e82f7db8SAndroid Build Coastguard Worker         default:
2173*e82f7db8SAndroid Build Coastguard Worker             EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"JVMTI to EventIndex mapping");
2174*e82f7db8SAndroid Build Coastguard Worker             break;
2175*e82f7db8SAndroid Build Coastguard Worker     }
2176*e82f7db8SAndroid Build Coastguard Worker     return (EventIndex)0;
2177*e82f7db8SAndroid Build Coastguard Worker }
2178*e82f7db8SAndroid Build Coastguard Worker 
2179*e82f7db8SAndroid Build Coastguard Worker /* This routine is commonly used, maps jvmti and agent errors to the best
2180*e82f7db8SAndroid Build Coastguard Worker  *    jdwp error code we can map to.
2181*e82f7db8SAndroid Build Coastguard Worker  */
2182*e82f7db8SAndroid Build Coastguard Worker jdwpError
map2jdwpError(jvmtiError error)2183*e82f7db8SAndroid Build Coastguard Worker map2jdwpError(jvmtiError error)
2184*e82f7db8SAndroid Build Coastguard Worker {
2185*e82f7db8SAndroid Build Coastguard Worker     switch ( error ) {
2186*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NONE:
2187*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NONE);
2188*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_THREAD:
2189*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_THREAD:
2190*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_THREAD);
2191*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_THREAD_GROUP:
2192*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_THREAD_GROUP);
2193*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_PRIORITY:
2194*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_PRIORITY);
2195*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
2196*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(THREAD_NOT_SUSPENDED);
2197*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_THREAD_SUSPENDED:
2198*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(THREAD_SUSPENDED);
2199*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_THREAD_NOT_ALIVE:
2200*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_THREAD);
2201*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_OBJECT:
2202*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_OBJECT:
2203*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_OBJECT);
2204*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_CLASS:
2205*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_CLASS);
2206*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_CLASS_NOT_PREPARED:
2207*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(CLASS_NOT_PREPARED);
2208*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_METHODID:
2209*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_METHODID);
2210*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_LOCATION:
2211*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_LOCATION);
2212*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_FIELDID:
2213*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_FIELDID);
2214*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_NO_MORE_FRAMES:
2215*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NO_MORE_FRAMES:
2216*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NO_MORE_FRAMES);
2217*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_OPAQUE_FRAME:
2218*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(OPAQUE_FRAME);
2219*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_TYPE_MISMATCH:
2220*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(TYPE_MISMATCH);
2221*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_SLOT:
2222*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_SLOT);
2223*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_DUPLICATE:
2224*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(DUPLICATE);
2225*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NOT_FOUND:
2226*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NOT_FOUND);
2227*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_MONITOR:
2228*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_MONITOR);
2229*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NOT_MONITOR_OWNER:
2230*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NOT_MONITOR_OWNER);
2231*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INTERRUPT:
2232*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INTERRUPT);
2233*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_CLASS_FORMAT:
2234*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_CLASS_FORMAT);
2235*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
2236*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(CIRCULAR_CLASS_DEFINITION);
2237*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_FAILS_VERIFICATION:
2238*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(FAILS_VERIFICATION);
2239*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_TYPESTATE:
2240*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_TYPESTATE);
2241*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_VERSION:
2242*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(UNSUPPORTED_VERSION);
2243*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NAMES_DONT_MATCH:
2244*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NAMES_DONT_MATCH);
2245*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_NULL_POINTER:
2246*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NULL_POINTER:
2247*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NULL_POINTER);
2248*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_ABSENT_INFORMATION:
2249*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(ABSENT_INFORMATION);
2250*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_EVENT_TYPE:
2251*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_EVENT_TYPE:
2252*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_EVENT_TYPE);
2253*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_ILLEGAL_ARGUMENT:
2254*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_ILLEGAL_ARGUMENT:
2255*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(ILLEGAL_ARGUMENT);
2256*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_OUT_OF_MEMORY:
2257*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_OUT_OF_MEMORY:
2258*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(OUT_OF_MEMORY);
2259*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_ACCESS_DENIED:
2260*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(ACCESS_DENIED);
2261*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_WRONG_PHASE:
2262*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_VM_DEAD:
2263*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_NO_JNI_ENV:
2264*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(VM_DEAD);
2265*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_JNI_EXCEPTION:
2266*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNATTACHED_THREAD:
2267*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(UNATTACHED_THREAD);
2268*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_NOT_AVAILABLE:
2269*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
2270*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NOT_IMPLEMENTED);
2271*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
2272*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED);
2273*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
2274*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED);
2275*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
2276*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED);
2277*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
2278*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED);
2279*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
2280*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
2281*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
2282*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
2283*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_NOT_CURRENT_FRAME:
2284*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NOT_CURRENT_FRAME);
2285*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_TAG:
2286*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_TAG);
2287*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_ALREADY_INVOKING:
2288*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(ALREADY_INVOKING);
2289*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_INDEX:
2290*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_INDEX);
2291*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_LENGTH:
2292*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_LENGTH);
2293*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_STRING:
2294*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_STRING);
2295*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_CLASS_LOADER:
2296*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_CLASS_LOADER);
2297*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_ARRAY:
2298*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_ARRAY);
2299*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_TRANSPORT_LOAD:
2300*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(TRANSPORT_LOAD);
2301*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_TRANSPORT_INIT:
2302*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(TRANSPORT_INIT);
2303*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_NATIVE_METHOD:
2304*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(NATIVE_METHOD);
2305*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_COUNT:
2306*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_COUNT);
2307*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INVALID_FRAMEID:
2308*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INVALID_FRAMEID);
2309*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INTERNAL:
2310*e82f7db8SAndroid Build Coastguard Worker         case JVMTI_ERROR_INVALID_ENVIRONMENT:
2311*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_INTERNAL:
2312*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_JVMTI_INTERNAL:
2313*e82f7db8SAndroid Build Coastguard Worker         case AGENT_ERROR_JDWP_INTERNAL:
2314*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(INTERNAL);
2315*e82f7db8SAndroid Build Coastguard Worker         default:
2316*e82f7db8SAndroid Build Coastguard Worker             break;
2317*e82f7db8SAndroid Build Coastguard Worker     }
2318*e82f7db8SAndroid Build Coastguard Worker     return JDWP_ERROR(INTERNAL);
2319*e82f7db8SAndroid Build Coastguard Worker }
2320*e82f7db8SAndroid Build Coastguard Worker 
2321*e82f7db8SAndroid Build Coastguard Worker jint
map2jdwpSuspendStatus(jint state)2322*e82f7db8SAndroid Build Coastguard Worker map2jdwpSuspendStatus(jint state)
2323*e82f7db8SAndroid Build Coastguard Worker {
2324*e82f7db8SAndroid Build Coastguard Worker     jint status = 0;
2325*e82f7db8SAndroid Build Coastguard Worker     if ( ( state & JVMTI_THREAD_STATE_SUSPENDED ) != 0 )  {
2326*e82f7db8SAndroid Build Coastguard Worker         status = JDWP_SUSPEND_STATUS(SUSPENDED);
2327*e82f7db8SAndroid Build Coastguard Worker     }
2328*e82f7db8SAndroid Build Coastguard Worker     return status;
2329*e82f7db8SAndroid Build Coastguard Worker }
2330*e82f7db8SAndroid Build Coastguard Worker 
2331*e82f7db8SAndroid Build Coastguard Worker jdwpThreadStatus
map2jdwpThreadStatus(jint state)2332*e82f7db8SAndroid Build Coastguard Worker map2jdwpThreadStatus(jint state)
2333*e82f7db8SAndroid Build Coastguard Worker {
2334*e82f7db8SAndroid Build Coastguard Worker     jdwpThreadStatus status;
2335*e82f7db8SAndroid Build Coastguard Worker 
2336*e82f7db8SAndroid Build Coastguard Worker     status = (jdwpThreadStatus)(-1);
2337*e82f7db8SAndroid Build Coastguard Worker 
2338*e82f7db8SAndroid Build Coastguard Worker     if ( ! ( state & JVMTI_THREAD_STATE_ALIVE ) ) {
2339*e82f7db8SAndroid Build Coastguard Worker         if ( state & JVMTI_THREAD_STATE_TERMINATED ) {
2340*e82f7db8SAndroid Build Coastguard Worker             status = JDWP_THREAD_STATUS(ZOMBIE);
2341*e82f7db8SAndroid Build Coastguard Worker         } else {
2342*e82f7db8SAndroid Build Coastguard Worker             /* FIXUP? New JDWP #define for not started? */
2343*e82f7db8SAndroid Build Coastguard Worker             status = (jdwpThreadStatus)(-1);
2344*e82f7db8SAndroid Build Coastguard Worker         }
2345*e82f7db8SAndroid Build Coastguard Worker     } else {
2346*e82f7db8SAndroid Build Coastguard Worker         if ( state & JVMTI_THREAD_STATE_SLEEPING ) {
2347*e82f7db8SAndroid Build Coastguard Worker             status = JDWP_THREAD_STATUS(SLEEPING);
2348*e82f7db8SAndroid Build Coastguard Worker         } else if ( state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
2349*e82f7db8SAndroid Build Coastguard Worker             status = JDWP_THREAD_STATUS(MONITOR);
2350*e82f7db8SAndroid Build Coastguard Worker         } else if ( state & JVMTI_THREAD_STATE_WAITING ) {
2351*e82f7db8SAndroid Build Coastguard Worker             status = JDWP_THREAD_STATUS(WAIT);
2352*e82f7db8SAndroid Build Coastguard Worker         } else if ( state & JVMTI_THREAD_STATE_RUNNABLE ) {
2353*e82f7db8SAndroid Build Coastguard Worker             status = JDWP_THREAD_STATUS(RUNNING);
2354*e82f7db8SAndroid Build Coastguard Worker         }
2355*e82f7db8SAndroid Build Coastguard Worker     }
2356*e82f7db8SAndroid Build Coastguard Worker     return status;
2357*e82f7db8SAndroid Build Coastguard Worker }
2358*e82f7db8SAndroid Build Coastguard Worker 
2359*e82f7db8SAndroid Build Coastguard Worker jint
map2jdwpClassStatus(jint classStatus)2360*e82f7db8SAndroid Build Coastguard Worker map2jdwpClassStatus(jint classStatus)
2361*e82f7db8SAndroid Build Coastguard Worker {
2362*e82f7db8SAndroid Build Coastguard Worker     jint status = 0;
2363*e82f7db8SAndroid Build Coastguard Worker     if ( ( classStatus & JVMTI_CLASS_STATUS_VERIFIED ) != 0 ) {
2364*e82f7db8SAndroid Build Coastguard Worker         status |= JDWP_CLASS_STATUS(VERIFIED);
2365*e82f7db8SAndroid Build Coastguard Worker     }
2366*e82f7db8SAndroid Build Coastguard Worker     if ( ( classStatus & JVMTI_CLASS_STATUS_PREPARED ) != 0 ) {
2367*e82f7db8SAndroid Build Coastguard Worker         status |= JDWP_CLASS_STATUS(PREPARED);
2368*e82f7db8SAndroid Build Coastguard Worker     }
2369*e82f7db8SAndroid Build Coastguard Worker     if ( ( classStatus & JVMTI_CLASS_STATUS_INITIALIZED ) != 0 ) {
2370*e82f7db8SAndroid Build Coastguard Worker         status |= JDWP_CLASS_STATUS(INITIALIZED);
2371*e82f7db8SAndroid Build Coastguard Worker     }
2372*e82f7db8SAndroid Build Coastguard Worker     if ( ( classStatus & JVMTI_CLASS_STATUS_ERROR ) != 0 ) {
2373*e82f7db8SAndroid Build Coastguard Worker         status |= JDWP_CLASS_STATUS(ERROR);
2374*e82f7db8SAndroid Build Coastguard Worker     }
2375*e82f7db8SAndroid Build Coastguard Worker     return status;
2376*e82f7db8SAndroid Build Coastguard Worker }
2377*e82f7db8SAndroid Build Coastguard Worker 
2378*e82f7db8SAndroid Build Coastguard Worker void
log_debugee_location(const char * func,jthread thread,jmethodID method,jlocation location)2379*e82f7db8SAndroid Build Coastguard Worker log_debugee_location(const char *func,
2380*e82f7db8SAndroid Build Coastguard Worker         jthread thread, jmethodID method, jlocation location)
2381*e82f7db8SAndroid Build Coastguard Worker {
2382*e82f7db8SAndroid Build Coastguard Worker     int logging_locations = LOG_TEST(JDWP_LOG_LOC);
2383*e82f7db8SAndroid Build Coastguard Worker 
2384*e82f7db8SAndroid Build Coastguard Worker     if ( logging_locations ) {
2385*e82f7db8SAndroid Build Coastguard Worker         char *method_name;
2386*e82f7db8SAndroid Build Coastguard Worker         char *class_sig;
2387*e82f7db8SAndroid Build Coastguard Worker         jvmtiError error;
2388*e82f7db8SAndroid Build Coastguard Worker         jvmtiThreadInfo info;
2389*e82f7db8SAndroid Build Coastguard Worker         jint state;
2390*e82f7db8SAndroid Build Coastguard Worker 
2391*e82f7db8SAndroid Build Coastguard Worker         /* Get thread information */
2392*e82f7db8SAndroid Build Coastguard Worker         info.name = NULL;
2393*e82f7db8SAndroid Build Coastguard Worker         error = FUNC_PTR(gdata->jvmti,GetThreadInfo)
2394*e82f7db8SAndroid Build Coastguard Worker                                 (gdata->jvmti, thread, &info);
2395*e82f7db8SAndroid Build Coastguard Worker         if ( error != JVMTI_ERROR_NONE) {
2396*e82f7db8SAndroid Build Coastguard Worker             info.name = NULL;
2397*e82f7db8SAndroid Build Coastguard Worker         }
2398*e82f7db8SAndroid Build Coastguard Worker         error = FUNC_PTR(gdata->jvmti,GetThreadState)
2399*e82f7db8SAndroid Build Coastguard Worker                                 (gdata->jvmti, thread, &state);
2400*e82f7db8SAndroid Build Coastguard Worker         if ( error != JVMTI_ERROR_NONE) {
2401*e82f7db8SAndroid Build Coastguard Worker             state = 0;
2402*e82f7db8SAndroid Build Coastguard Worker         }
2403*e82f7db8SAndroid Build Coastguard Worker 
2404*e82f7db8SAndroid Build Coastguard Worker         /* Get method if necessary */
2405*e82f7db8SAndroid Build Coastguard Worker         if ( method==NULL ) {
2406*e82f7db8SAndroid Build Coastguard Worker             error = FUNC_PTR(gdata->jvmti,GetFrameLocation)
2407*e82f7db8SAndroid Build Coastguard Worker                         (gdata->jvmti, thread, 0, &method, &location);
2408*e82f7db8SAndroid Build Coastguard Worker             if ( error != JVMTI_ERROR_NONE ) {
2409*e82f7db8SAndroid Build Coastguard Worker                 method = NULL;
2410*e82f7db8SAndroid Build Coastguard Worker                 location = 0;
2411*e82f7db8SAndroid Build Coastguard Worker             }
2412*e82f7db8SAndroid Build Coastguard Worker         }
2413*e82f7db8SAndroid Build Coastguard Worker 
2414*e82f7db8SAndroid Build Coastguard Worker         /* Get method name */
2415*e82f7db8SAndroid Build Coastguard Worker         method_name = NULL;
2416*e82f7db8SAndroid Build Coastguard Worker         if ( method != NULL ) {
2417*e82f7db8SAndroid Build Coastguard Worker             error = methodSignature(method, &method_name, NULL, NULL);
2418*e82f7db8SAndroid Build Coastguard Worker             if ( error != JVMTI_ERROR_NONE ) {
2419*e82f7db8SAndroid Build Coastguard Worker                 method_name = NULL;
2420*e82f7db8SAndroid Build Coastguard Worker             }
2421*e82f7db8SAndroid Build Coastguard Worker         }
2422*e82f7db8SAndroid Build Coastguard Worker 
2423*e82f7db8SAndroid Build Coastguard Worker         /* Get class signature */
2424*e82f7db8SAndroid Build Coastguard Worker         class_sig = NULL;
2425*e82f7db8SAndroid Build Coastguard Worker         if ( method != NULL ) {
2426*e82f7db8SAndroid Build Coastguard Worker             jclass clazz;
2427*e82f7db8SAndroid Build Coastguard Worker 
2428*e82f7db8SAndroid Build Coastguard Worker             error = methodClass(method, &clazz);
2429*e82f7db8SAndroid Build Coastguard Worker             if ( error == JVMTI_ERROR_NONE ) {
2430*e82f7db8SAndroid Build Coastguard Worker                 error = classSignature(clazz, &class_sig, NULL);
2431*e82f7db8SAndroid Build Coastguard Worker                 if ( error != JVMTI_ERROR_NONE ) {
2432*e82f7db8SAndroid Build Coastguard Worker                     class_sig = NULL;
2433*e82f7db8SAndroid Build Coastguard Worker                 }
2434*e82f7db8SAndroid Build Coastguard Worker             }
2435*e82f7db8SAndroid Build Coastguard Worker         }
2436*e82f7db8SAndroid Build Coastguard Worker 
2437*e82f7db8SAndroid Build Coastguard Worker         /* Issue log message */
2438*e82f7db8SAndroid Build Coastguard Worker         LOG_LOC(("%s: debugee: thread=%p(%s:0x%x),method=%p(%s@%d;%s)",
2439*e82f7db8SAndroid Build Coastguard Worker                 func,
2440*e82f7db8SAndroid Build Coastguard Worker                 thread, info.name==NULL ? "?" : info.name, state,
2441*e82f7db8SAndroid Build Coastguard Worker                 method, method_name==NULL ? "?" : method_name,
2442*e82f7db8SAndroid Build Coastguard Worker                 (int)location, class_sig==NULL ? "?" : class_sig));
2443*e82f7db8SAndroid Build Coastguard Worker 
2444*e82f7db8SAndroid Build Coastguard Worker         /* Free memory */
2445*e82f7db8SAndroid Build Coastguard Worker         if ( class_sig != NULL ) {
2446*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(class_sig);
2447*e82f7db8SAndroid Build Coastguard Worker         }
2448*e82f7db8SAndroid Build Coastguard Worker         if ( method_name != NULL ) {
2449*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(method_name);
2450*e82f7db8SAndroid Build Coastguard Worker         }
2451*e82f7db8SAndroid Build Coastguard Worker         if ( info.name != NULL ) {
2452*e82f7db8SAndroid Build Coastguard Worker             jvmtiDeallocate(info.name);
2453*e82f7db8SAndroid Build Coastguard Worker         }
2454*e82f7db8SAndroid Build Coastguard Worker     }
2455*e82f7db8SAndroid Build Coastguard Worker }
2456*e82f7db8SAndroid Build Coastguard Worker 
2457*e82f7db8SAndroid Build Coastguard Worker /* ********************************************************************* */
2458*e82f7db8SAndroid Build Coastguard Worker /* JDK 6.0: Use of new Heap Iteration functions */
2459*e82f7db8SAndroid Build Coastguard Worker /* ********************************************************************* */
2460*e82f7db8SAndroid Build Coastguard Worker 
2461*e82f7db8SAndroid Build Coastguard Worker /* ********************************************************************* */
2462*e82f7db8SAndroid Build Coastguard Worker /* Instances */
2463*e82f7db8SAndroid Build Coastguard Worker 
2464*e82f7db8SAndroid Build Coastguard Worker /* Structure to hold class instances heap iteration data (arg user_data) */
2465*e82f7db8SAndroid Build Coastguard Worker typedef struct ClassInstancesData {
2466*e82f7db8SAndroid Build Coastguard Worker     jint         instCount;
2467*e82f7db8SAndroid Build Coastguard Worker     jint         maxInstances;
2468*e82f7db8SAndroid Build Coastguard Worker     jlong        objTag;
2469*e82f7db8SAndroid Build Coastguard Worker     jvmtiError   error;
2470*e82f7db8SAndroid Build Coastguard Worker } ClassInstancesData;
2471*e82f7db8SAndroid Build Coastguard Worker 
2472*e82f7db8SAndroid Build Coastguard Worker /* Callback for instance object tagging (heap_reference_callback). */
2473*e82f7db8SAndroid Build Coastguard Worker static jint JNICALL
cbObjectTagInstance(jvmtiHeapReferenceKind reference_kind,const jvmtiHeapReferenceInfo * reference_info,jlong class_tag,jlong referrer_class_tag,jlong size,jlong * tag_ptr,jlong * referrer_tag_ptr,jint length,void * user_data)2474*e82f7db8SAndroid Build Coastguard Worker cbObjectTagInstance(jvmtiHeapReferenceKind reference_kind,
2475*e82f7db8SAndroid Build Coastguard Worker      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2476*e82f7db8SAndroid Build Coastguard Worker      jlong referrer_class_tag, jlong size,
2477*e82f7db8SAndroid Build Coastguard Worker      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2478*e82f7db8SAndroid Build Coastguard Worker {
2479*e82f7db8SAndroid Build Coastguard Worker     ClassInstancesData  *data;
2480*e82f7db8SAndroid Build Coastguard Worker 
2481*e82f7db8SAndroid Build Coastguard Worker     /* Check data structure */
2482*e82f7db8SAndroid Build Coastguard Worker     data = (ClassInstancesData*)user_data;
2483*e82f7db8SAndroid Build Coastguard Worker     if (data == NULL) {
2484*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2485*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2486*e82f7db8SAndroid Build Coastguard Worker     }
2487*e82f7db8SAndroid Build Coastguard Worker 
2488*e82f7db8SAndroid Build Coastguard Worker     /* If we have tagged enough objects, just abort */
2489*e82f7db8SAndroid Build Coastguard Worker     if ( data->maxInstances != 0 && data->instCount >= data->maxInstances ) {
2490*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2491*e82f7db8SAndroid Build Coastguard Worker     }
2492*e82f7db8SAndroid Build Coastguard Worker 
2493*e82f7db8SAndroid Build Coastguard Worker     /* If tagged already, just continue */
2494*e82f7db8SAndroid Build Coastguard Worker     if ( (*tag_ptr) != (jlong)0 ) {
2495*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_OBJECTS;
2496*e82f7db8SAndroid Build Coastguard Worker     }
2497*e82f7db8SAndroid Build Coastguard Worker 
2498*e82f7db8SAndroid Build Coastguard Worker     /* Tag the object so we don't count it again, and so we can retrieve it */
2499*e82f7db8SAndroid Build Coastguard Worker     (*tag_ptr) = data->objTag;
2500*e82f7db8SAndroid Build Coastguard Worker     data->instCount++;
2501*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_VISIT_OBJECTS;
2502*e82f7db8SAndroid Build Coastguard Worker }
2503*e82f7db8SAndroid Build Coastguard Worker 
2504*e82f7db8SAndroid Build Coastguard Worker /* Get instances for one class */
2505*e82f7db8SAndroid Build Coastguard Worker jvmtiError
classInstances(jclass klass,ObjectBatch * instances,int maxInstances)2506*e82f7db8SAndroid Build Coastguard Worker classInstances(jclass klass, ObjectBatch *instances, int maxInstances)
2507*e82f7db8SAndroid Build Coastguard Worker {
2508*e82f7db8SAndroid Build Coastguard Worker     ClassInstancesData data;
2509*e82f7db8SAndroid Build Coastguard Worker     jvmtiHeapCallbacks heap_callbacks;
2510*e82f7db8SAndroid Build Coastguard Worker     jvmtiError         error;
2511*e82f7db8SAndroid Build Coastguard Worker     jvmtiEnv          *jvmti;
2512*e82f7db8SAndroid Build Coastguard Worker 
2513*e82f7db8SAndroid Build Coastguard Worker     /* Check interface assumptions */
2514*e82f7db8SAndroid Build Coastguard Worker 
2515*e82f7db8SAndroid Build Coastguard Worker     if (klass == NULL) {
2516*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INVALID_OBJECT;
2517*e82f7db8SAndroid Build Coastguard Worker     }
2518*e82f7db8SAndroid Build Coastguard Worker 
2519*e82f7db8SAndroid Build Coastguard Worker     if ( maxInstances < 0 || instances == NULL) {
2520*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2521*e82f7db8SAndroid Build Coastguard Worker     }
2522*e82f7db8SAndroid Build Coastguard Worker 
2523*e82f7db8SAndroid Build Coastguard Worker     /* Initialize return information */
2524*e82f7db8SAndroid Build Coastguard Worker     instances->count   = 0;
2525*e82f7db8SAndroid Build Coastguard Worker     instances->objects = NULL;
2526*e82f7db8SAndroid Build Coastguard Worker 
2527*e82f7db8SAndroid Build Coastguard Worker     /* Get jvmti environment to use */
2528*e82f7db8SAndroid Build Coastguard Worker     jvmti = getSpecialJvmti();
2529*e82f7db8SAndroid Build Coastguard Worker     if ( jvmti == NULL ) {
2530*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INTERNAL;
2531*e82f7db8SAndroid Build Coastguard Worker     }
2532*e82f7db8SAndroid Build Coastguard Worker 
2533*e82f7db8SAndroid Build Coastguard Worker     /* Setup data to passed around the callbacks */
2534*e82f7db8SAndroid Build Coastguard Worker     data.instCount    = 0;
2535*e82f7db8SAndroid Build Coastguard Worker     data.maxInstances = maxInstances;
2536*e82f7db8SAndroid Build Coastguard Worker     data.objTag       = (jlong)1;
2537*e82f7db8SAndroid Build Coastguard Worker     data.error        = JVMTI_ERROR_NONE;
2538*e82f7db8SAndroid Build Coastguard Worker 
2539*e82f7db8SAndroid Build Coastguard Worker     /* Clear out callbacks structure */
2540*e82f7db8SAndroid Build Coastguard Worker     (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2541*e82f7db8SAndroid Build Coastguard Worker 
2542*e82f7db8SAndroid Build Coastguard Worker     /* Set the callbacks we want */
2543*e82f7db8SAndroid Build Coastguard Worker     heap_callbacks.heap_reference_callback = &cbObjectTagInstance;
2544*e82f7db8SAndroid Build Coastguard Worker 
2545*e82f7db8SAndroid Build Coastguard Worker     /* Follow references, no initiating object, just this class, all objects */
2546*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2547*e82f7db8SAndroid Build Coastguard Worker                  (jvmti, 0, klass, NULL, &heap_callbacks, &data);
2548*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
2549*e82f7db8SAndroid Build Coastguard Worker         error = data.error;
2550*e82f7db8SAndroid Build Coastguard Worker     }
2551*e82f7db8SAndroid Build Coastguard Worker 
2552*e82f7db8SAndroid Build Coastguard Worker     /* Get all the instances now that they are tagged */
2553*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
2554*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
2555*e82f7db8SAndroid Build Coastguard Worker                       (jvmti, 1, &(data.objTag), &(instances->count),
2556*e82f7db8SAndroid Build Coastguard Worker                        &(instances->objects), NULL);
2557*e82f7db8SAndroid Build Coastguard Worker         /* Verify we got the count we expected */
2558*e82f7db8SAndroid Build Coastguard Worker         if ( data.instCount != instances->count ) {
2559*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_INTERNAL;
2560*e82f7db8SAndroid Build Coastguard Worker         }
2561*e82f7db8SAndroid Build Coastguard Worker     }
2562*e82f7db8SAndroid Build Coastguard Worker 
2563*e82f7db8SAndroid Build Coastguard Worker     /* Dispose of any special jvmti environment */
2564*e82f7db8SAndroid Build Coastguard Worker     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2565*e82f7db8SAndroid Build Coastguard Worker     return error;
2566*e82f7db8SAndroid Build Coastguard Worker }
2567*e82f7db8SAndroid Build Coastguard Worker 
2568*e82f7db8SAndroid Build Coastguard Worker /* ********************************************************************* */
2569*e82f7db8SAndroid Build Coastguard Worker /* Instance counts. */
2570*e82f7db8SAndroid Build Coastguard Worker 
2571*e82f7db8SAndroid Build Coastguard Worker /* Macros to convert a class or instance tag to an index and back again */
2572*e82f7db8SAndroid Build Coastguard Worker #define INDEX2CLASSTAG(i)      ((jlong)((i)+1))
2573*e82f7db8SAndroid Build Coastguard Worker #define CLASSTAG2INDEX(t)      (((int)(t))-1)
2574*e82f7db8SAndroid Build Coastguard Worker #define JLONG_ABS(x)           (((x)<(jlong)0)?-(x):(x))
2575*e82f7db8SAndroid Build Coastguard Worker 
2576*e82f7db8SAndroid Build Coastguard Worker /* Structure to hold class count heap traversal data (arg user_data) */
2577*e82f7db8SAndroid Build Coastguard Worker typedef struct ClassCountData {
2578*e82f7db8SAndroid Build Coastguard Worker     int          classCount;
2579*e82f7db8SAndroid Build Coastguard Worker     jlong       *counts;
2580*e82f7db8SAndroid Build Coastguard Worker     jlong        negObjTag;
2581*e82f7db8SAndroid Build Coastguard Worker     jvmtiError   error;
2582*e82f7db8SAndroid Build Coastguard Worker } ClassCountData;
2583*e82f7db8SAndroid Build Coastguard Worker 
2584*e82f7db8SAndroid Build Coastguard Worker /* Two different cbObjectCounter's, one for FollowReferences, one for
2585*e82f7db8SAndroid Build Coastguard Worker  *    IterateThroughHeap. Pick a card, any card.
2586*e82f7db8SAndroid Build Coastguard Worker  */
2587*e82f7db8SAndroid Build Coastguard Worker 
2588*e82f7db8SAndroid Build Coastguard Worker /* Callback for object count heap traversal (heap_reference_callback) */
2589*e82f7db8SAndroid Build Coastguard Worker static jint JNICALL
cbObjectCounterFromRef(jvmtiHeapReferenceKind reference_kind,const jvmtiHeapReferenceInfo * reference_info,jlong class_tag,jlong referrer_class_tag,jlong size,jlong * tag_ptr,jlong * referrer_tag_ptr,jint length,void * user_data)2590*e82f7db8SAndroid Build Coastguard Worker cbObjectCounterFromRef(jvmtiHeapReferenceKind reference_kind,
2591*e82f7db8SAndroid Build Coastguard Worker      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2592*e82f7db8SAndroid Build Coastguard Worker      jlong referrer_class_tag, jlong size,
2593*e82f7db8SAndroid Build Coastguard Worker      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2594*e82f7db8SAndroid Build Coastguard Worker {
2595*e82f7db8SAndroid Build Coastguard Worker     ClassCountData  *data;
2596*e82f7db8SAndroid Build Coastguard Worker     int              index;
2597*e82f7db8SAndroid Build Coastguard Worker     jlong            jindex;
2598*e82f7db8SAndroid Build Coastguard Worker     jlong            tag;
2599*e82f7db8SAndroid Build Coastguard Worker 
2600*e82f7db8SAndroid Build Coastguard Worker     /* Check data structure */
2601*e82f7db8SAndroid Build Coastguard Worker     data = (ClassCountData*)user_data;
2602*e82f7db8SAndroid Build Coastguard Worker     if (data == NULL) {
2603*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2604*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2605*e82f7db8SAndroid Build Coastguard Worker     }
2606*e82f7db8SAndroid Build Coastguard Worker 
2607*e82f7db8SAndroid Build Coastguard Worker     /* Classes with no class_tag should have been filtered out. */
2608*e82f7db8SAndroid Build Coastguard Worker     if ( class_tag == (jlong)0 ) {
2609*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_INTERNAL;
2610*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2611*e82f7db8SAndroid Build Coastguard Worker     }
2612*e82f7db8SAndroid Build Coastguard Worker 
2613*e82f7db8SAndroid Build Coastguard Worker     /* Class tag not one we really want (jclass not in supplied list) */
2614*e82f7db8SAndroid Build Coastguard Worker     if ( class_tag == data->negObjTag ) {
2615*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_OBJECTS;
2616*e82f7db8SAndroid Build Coastguard Worker     }
2617*e82f7db8SAndroid Build Coastguard Worker 
2618*e82f7db8SAndroid Build Coastguard Worker     /* If object tag is negative, just continue, we counted it */
2619*e82f7db8SAndroid Build Coastguard Worker     tag = (*tag_ptr);
2620*e82f7db8SAndroid Build Coastguard Worker     if ( tag < (jlong)0 ) {
2621*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_OBJECTS;
2622*e82f7db8SAndroid Build Coastguard Worker     }
2623*e82f7db8SAndroid Build Coastguard Worker 
2624*e82f7db8SAndroid Build Coastguard Worker     /* Tag the object with a negative value just so we don't count it again */
2625*e82f7db8SAndroid Build Coastguard Worker     if ( tag == (jlong)0 ) {
2626*e82f7db8SAndroid Build Coastguard Worker         /* This object had no tag value, so we give it the negObjTag value */
2627*e82f7db8SAndroid Build Coastguard Worker         (*tag_ptr) = data->negObjTag;
2628*e82f7db8SAndroid Build Coastguard Worker     } else {
2629*e82f7db8SAndroid Build Coastguard Worker         /* If this object had a positive tag value, it must be one of the
2630*e82f7db8SAndroid Build Coastguard Worker          *    jclass objects we tagged. We need to preserve the value of
2631*e82f7db8SAndroid Build Coastguard Worker          *    this tag for later objects that might have this as a class
2632*e82f7db8SAndroid Build Coastguard Worker          *    tag, so we just make the existing tag value negative.
2633*e82f7db8SAndroid Build Coastguard Worker          */
2634*e82f7db8SAndroid Build Coastguard Worker         (*tag_ptr) = -tag;
2635*e82f7db8SAndroid Build Coastguard Worker     }
2636*e82f7db8SAndroid Build Coastguard Worker 
2637*e82f7db8SAndroid Build Coastguard Worker     /* Absolute value of class tag is an index into the counts[] array */
2638*e82f7db8SAndroid Build Coastguard Worker     jindex = JLONG_ABS(class_tag);
2639*e82f7db8SAndroid Build Coastguard Worker     index = CLASSTAG2INDEX(jindex);
2640*e82f7db8SAndroid Build Coastguard Worker     if (index < 0 || index >= data->classCount) {
2641*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2642*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2643*e82f7db8SAndroid Build Coastguard Worker     }
2644*e82f7db8SAndroid Build Coastguard Worker 
2645*e82f7db8SAndroid Build Coastguard Worker     /* Bump instance count on this class */
2646*e82f7db8SAndroid Build Coastguard Worker     data->counts[index]++;
2647*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_VISIT_OBJECTS;
2648*e82f7db8SAndroid Build Coastguard Worker }
2649*e82f7db8SAndroid Build Coastguard Worker 
2650*e82f7db8SAndroid Build Coastguard Worker /* Callback for instance count heap traversal (heap_iteration_callback) */
2651*e82f7db8SAndroid Build Coastguard Worker static jint JNICALL
cbObjectCounter(jlong class_tag,jlong size,jlong * tag_ptr,jint length,void * user_data)2652*e82f7db8SAndroid Build Coastguard Worker cbObjectCounter(jlong class_tag, jlong size, jlong* tag_ptr, jint length,
2653*e82f7db8SAndroid Build Coastguard Worker                         void* user_data)
2654*e82f7db8SAndroid Build Coastguard Worker {
2655*e82f7db8SAndroid Build Coastguard Worker     ClassCountData  *data;
2656*e82f7db8SAndroid Build Coastguard Worker     int              index;
2657*e82f7db8SAndroid Build Coastguard Worker 
2658*e82f7db8SAndroid Build Coastguard Worker     /* Check data structure */
2659*e82f7db8SAndroid Build Coastguard Worker     data = (ClassCountData*)user_data;
2660*e82f7db8SAndroid Build Coastguard Worker     if (data == NULL) {
2661*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2662*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2663*e82f7db8SAndroid Build Coastguard Worker     }
2664*e82f7db8SAndroid Build Coastguard Worker 
2665*e82f7db8SAndroid Build Coastguard Worker     /* Classes with no tag should be filtered out. */
2666*e82f7db8SAndroid Build Coastguard Worker     if ( class_tag == (jlong)0 ) {
2667*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_INTERNAL;
2668*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2669*e82f7db8SAndroid Build Coastguard Worker     }
2670*e82f7db8SAndroid Build Coastguard Worker 
2671*e82f7db8SAndroid Build Coastguard Worker     /* Class tag is actually an index into data arrays */
2672*e82f7db8SAndroid Build Coastguard Worker     index = CLASSTAG2INDEX(class_tag);
2673*e82f7db8SAndroid Build Coastguard Worker     if (index < 0 || index >= data->classCount) {
2674*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2675*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2676*e82f7db8SAndroid Build Coastguard Worker     }
2677*e82f7db8SAndroid Build Coastguard Worker 
2678*e82f7db8SAndroid Build Coastguard Worker     /* Bump instance count on this class */
2679*e82f7db8SAndroid Build Coastguard Worker     data->counts[index]++;
2680*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_VISIT_OBJECTS;
2681*e82f7db8SAndroid Build Coastguard Worker }
2682*e82f7db8SAndroid Build Coastguard Worker 
2683*e82f7db8SAndroid Build Coastguard Worker /* Get instance counts for a set of classes */
2684*e82f7db8SAndroid Build Coastguard Worker jvmtiError
classInstanceCounts(jint classCount,jclass * classes,jlong * counts)2685*e82f7db8SAndroid Build Coastguard Worker classInstanceCounts(jint classCount, jclass *classes, jlong *counts)
2686*e82f7db8SAndroid Build Coastguard Worker {
2687*e82f7db8SAndroid Build Coastguard Worker     jvmtiHeapCallbacks heap_callbacks;
2688*e82f7db8SAndroid Build Coastguard Worker     ClassCountData     data;
2689*e82f7db8SAndroid Build Coastguard Worker     jvmtiError         error;
2690*e82f7db8SAndroid Build Coastguard Worker     jvmtiEnv          *jvmti;
2691*e82f7db8SAndroid Build Coastguard Worker     int                i;
2692*e82f7db8SAndroid Build Coastguard Worker 
2693*e82f7db8SAndroid Build Coastguard Worker     /* Check interface assumptions */
2694*e82f7db8SAndroid Build Coastguard Worker     if ( classes == NULL || classCount <= 0 || counts == NULL ) {
2695*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2696*e82f7db8SAndroid Build Coastguard Worker     }
2697*e82f7db8SAndroid Build Coastguard Worker 
2698*e82f7db8SAndroid Build Coastguard Worker     /* Initialize return information */
2699*e82f7db8SAndroid Build Coastguard Worker     for ( i = 0 ; i < classCount ; i++ ) {
2700*e82f7db8SAndroid Build Coastguard Worker         counts[i] = (jlong)0;
2701*e82f7db8SAndroid Build Coastguard Worker     }
2702*e82f7db8SAndroid Build Coastguard Worker 
2703*e82f7db8SAndroid Build Coastguard Worker     /* Get jvmti environment to use */
2704*e82f7db8SAndroid Build Coastguard Worker     jvmti = getSpecialJvmti();
2705*e82f7db8SAndroid Build Coastguard Worker     if ( jvmti == NULL ) {
2706*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INTERNAL;
2707*e82f7db8SAndroid Build Coastguard Worker     }
2708*e82f7db8SAndroid Build Coastguard Worker 
2709*e82f7db8SAndroid Build Coastguard Worker     /* Setup class data structure */
2710*e82f7db8SAndroid Build Coastguard Worker     data.error        = JVMTI_ERROR_NONE;
2711*e82f7db8SAndroid Build Coastguard Worker     data.classCount   = classCount;
2712*e82f7db8SAndroid Build Coastguard Worker     data.counts       = counts;
2713*e82f7db8SAndroid Build Coastguard Worker 
2714*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_ERROR_NONE;
2715*e82f7db8SAndroid Build Coastguard Worker     /* Set tags on classes, use index in classes[] as the tag value. */
2716*e82f7db8SAndroid Build Coastguard Worker     error             = JVMTI_ERROR_NONE;
2717*e82f7db8SAndroid Build Coastguard Worker     for ( i = 0 ; i < classCount ; i++ ) {
2718*e82f7db8SAndroid Build Coastguard Worker         if (classes[i] != NULL) {
2719*e82f7db8SAndroid Build Coastguard Worker             jlong tag;
2720*e82f7db8SAndroid Build Coastguard Worker 
2721*e82f7db8SAndroid Build Coastguard Worker             tag = INDEX2CLASSTAG(i);
2722*e82f7db8SAndroid Build Coastguard Worker             error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, classes[i], tag);
2723*e82f7db8SAndroid Build Coastguard Worker             if ( error != JVMTI_ERROR_NONE ) {
2724*e82f7db8SAndroid Build Coastguard Worker                 break;
2725*e82f7db8SAndroid Build Coastguard Worker             }
2726*e82f7db8SAndroid Build Coastguard Worker         }
2727*e82f7db8SAndroid Build Coastguard Worker     }
2728*e82f7db8SAndroid Build Coastguard Worker 
2729*e82f7db8SAndroid Build Coastguard Worker     /* Traverse heap, two ways to do this for instance counts. */
2730*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
2731*e82f7db8SAndroid Build Coastguard Worker 
2732*e82f7db8SAndroid Build Coastguard Worker         /* Clear out callbacks structure */
2733*e82f7db8SAndroid Build Coastguard Worker         (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2734*e82f7db8SAndroid Build Coastguard Worker 
2735*e82f7db8SAndroid Build Coastguard Worker         /* Check debug flags to see how to do this. */
2736*e82f7db8SAndroid Build Coastguard Worker         if ( (gdata->debugflags & USE_ITERATE_THROUGH_HEAP) == 0 ) {
2737*e82f7db8SAndroid Build Coastguard Worker 
2738*e82f7db8SAndroid Build Coastguard Worker             /* Using FollowReferences only gives us live objects, but we
2739*e82f7db8SAndroid Build Coastguard Worker              *   need to tag the objects to avoid counting them twice since
2740*e82f7db8SAndroid Build Coastguard Worker              *   the callback is per reference.
2741*e82f7db8SAndroid Build Coastguard Worker              *   The jclass objects have been tagged with their index in the
2742*e82f7db8SAndroid Build Coastguard Worker              *   supplied list, and that tag may flip to negative if it
2743*e82f7db8SAndroid Build Coastguard Worker              *   is also an object of interest.
2744*e82f7db8SAndroid Build Coastguard Worker              *   All other objects being counted that weren't in the
2745*e82f7db8SAndroid Build Coastguard Worker              *   supplied classes list will have a negative classCount
2746*e82f7db8SAndroid Build Coastguard Worker              *   tag value. So all objects counted will have negative tags.
2747*e82f7db8SAndroid Build Coastguard Worker              *   If the absolute tag value is an index in the supplied
2748*e82f7db8SAndroid Build Coastguard Worker              *   list, then it's one of the supplied classes.
2749*e82f7db8SAndroid Build Coastguard Worker              */
2750*e82f7db8SAndroid Build Coastguard Worker             data.negObjTag = -INDEX2CLASSTAG(classCount);
2751*e82f7db8SAndroid Build Coastguard Worker 
2752*e82f7db8SAndroid Build Coastguard Worker             /* Setup callbacks, only using object reference callback */
2753*e82f7db8SAndroid Build Coastguard Worker             heap_callbacks.heap_reference_callback = &cbObjectCounterFromRef;
2754*e82f7db8SAndroid Build Coastguard Worker 
2755*e82f7db8SAndroid Build Coastguard Worker             /* Follow references, no initiating object, tagged classes only */
2756*e82f7db8SAndroid Build Coastguard Worker             error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2757*e82f7db8SAndroid Build Coastguard Worker                           (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
2758*e82f7db8SAndroid Build Coastguard Worker                            NULL, NULL, &heap_callbacks, &data);
2759*e82f7db8SAndroid Build Coastguard Worker 
2760*e82f7db8SAndroid Build Coastguard Worker         } else {
2761*e82f7db8SAndroid Build Coastguard Worker 
2762*e82f7db8SAndroid Build Coastguard Worker             /* Using IterateThroughHeap means that we will visit each object
2763*e82f7db8SAndroid Build Coastguard Worker              *   once, so no special tag tricks here. Just simple counting.
2764*e82f7db8SAndroid Build Coastguard Worker              *   However in this case the object might not be live, so we do
2765*e82f7db8SAndroid Build Coastguard Worker              *   a GC beforehand to make sure we minimize this.
2766*e82f7db8SAndroid Build Coastguard Worker              */
2767*e82f7db8SAndroid Build Coastguard Worker 
2768*e82f7db8SAndroid Build Coastguard Worker             /* FIXUP: Need some kind of trigger here to avoid excessive GC's? */
2769*e82f7db8SAndroid Build Coastguard Worker             error = JVMTI_FUNC_PTR(jvmti,ForceGarbageCollection)(jvmti);
2770*e82f7db8SAndroid Build Coastguard Worker             if ( error != JVMTI_ERROR_NONE ) {
2771*e82f7db8SAndroid Build Coastguard Worker 
2772*e82f7db8SAndroid Build Coastguard Worker                 /* Setup callbacks, just need object callback */
2773*e82f7db8SAndroid Build Coastguard Worker                 heap_callbacks.heap_iteration_callback = &cbObjectCounter;
2774*e82f7db8SAndroid Build Coastguard Worker 
2775*e82f7db8SAndroid Build Coastguard Worker                 /* Iterate through entire heap, tagged classes only */
2776*e82f7db8SAndroid Build Coastguard Worker                 error = JVMTI_FUNC_PTR(jvmti,IterateThroughHeap)
2777*e82f7db8SAndroid Build Coastguard Worker                               (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
2778*e82f7db8SAndroid Build Coastguard Worker                                NULL, &heap_callbacks, &data);
2779*e82f7db8SAndroid Build Coastguard Worker 
2780*e82f7db8SAndroid Build Coastguard Worker             }
2781*e82f7db8SAndroid Build Coastguard Worker         }
2782*e82f7db8SAndroid Build Coastguard Worker 
2783*e82f7db8SAndroid Build Coastguard Worker         /* Use data error if needed */
2784*e82f7db8SAndroid Build Coastguard Worker         if ( error == JVMTI_ERROR_NONE ) {
2785*e82f7db8SAndroid Build Coastguard Worker             error = data.error;
2786*e82f7db8SAndroid Build Coastguard Worker         }
2787*e82f7db8SAndroid Build Coastguard Worker 
2788*e82f7db8SAndroid Build Coastguard Worker     }
2789*e82f7db8SAndroid Build Coastguard Worker 
2790*e82f7db8SAndroid Build Coastguard Worker     /* Dispose of any special jvmti environment */
2791*e82f7db8SAndroid Build Coastguard Worker     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2792*e82f7db8SAndroid Build Coastguard Worker     return error;
2793*e82f7db8SAndroid Build Coastguard Worker }
2794*e82f7db8SAndroid Build Coastguard Worker 
2795*e82f7db8SAndroid Build Coastguard Worker /* ********************************************************************* */
2796*e82f7db8SAndroid Build Coastguard Worker /* Referrers */
2797*e82f7db8SAndroid Build Coastguard Worker 
2798*e82f7db8SAndroid Build Coastguard Worker /* Structure to hold object referrer heap traversal data (arg user_data) */
2799*e82f7db8SAndroid Build Coastguard Worker typedef struct ReferrerData {
2800*e82f7db8SAndroid Build Coastguard Worker   int        refCount;
2801*e82f7db8SAndroid Build Coastguard Worker   int        maxObjects;
2802*e82f7db8SAndroid Build Coastguard Worker   jlong      refTag;
2803*e82f7db8SAndroid Build Coastguard Worker   jlong      objTag;
2804*e82f7db8SAndroid Build Coastguard Worker   jboolean   selfRef;
2805*e82f7db8SAndroid Build Coastguard Worker   jvmtiError error;
2806*e82f7db8SAndroid Build Coastguard Worker } ReferrerData;
2807*e82f7db8SAndroid Build Coastguard Worker 
2808*e82f7db8SAndroid Build Coastguard Worker /* Callback for referrers object tagging (heap_reference_callback). */
2809*e82f7db8SAndroid Build Coastguard Worker static jint JNICALL
cbObjectTagReferrer(jvmtiHeapReferenceKind reference_kind,const jvmtiHeapReferenceInfo * reference_info,jlong class_tag,jlong referrer_class_tag,jlong size,jlong * tag_ptr,jlong * referrer_tag_ptr,jint length,void * user_data)2810*e82f7db8SAndroid Build Coastguard Worker cbObjectTagReferrer(jvmtiHeapReferenceKind reference_kind,
2811*e82f7db8SAndroid Build Coastguard Worker      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2812*e82f7db8SAndroid Build Coastguard Worker      jlong referrer_class_tag, jlong size,
2813*e82f7db8SAndroid Build Coastguard Worker      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2814*e82f7db8SAndroid Build Coastguard Worker {
2815*e82f7db8SAndroid Build Coastguard Worker     ReferrerData  *data;
2816*e82f7db8SAndroid Build Coastguard Worker 
2817*e82f7db8SAndroid Build Coastguard Worker     /* Check data structure */
2818*e82f7db8SAndroid Build Coastguard Worker     data = (ReferrerData*)user_data;
2819*e82f7db8SAndroid Build Coastguard Worker     if (data == NULL) {
2820*e82f7db8SAndroid Build Coastguard Worker         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2821*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2822*e82f7db8SAndroid Build Coastguard Worker     }
2823*e82f7db8SAndroid Build Coastguard Worker 
2824*e82f7db8SAndroid Build Coastguard Worker     /* If we have tagged enough objects, just abort */
2825*e82f7db8SAndroid Build Coastguard Worker     if ( data->maxObjects != 0 && data->refCount >= data->maxObjects ) {
2826*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_ABORT;
2827*e82f7db8SAndroid Build Coastguard Worker     }
2828*e82f7db8SAndroid Build Coastguard Worker 
2829*e82f7db8SAndroid Build Coastguard Worker     /* If not of interest, just continue */
2830*e82f7db8SAndroid Build Coastguard Worker     if ( (*tag_ptr) != data->objTag ) {
2831*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_OBJECTS;
2832*e82f7db8SAndroid Build Coastguard Worker     }
2833*e82f7db8SAndroid Build Coastguard Worker 
2834*e82f7db8SAndroid Build Coastguard Worker     /* Self reference that we haven't counted? */
2835*e82f7db8SAndroid Build Coastguard Worker     if ( tag_ptr == referrer_tag_ptr ) {
2836*e82f7db8SAndroid Build Coastguard Worker         if ( data->selfRef == JNI_FALSE ) {
2837*e82f7db8SAndroid Build Coastguard Worker             data->selfRef = JNI_TRUE;
2838*e82f7db8SAndroid Build Coastguard Worker             data->refCount++;
2839*e82f7db8SAndroid Build Coastguard Worker         }
2840*e82f7db8SAndroid Build Coastguard Worker         return JVMTI_VISIT_OBJECTS;
2841*e82f7db8SAndroid Build Coastguard Worker     }
2842*e82f7db8SAndroid Build Coastguard Worker 
2843*e82f7db8SAndroid Build Coastguard Worker     /* If the referrer can be tagged, and hasn't been tagged, tag it */
2844*e82f7db8SAndroid Build Coastguard Worker     if ( referrer_tag_ptr != NULL ) {
2845*e82f7db8SAndroid Build Coastguard Worker         if ( (*referrer_tag_ptr) == (jlong)0 ) {
2846*e82f7db8SAndroid Build Coastguard Worker             *referrer_tag_ptr = data->refTag;
2847*e82f7db8SAndroid Build Coastguard Worker             data->refCount++;
2848*e82f7db8SAndroid Build Coastguard Worker         }
2849*e82f7db8SAndroid Build Coastguard Worker     }
2850*e82f7db8SAndroid Build Coastguard Worker     return JVMTI_VISIT_OBJECTS;
2851*e82f7db8SAndroid Build Coastguard Worker }
2852*e82f7db8SAndroid Build Coastguard Worker 
2853*e82f7db8SAndroid Build Coastguard Worker /* Heap traversal to find referrers of an object */
2854*e82f7db8SAndroid Build Coastguard Worker jvmtiError
objectReferrers(jobject obj,ObjectBatch * referrers,int maxObjects)2855*e82f7db8SAndroid Build Coastguard Worker objectReferrers(jobject obj, ObjectBatch *referrers, int maxObjects)
2856*e82f7db8SAndroid Build Coastguard Worker {
2857*e82f7db8SAndroid Build Coastguard Worker     jvmtiHeapCallbacks heap_callbacks;
2858*e82f7db8SAndroid Build Coastguard Worker     ReferrerData       data;
2859*e82f7db8SAndroid Build Coastguard Worker     jvmtiError         error;
2860*e82f7db8SAndroid Build Coastguard Worker     jvmtiEnv          *jvmti;
2861*e82f7db8SAndroid Build Coastguard Worker 
2862*e82f7db8SAndroid Build Coastguard Worker     /* Check interface assumptions */
2863*e82f7db8SAndroid Build Coastguard Worker     if (obj == NULL) {
2864*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INVALID_OBJECT;
2865*e82f7db8SAndroid Build Coastguard Worker     }
2866*e82f7db8SAndroid Build Coastguard Worker     if (referrers == NULL || maxObjects < 0 ) {
2867*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2868*e82f7db8SAndroid Build Coastguard Worker     }
2869*e82f7db8SAndroid Build Coastguard Worker 
2870*e82f7db8SAndroid Build Coastguard Worker     /* Initialize return information */
2871*e82f7db8SAndroid Build Coastguard Worker     referrers->count = 0;
2872*e82f7db8SAndroid Build Coastguard Worker     referrers->objects = NULL;
2873*e82f7db8SAndroid Build Coastguard Worker 
2874*e82f7db8SAndroid Build Coastguard Worker     /* Get jvmti environment to use */
2875*e82f7db8SAndroid Build Coastguard Worker     jvmti = getSpecialJvmti();
2876*e82f7db8SAndroid Build Coastguard Worker     if ( jvmti == NULL ) {
2877*e82f7db8SAndroid Build Coastguard Worker         return AGENT_ERROR_INTERNAL;
2878*e82f7db8SAndroid Build Coastguard Worker     }
2879*e82f7db8SAndroid Build Coastguard Worker 
2880*e82f7db8SAndroid Build Coastguard Worker     /* Fill in the data structure passed around the callbacks */
2881*e82f7db8SAndroid Build Coastguard Worker     data.refCount   = 0;
2882*e82f7db8SAndroid Build Coastguard Worker     data.maxObjects = maxObjects;
2883*e82f7db8SAndroid Build Coastguard Worker     data.objTag     = (jlong)1;
2884*e82f7db8SAndroid Build Coastguard Worker     data.refTag     = (jlong)2;
2885*e82f7db8SAndroid Build Coastguard Worker     data.selfRef    = JNI_FALSE;
2886*e82f7db8SAndroid Build Coastguard Worker     data.error      = JVMTI_ERROR_NONE;
2887*e82f7db8SAndroid Build Coastguard Worker 
2888*e82f7db8SAndroid Build Coastguard Worker     /* Tag the object of interest */
2889*e82f7db8SAndroid Build Coastguard Worker     error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.objTag);
2890*e82f7db8SAndroid Build Coastguard Worker 
2891*e82f7db8SAndroid Build Coastguard Worker     /* No need to go any further if we can't tag the object */
2892*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
2893*e82f7db8SAndroid Build Coastguard Worker 
2894*e82f7db8SAndroid Build Coastguard Worker         /* Clear out callbacks structure */
2895*e82f7db8SAndroid Build Coastguard Worker         (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2896*e82f7db8SAndroid Build Coastguard Worker 
2897*e82f7db8SAndroid Build Coastguard Worker         /* Setup callbacks we want */
2898*e82f7db8SAndroid Build Coastguard Worker         heap_callbacks.heap_reference_callback = &cbObjectTagReferrer;
2899*e82f7db8SAndroid Build Coastguard Worker 
2900*e82f7db8SAndroid Build Coastguard Worker         /* Follow references, no initiating object, all classes, 1 tagged objs */
2901*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2902*e82f7db8SAndroid Build Coastguard Worker                       (jvmti, JVMTI_HEAP_FILTER_UNTAGGED,
2903*e82f7db8SAndroid Build Coastguard Worker                        NULL, NULL, &heap_callbacks, &data);
2904*e82f7db8SAndroid Build Coastguard Worker 
2905*e82f7db8SAndroid Build Coastguard Worker         /* Use data error if needed */
2906*e82f7db8SAndroid Build Coastguard Worker         if ( error == JVMTI_ERROR_NONE ) {
2907*e82f7db8SAndroid Build Coastguard Worker             error = data.error;
2908*e82f7db8SAndroid Build Coastguard Worker         }
2909*e82f7db8SAndroid Build Coastguard Worker 
2910*e82f7db8SAndroid Build Coastguard Worker     }
2911*e82f7db8SAndroid Build Coastguard Worker 
2912*e82f7db8SAndroid Build Coastguard Worker     /* Watch out for self-reference */
2913*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE && data.selfRef == JNI_TRUE ) {
2914*e82f7db8SAndroid Build Coastguard Worker         /* Tag itself as a referer */
2915*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.refTag);
2916*e82f7db8SAndroid Build Coastguard Worker     }
2917*e82f7db8SAndroid Build Coastguard Worker 
2918*e82f7db8SAndroid Build Coastguard Worker     /* Get the jobjects for the tagged referrer objects.  */
2919*e82f7db8SAndroid Build Coastguard Worker     if ( error == JVMTI_ERROR_NONE ) {
2920*e82f7db8SAndroid Build Coastguard Worker         error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
2921*e82f7db8SAndroid Build Coastguard Worker                     (jvmti, 1, &(data.refTag), &(referrers->count),
2922*e82f7db8SAndroid Build Coastguard Worker                           &(referrers->objects), NULL);
2923*e82f7db8SAndroid Build Coastguard Worker         /* Verify we got the count we expected */
2924*e82f7db8SAndroid Build Coastguard Worker         if ( data.refCount != referrers->count ) {
2925*e82f7db8SAndroid Build Coastguard Worker             error = AGENT_ERROR_INTERNAL;
2926*e82f7db8SAndroid Build Coastguard Worker         }
2927*e82f7db8SAndroid Build Coastguard Worker     }
2928*e82f7db8SAndroid Build Coastguard Worker 
2929*e82f7db8SAndroid Build Coastguard Worker     /* Dispose of any special jvmti environment */
2930*e82f7db8SAndroid Build Coastguard Worker     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2931*e82f7db8SAndroid Build Coastguard Worker     return error;
2932*e82f7db8SAndroid Build Coastguard Worker }
2933