1 /*
  2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "classfile/javaClasses.inline.hpp"
 27 #include "prims/jvmtiExport.hpp"
 28 #include "prims/jvmtiExtensions.hpp"
 29 #include "prims/jvmtiThreadState.inline.hpp"
 30 #include "runtime/interfaceSupport.inline.hpp"
 31 #include "runtime/handles.inline.hpp"
 32 #include "runtime/jniHandles.inline.hpp"
 33 
 34 // the list of extension functions
 35 GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions;
 36 
 37 // the list of extension events
 38 GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events;
 39 
 40 
 41 /*
 42  * Extension Functions
 43  */
 44 static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, ...) {
 45   jboolean* enabled = NULL;
 46   va_list ap;
 47 
 48   va_start(ap, env);
 49   enabled = va_arg(ap, jboolean *);
 50   va_end(ap);
 51 
 52   if (enabled == NULL) {
 53     return JVMTI_ERROR_NULL_POINTER;
 54   }
 55   *enabled = (jboolean)ClassUnloading;
 56   return JVMTI_ERROR_NONE;
 57 }
 58 
 59 // Parameters: (jthread thread, jthread* vthread_ptr)
 60 static jvmtiError JNICALL GetVirtualThread(const jvmtiEnv* env, ...) {
 61   JvmtiEnv* jvmti_env = JvmtiEnv::JvmtiEnv_from_jvmti_env((jvmtiEnv*)env);
 62   if (jvmti_env->get_capabilities()->can_support_virtual_threads == 0) {
 63     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
 64   }
 65 
 66   JavaThread* current_thread = JavaThread::current();
 67   ResourceMark rm(current_thread);
 68   jthread thread = NULL;
 69   jthread* vthread_ptr = NULL;
 70   JavaThread* java_thread = NULL;
 71   oop cthread_oop = NULL;
 72   oop thread_oop = NULL;
 73   va_list ap;
 74 
 75   va_start(ap, env);
 76   thread = va_arg(ap, jthread);
 77   vthread_ptr = va_arg(ap, jthread*);
 78   va_end(ap);
 79 
 80   ThreadInVMfromNative tiv(current_thread);
 81   JvmtiVTMTDisabler vtmt_disabler;
 82   ThreadsListHandle tlh(current_thread);
 83 
 84   jvmtiError err;
 85 
 86   *vthread_ptr = NULL;
 87   if (thread == NULL) {
 88     java_thread = current_thread;
 89     cthread_oop = java_thread->threadObj();
 90   } else {
 91     err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &cthread_oop);
 92     if (err != JVMTI_ERROR_NONE) {
 93       return err;
 94     }
 95   }
 96   if (vthread_ptr == NULL) {
 97     return JVMTI_ERROR_NULL_POINTER;
 98   }
 99   if (cthread_oop == NULL || java_lang_VirtualThread::is_instance(cthread_oop)) {
100     return JVMTI_ERROR_INVALID_THREAD;
101   }
102 
103   JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
104   if (state == NULL) {
105     return JVMTI_ERROR_THREAD_NOT_ALIVE;
106   }
107   oop vthread_oop = java_thread->mounted_vthread();
108   if (!java_lang_VirtualThread::is_instance(vthread_oop)) { // not a virtual thread
109     vthread_oop = NULL;
110   }
111   *vthread_ptr = (jthread)JNIHandles::make_local(current_thread, vthread_oop);
112   return JVMTI_ERROR_NONE;
113 }
114 
115 // Parameters: (jthread vthread, jthread* thread_ptr)
116 static jvmtiError JNICALL GetCarrierThread(const jvmtiEnv* env, ...) {
117   JvmtiEnv* jvmti_env = JvmtiEnv::JvmtiEnv_from_jvmti_env((jvmtiEnv*)env);
118   if (jvmti_env->get_capabilities()->can_support_virtual_threads == 0) {
119     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
120   }
121 
122   JavaThread* current_thread = JavaThread::current();
123   HandleMark hm(current_thread);
124   jthread vthread = NULL;
125   jthread* thread_ptr = NULL;
126   va_list ap;
127 
128   va_start(ap, env);
129   vthread = va_arg(ap, jthread);
130   thread_ptr = va_arg(ap, jthread*);
131   va_end(ap);
132 
133   ThreadInVMfromNative tiv(current_thread);
134   JvmtiVTMTDisabler vtmt_disabler;
135 
136   ThreadsListHandle tlh(current_thread);
137   JavaThread* java_thread;
138   oop vthread_oop = NULL;
139   jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), vthread, &java_thread, &vthread_oop);
140   if (err != JVMTI_ERROR_NONE) {
141     // We got an error code so we don't have a JavaThread *, but
142     // only return an error from here if we didn't get a valid
143     // thread_oop.
144     // In a vthread case the cv_external_thread_to_JavaThread is expected to correctly set
145     // the thread_oop and return JVMTI_ERROR_INVALID_THREAD which we ignore here.
146     if (vthread_oop == NULL) {
147       return err;
148     }
149   }
150  
151   if (!java_lang_VirtualThread::is_instance(vthread_oop)) {
152     return JVMTI_ERROR_INVALID_THREAD;
153   }
154   if (thread_ptr == NULL) {
155       return JVMTI_ERROR_NULL_POINTER;
156   }
157   VThreadGetThreadClosure op(Handle(current_thread, vthread_oop), thread_ptr);
158   Handshake::execute(&op, &tlh, current_thread);
159   return op.result();
160 }
161 
162 // register extension functions and events. In this implementation we
163 // have a single extension function (to prove the API) that tests if class
164 // unloading is enabled or disabled. We also have a single extension event
165 // EXT_EVENT_CLASS_UNLOAD which is used to provide the JVMDI_EVENT_CLASS_UNLOAD
166 // event. The function and the event are registered here.
167 //
168 void JvmtiExtensions::register_extensions() {
169   _ext_functions = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiExtensionFunctionInfo*>(1, mtServiceability);
170   _ext_events = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiExtensionEventInfo*>(1, mtServiceability);
171 
172   // register our extension functions
173   static jvmtiParamInfo func_params0[] = {
174     { (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, JNI_FALSE }
175   };
176   static jvmtiParamInfo func_params1[] = {
177     { (char*)"GetVirtualThread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE },
178     { (char*)"GetVirtualThread", JVMTI_KIND_OUT, JVMTI_TYPE_JTHREAD, JNI_FALSE }
179   };
180   static jvmtiParamInfo func_params2[] = {
181     { (char*)"GetVirtualThread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE },
182     { (char*)"GetCarrierThread", JVMTI_KIND_OUT, JVMTI_TYPE_JTHREAD, JNI_FALSE }
183   };
184 
185   static jvmtiError errors[] = {
186     JVMTI_ERROR_MUST_POSSESS_CAPABILITY,
187     JVMTI_ERROR_INVALID_THREAD
188   };
189 
190   static jvmtiExtensionFunctionInfo ext_func0 = {
191     (jvmtiExtensionFunction)IsClassUnloadingEnabled,
192     (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled",
193     (char*)"Tell if class unloading is enabled (-noclassgc)",
194     sizeof(func_params0)/sizeof(func_params0[0]),
195     func_params0,
196     0,              // no non-universal errors
197     NULL
198   };
199 
200   static jvmtiExtensionFunctionInfo ext_func1 = {
201     (jvmtiExtensionFunction)GetVirtualThread,
202     (char*)"com.sun.hotspot.functions.GetVirtualThread",
203     (char*)"Get virtual thread executed on carrier thread",
204     sizeof(func_params1)/sizeof(func_params1[0]),
205     func_params1,
206     sizeof(errors)/sizeof(jvmtiError),   // non-universal errors
207     errors
208   };
209 
210   static jvmtiExtensionFunctionInfo ext_func2 = {
211     (jvmtiExtensionFunction)GetCarrierThread,
212     (char*)"com.sun.hotspot.functions.GetCarrierThread",
213     (char*)"Get carrier thread executing virtual thread",
214     sizeof(func_params2)/sizeof(func_params2[0]),
215     func_params2,
216     sizeof(errors)/sizeof(jvmtiError),   // non-universal errors
217     errors
218   };
219 
220   _ext_functions->append(&ext_func0);
221   _ext_functions->append(&ext_func1);
222   _ext_functions->append(&ext_func2);
223 
224   // register our extension event
225 
226   static jvmtiParamInfo class_unload_event_params[] = {
227     { (char*)"JNI Environment", JVMTI_KIND_IN_PTR, JVMTI_TYPE_JNIENV, JNI_FALSE },
228     { (char*)"Class", JVMTI_KIND_IN_PTR, JVMTI_TYPE_CCHAR, JNI_FALSE }
229   };
230   static jvmtiParamInfo virtual_thread_event_params[] = {
231     { (char*)"JNI Environment", JVMTI_KIND_IN_PTR, JVMTI_TYPE_JNIENV, JNI_FALSE },
232     { (char*)"Virtual Thread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE }
233   };
234 
235   static jvmtiExtensionEventInfo class_unload_ext_event = {
236     EXT_EVENT_CLASS_UNLOAD,
237     (char*)"com.sun.hotspot.events.ClassUnload",
238     (char*)"CLASS_UNLOAD event",
239     sizeof(class_unload_event_params)/sizeof(class_unload_event_params[0]),
240     class_unload_event_params
241   };
242   static jvmtiExtensionEventInfo virtual_thread_mount_ext_event = {
243     EXT_EVENT_VIRTUAL_THREAD_MOUNT,
244     (char*)"com.sun.hotspot.events.VirtualThreadMount",
245     (char*)"VIRTUAL_THREAD_MOUNT event",
246     sizeof(virtual_thread_event_params)/sizeof(virtual_thread_event_params[0]),
247     virtual_thread_event_params
248   };
249   static jvmtiExtensionEventInfo virtual_thread_unmount_ext_event = {
250     EXT_EVENT_VIRTUAL_THREAD_UNMOUNT,
251     (char*)"com.sun.hotspot.events.VirtualThreadUnmount",
252     (char*)"VIRTUAL_THREAD_UNMOUNT event",
253     sizeof(virtual_thread_event_params)/sizeof(virtual_thread_event_params[0]),
254     virtual_thread_event_params
255   };
256 
257   _ext_events->append(&class_unload_ext_event);
258   _ext_events->append(&virtual_thread_mount_ext_event);
259   _ext_events->append(&virtual_thread_unmount_ext_event);
260 }
261 
262 
263 // return the list of extension functions
264 
265 jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env,
266                                           jint* extension_count_ptr,
267                                           jvmtiExtensionFunctionInfo** extensions)
268 {
269   guarantee(_ext_functions != NULL, "registration not done");
270 
271   ResourceTracker rt(env);
272 
273   jvmtiExtensionFunctionInfo* ext_funcs;
274   jvmtiError err = rt.allocate(_ext_functions->length() *
275                                sizeof(jvmtiExtensionFunctionInfo),
276                                (unsigned char**)&ext_funcs);
277   if (err != JVMTI_ERROR_NONE) {
278     return err;
279   }
280 
281   for (int i=0; i<_ext_functions->length(); i++ ) {
282     ext_funcs[i].func = _ext_functions->at(i)->func;
283 
284     char *id = _ext_functions->at(i)->id;
285     err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id));
286     if (err != JVMTI_ERROR_NONE) {
287       return err;
288     }
289     strcpy(ext_funcs[i].id, id);
290 
291     char *desc = _ext_functions->at(i)->short_description;
292     err = rt.allocate(strlen(desc)+1,
293                       (unsigned char**)&(ext_funcs[i].short_description));
294     if (err != JVMTI_ERROR_NONE) {
295       return err;
296     }
297     strcpy(ext_funcs[i].short_description, desc);
298 
299     // params
300 
301     jint param_count = _ext_functions->at(i)->param_count;
302 
303     ext_funcs[i].param_count = param_count;
304     if (param_count == 0) {
305       ext_funcs[i].params = NULL;
306     } else {
307       err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
308                         (unsigned char**)&(ext_funcs[i].params));
309       if (err != JVMTI_ERROR_NONE) {
310         return err;
311       }
312       jvmtiParamInfo* src_params = _ext_functions->at(i)->params;
313       jvmtiParamInfo* dst_params = ext_funcs[i].params;
314 
315       for (int j=0; j<param_count; j++) {
316         err = rt.allocate(strlen(src_params[j].name)+1,
317                           (unsigned char**)&(dst_params[j].name));
318         if (err != JVMTI_ERROR_NONE) {
319           return err;
320         }
321         strcpy(dst_params[j].name, src_params[j].name);
322 
323         dst_params[j].kind = src_params[j].kind;
324         dst_params[j].base_type = src_params[j].base_type;
325         dst_params[j].null_ok = src_params[j].null_ok;
326       }
327     }
328 
329     // errors
330 
331     jint error_count = _ext_functions->at(i)->error_count;
332     ext_funcs[i].error_count = error_count;
333     if (error_count == 0) {
334       ext_funcs[i].errors = NULL;
335     } else {
336       err = rt.allocate(error_count*sizeof(jvmtiError),
337                         (unsigned char**)&(ext_funcs[i].errors));
338       if (err != JVMTI_ERROR_NONE) {
339         return err;
340       }
341       memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors,
342              error_count*sizeof(jvmtiError));
343     }
344   }
345 
346   *extension_count_ptr = _ext_functions->length();
347   *extensions = ext_funcs;
348   return JVMTI_ERROR_NONE;
349 }
350 
351 
352 // return the list of extension events
353 
354 jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env,
355                                        jint* extension_count_ptr,
356                                        jvmtiExtensionEventInfo** extensions)
357 {
358   guarantee(_ext_events != NULL, "registration not done");
359 
360   ResourceTracker rt(env);
361 
362   jvmtiExtensionEventInfo* ext_events;
363   jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo),
364                                (unsigned char**)&ext_events);
365   if (err != JVMTI_ERROR_NONE) {
366     return err;
367   }
368 
369   for (int i=0; i<_ext_events->length(); i++ ) {
370     ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index;
371 
372     char *id = _ext_events->at(i)->id;
373     err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id));
374     if (err != JVMTI_ERROR_NONE) {
375       return err;
376     }
377     strcpy(ext_events[i].id, id);
378 
379     char *desc = _ext_events->at(i)->short_description;
380     err = rt.allocate(strlen(desc)+1,
381                       (unsigned char**)&(ext_events[i].short_description));
382     if (err != JVMTI_ERROR_NONE) {
383       return err;
384     }
385     strcpy(ext_events[i].short_description, desc);
386 
387     // params
388 
389     jint param_count = _ext_events->at(i)->param_count;
390 
391     ext_events[i].param_count = param_count;
392     if (param_count == 0) {
393       ext_events[i].params = NULL;
394     } else {
395       err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
396                         (unsigned char**)&(ext_events[i].params));
397       if (err != JVMTI_ERROR_NONE) {
398         return err;
399       }
400       jvmtiParamInfo* src_params = _ext_events->at(i)->params;
401       jvmtiParamInfo* dst_params = ext_events[i].params;
402 
403       for (int j=0; j<param_count; j++) {
404         err = rt.allocate(strlen(src_params[j].name)+1,
405                           (unsigned char**)&(dst_params[j].name));
406         if (err != JVMTI_ERROR_NONE) {
407           return err;
408         }
409         strcpy(dst_params[j].name, src_params[j].name);
410 
411         dst_params[j].kind = src_params[j].kind;
412         dst_params[j].base_type = src_params[j].base_type;
413         dst_params[j].null_ok = src_params[j].null_ok;
414       }
415     }
416   }
417 
418   *extension_count_ptr = _ext_events->length();
419   *extensions = ext_events;
420   return JVMTI_ERROR_NONE;
421 }
422 
423 // set callback for an extension event and enable/disable it.
424 
425 jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env,
426                                                jint extension_event_index,
427                                                jvmtiExtensionEvent callback)
428 {
429   guarantee(_ext_events != NULL, "registration not done");
430 
431   jvmtiExtensionEventInfo* event = NULL;
432 
433   // if there are extension events registered then validate that the
434   // extension_event_index matches one of the registered events.
435   if (_ext_events != NULL) {
436     for (int i=0; i<_ext_events->length(); i++ ) {
437       if (_ext_events->at(i)->extension_event_index == extension_event_index) {
438          event = _ext_events->at(i);
439          break;
440       }
441     }
442   }
443 
444   // invalid event index
445   if (event == NULL) {
446     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
447   }
448 
449   JvmtiEventController::set_extension_event_callback(env, extension_event_index,
450                                                      callback);
451 
452   return JVMTI_ERROR_NONE;
453 }