src/share/vm/jfr/jni/jfrJavaSupport.cpp

Mon, 29 Jun 2020 21:30:26 +0100

author
andrew
date
Mon, 29 Jun 2020 21:30:26 +0100
changeset 9949
fb74ae591209
parent 9944
26d1803768c7
parent 9925
30fb8c8cceb9
child 9986
85e682d8ab91
permissions
-rw-r--r--

Merge

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #include "precompiled.hpp"
apetushkov@9858 26 #include "jni.h"
apetushkov@9858 27 #include "classfile/javaClasses.hpp"
apetushkov@9858 28 #include "classfile/symbolTable.hpp"
apetushkov@9858 29 #include "classfile/systemDictionary.hpp"
apetushkov@9858 30 #include "classfile/vmSymbols.hpp"
apetushkov@9858 31 #include "jfr/jni/jfrJavaCall.hpp"
apetushkov@9858 32 #include "jfr/jni/jfrJavaSupport.hpp"
apetushkov@9858 33 #include "jfr/support/jfrThreadId.hpp"
apetushkov@9858 34 #include "memory/resourceArea.hpp"
apetushkov@9858 35 #include "oops/instanceOop.hpp"
apetushkov@9858 36 #include "oops/oop.inline.hpp"
apetushkov@9858 37 #include "oops/objArrayKlass.hpp"
apetushkov@9858 38 #include "oops/objArrayOop.hpp"
apetushkov@9858 39 #include "runtime/handles.inline.hpp"
apetushkov@9858 40 #include "runtime/fieldDescriptor.hpp"
apetushkov@9858 41 #include "runtime/java.hpp"
apetushkov@9858 42 #include "runtime/jniHandles.hpp"
apetushkov@9858 43 #include "runtime/synchronizer.hpp"
apetushkov@9858 44 #include "runtime/thread.inline.hpp"
apetushkov@9858 45 //#include "runtime/threadSMR.hpp"
apetushkov@9858 46
apetushkov@9858 47 #ifdef ASSERT
apetushkov@9858 48 void JfrJavaSupport::check_java_thread_in_vm(Thread* t) {
apetushkov@9858 49 assert(t != NULL, "invariant");
apetushkov@9858 50 assert(t->is_Java_thread(), "invariant");
apetushkov@9858 51 assert(((JavaThread*)t)->thread_state() == _thread_in_vm, "invariant");
apetushkov@9858 52 }
apetushkov@9858 53
apetushkov@9858 54 void JfrJavaSupport::check_java_thread_in_native(Thread* t) {
apetushkov@9858 55 assert(t != NULL, "invariant");
apetushkov@9858 56 assert(t->is_Java_thread(), "invariant");
apetushkov@9858 57 assert(((JavaThread*)t)->thread_state() == _thread_in_native, "invariant");
apetushkov@9858 58 }
apetushkov@9858 59 #endif
apetushkov@9858 60
apetushkov@9858 61 /*
apetushkov@9858 62 * Handles and references
apetushkov@9858 63 */
apetushkov@9858 64 jobject JfrJavaSupport::local_jni_handle(const oop obj, Thread* t) {
apetushkov@9858 65 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 66 return t->active_handles()->allocate_handle(obj);
apetushkov@9858 67 }
apetushkov@9858 68
apetushkov@9858 69 jobject JfrJavaSupport::local_jni_handle(const jobject handle, Thread* t) {
apetushkov@9858 70 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 71 const oop obj = JNIHandles::resolve(handle);
apetushkov@9858 72 return obj == NULL ? NULL : local_jni_handle(obj, t);
apetushkov@9858 73 }
apetushkov@9858 74
apetushkov@9858 75 void JfrJavaSupport::destroy_local_jni_handle(jobject handle) {
apetushkov@9858 76 JNIHandles::destroy_local(handle);
apetushkov@9858 77 }
apetushkov@9858 78
apetushkov@9858 79 jobject JfrJavaSupport::global_jni_handle(const oop obj, Thread* t) {
apetushkov@9858 80 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 81 HandleMark hm(t);
apetushkov@9858 82 return JNIHandles::make_global(Handle(t, obj));
apetushkov@9858 83 }
apetushkov@9858 84
apetushkov@9858 85 jobject JfrJavaSupport::global_jni_handle(const jobject handle, Thread* t) {
apetushkov@9858 86 const oop obj = JNIHandles::resolve(handle);
apetushkov@9858 87 return obj == NULL ? NULL : global_jni_handle(obj, t);
apetushkov@9858 88 }
apetushkov@9858 89
apetushkov@9858 90 void JfrJavaSupport::destroy_global_jni_handle(const jobject handle) {
apetushkov@9858 91 JNIHandles::destroy_global(handle);
apetushkov@9858 92 }
apetushkov@9858 93
apetushkov@9858 94 oop JfrJavaSupport::resolve_non_null(jobject obj) {
apetushkov@9858 95 return JNIHandles::resolve_non_null(obj);
apetushkov@9858 96 }
apetushkov@9858 97
apetushkov@9858 98 /*
apetushkov@9858 99 * Method invocation
apetushkov@9858 100 */
apetushkov@9858 101 void JfrJavaSupport::call_static(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 102 JfrJavaCall::call_static(args, THREAD);
apetushkov@9858 103 }
apetushkov@9858 104
apetushkov@9858 105 void JfrJavaSupport::call_special(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 106 JfrJavaCall::call_special(args, THREAD);
apetushkov@9858 107 }
apetushkov@9858 108
apetushkov@9858 109 void JfrJavaSupport::call_virtual(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 110 JfrJavaCall::call_virtual(args, THREAD);
apetushkov@9858 111 }
apetushkov@9858 112
apetushkov@9858 113 void JfrJavaSupport::notify_all(jobject object, TRAPS) {
apetushkov@9858 114 assert(object != NULL, "invariant");
apetushkov@9858 115 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 116 HandleMark hm(THREAD);
apetushkov@9858 117 Handle h_obj(THREAD, resolve_non_null(object));
apetushkov@9858 118 assert(h_obj.not_null(), "invariant");
apetushkov@9858 119 ObjectSynchronizer::jni_enter(h_obj, THREAD);
apetushkov@9858 120 ObjectSynchronizer::notifyall(h_obj, THREAD);
apetushkov@9858 121 ObjectSynchronizer::jni_exit(h_obj(), THREAD);
apetushkov@9858 122 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 123 }
apetushkov@9858 124
apetushkov@9858 125 /*
apetushkov@9858 126 * Object construction
apetushkov@9858 127 */
apetushkov@9858 128 static void object_construction(JfrJavaArguments* args, JavaValue* result, InstanceKlass* klass, TRAPS) {
apetushkov@9858 129 assert(args != NULL, "invariant");
apetushkov@9858 130 assert(result != NULL, "invariant");
apetushkov@9858 131 assert(klass != NULL, "invariant");
apetushkov@9858 132 assert(klass->is_initialized(), "invariant");
apetushkov@9858 133
apetushkov@9858 134 HandleMark hm(THREAD);
apetushkov@9858 135 instanceOop obj = klass->allocate_instance(CHECK);
apetushkov@9858 136 instanceHandle h_obj(THREAD, obj);
apetushkov@9858 137 assert(h_obj.not_null(), "invariant");
apetushkov@9858 138 args->set_receiver(h_obj);
apetushkov@9858 139 result->set_type(T_VOID); // constructor result type
apetushkov@9858 140 JfrJavaSupport::call_special(args, CHECK);
apetushkov@9858 141 result->set_type(T_OBJECT); // set back to original result type
apetushkov@9858 142 result->set_jobject((jobject)h_obj());
apetushkov@9858 143 }
apetushkov@9858 144
apetushkov@9858 145 static void array_construction(JfrJavaArguments* args, JavaValue* result, InstanceKlass* klass, int array_length, TRAPS) {
apetushkov@9858 146 assert(args != NULL, "invariant");
apetushkov@9858 147 assert(result != NULL, "invariant");
apetushkov@9858 148 assert(klass != NULL, "invariant");
apetushkov@9858 149 assert(klass->is_initialized(), "invariant");
apetushkov@9858 150
apetushkov@9858 151 Klass* const ak = klass->array_klass(THREAD);
apetushkov@9858 152 ObjArrayKlass::cast(ak)->initialize(THREAD);
apetushkov@9858 153 HandleMark hm(THREAD);
apetushkov@9858 154 objArrayOop arr = ObjArrayKlass::cast(ak)->allocate(array_length, CHECK);
apetushkov@9858 155 result->set_jobject((jobject)arr);
apetushkov@9858 156 }
apetushkov@9858 157
apetushkov@9858 158 static void create_object(JfrJavaArguments* args, JavaValue* result, TRAPS) {
apetushkov@9858 159 assert(args != NULL, "invariant");
apetushkov@9858 160 assert(result != NULL, "invariant");
apetushkov@9858 161 assert(result->get_type() == T_OBJECT, "invariant");
apetushkov@9858 162 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 163
apetushkov@9858 164 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass());
apetushkov@9858 165 klass->initialize(CHECK);
apetushkov@9858 166
apetushkov@9858 167 const int array_length = args->array_length();
apetushkov@9858 168
egahlin@9883 169 if (array_length >= 0) {
apetushkov@9858 170 array_construction(args, result, klass, array_length, CHECK);
apetushkov@9858 171 } else {
apetushkov@9858 172 object_construction(args, result, klass, THREAD);
apetushkov@9858 173 }
apetushkov@9858 174 }
apetushkov@9858 175
apetushkov@9858 176 static void handle_result(JavaValue* result, bool global_ref, Thread* t) {
apetushkov@9858 177 assert(result != NULL, "invariant");
apetushkov@9858 178 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(t));
apetushkov@9858 179 const oop result_oop = (const oop)result->get_jobject();
apetushkov@9858 180 if (result_oop == NULL) {
apetushkov@9858 181 return;
apetushkov@9858 182 }
apetushkov@9858 183 result->set_jobject(global_ref ?
apetushkov@9858 184 JfrJavaSupport::global_jni_handle(result_oop, t) :
apetushkov@9858 185 JfrJavaSupport::local_jni_handle(result_oop, t));
apetushkov@9858 186 }
apetushkov@9858 187
apetushkov@9858 188 void JfrJavaSupport::new_object(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 189 assert(args != NULL, "invariant");
apetushkov@9858 190 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 191 create_object(args, args->result(), THREAD);
apetushkov@9858 192 }
apetushkov@9858 193
apetushkov@9858 194 void JfrJavaSupport::new_object_local_ref(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 195 assert(args != NULL, "invariant");
apetushkov@9858 196 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 197 JavaValue* const result = args->result();
apetushkov@9858 198 assert(result != NULL, "invariant");
apetushkov@9858 199 create_object(args, result, CHECK);
apetushkov@9858 200 handle_result(result, false, THREAD);
apetushkov@9858 201 }
apetushkov@9858 202
apetushkov@9858 203 void JfrJavaSupport::new_object_global_ref(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 204 assert(args != NULL, "invariant");
apetushkov@9858 205 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 206 JavaValue* const result = args->result();
apetushkov@9858 207 assert(result != NULL, "invariant");
apetushkov@9858 208 create_object(args, result, CHECK);
apetushkov@9858 209 handle_result(result, true, THREAD);
apetushkov@9858 210 }
apetushkov@9858 211
apetushkov@9858 212 jstring JfrJavaSupport::new_string(const char* c_str, TRAPS) {
apetushkov@9858 213 assert(c_str != NULL, "invariant");
apetushkov@9858 214 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 215 const oop result = java_lang_String::create_oop_from_str(c_str, THREAD);
apetushkov@9858 216 return (jstring)local_jni_handle(result, THREAD);
apetushkov@9858 217 }
apetushkov@9858 218
apetushkov@9858 219 jobjectArray JfrJavaSupport::new_string_array(int length, TRAPS) {
apetushkov@9858 220 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 221 JavaValue result(T_OBJECT);
apetushkov@9858 222 JfrJavaArguments args(&result, "java/lang/String", "<init>", "()V", CHECK_NULL);
apetushkov@9858 223 args.set_array_length(length);
apetushkov@9858 224 new_object_local_ref(&args, THREAD);
apetushkov@9858 225 return (jobjectArray)args.result()->get_jobject();
apetushkov@9858 226 }
apetushkov@9858 227
apetushkov@9858 228 jobject JfrJavaSupport::new_java_lang_Boolean(bool value, TRAPS) {
apetushkov@9858 229 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 230 JavaValue result(T_OBJECT);
apetushkov@9858 231 JfrJavaArguments args(&result, "java/lang/Boolean", "<init>", "(Z)V", CHECK_NULL);
apetushkov@9858 232 args.push_int(value ? (jint)JNI_TRUE : (jint)JNI_FALSE);
apetushkov@9858 233 new_object_local_ref(&args, THREAD);
apetushkov@9858 234 return args.result()->get_jobject();
apetushkov@9858 235 }
apetushkov@9858 236
apetushkov@9858 237 jobject JfrJavaSupport::new_java_lang_Integer(jint value, TRAPS) {
apetushkov@9858 238 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 239 JavaValue result(T_OBJECT);
apetushkov@9858 240 JfrJavaArguments args(&result, "java/lang/Integer", "<init>", "(I)V", CHECK_NULL);
apetushkov@9858 241 args.push_int(value);
apetushkov@9858 242 new_object_local_ref(&args, THREAD);
apetushkov@9858 243 return args.result()->get_jobject();
apetushkov@9858 244 }
apetushkov@9858 245
apetushkov@9858 246 jobject JfrJavaSupport::new_java_lang_Long(jlong value, TRAPS) {
apetushkov@9858 247 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 248 JavaValue result(T_OBJECT);
apetushkov@9858 249 JfrJavaArguments args(&result, "java/lang/Long", "<init>", "(J)V", CHECK_NULL);
apetushkov@9858 250 args.push_long(value);
apetushkov@9858 251 new_object_local_ref(&args, THREAD);
apetushkov@9858 252 return args.result()->get_jobject();
apetushkov@9858 253 }
apetushkov@9858 254
apetushkov@9858 255 void JfrJavaSupport::set_array_element(jobjectArray arr, jobject element, int index, Thread* t) {
apetushkov@9858 256 assert(arr != NULL, "invariant");
apetushkov@9858 257 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 258 HandleMark hm(t);
apetushkov@9858 259 objArrayHandle a(t, (objArrayOop)resolve_non_null(arr));
apetushkov@9858 260 a->obj_at_put(index, resolve_non_null(element));
apetushkov@9858 261 }
apetushkov@9858 262
apetushkov@9858 263 /*
apetushkov@9858 264 * Field access
apetushkov@9858 265 */
apetushkov@9858 266 static void write_int_field(const Handle& h_oop, fieldDescriptor* fd, jint value) {
apetushkov@9858 267 assert(h_oop.not_null(), "invariant");
apetushkov@9858 268 assert(fd != NULL, "invariant");
apetushkov@9858 269 h_oop->int_field_put(fd->offset(), value);
apetushkov@9858 270 }
apetushkov@9858 271
apetushkov@9858 272 static void write_float_field(const Handle& h_oop, fieldDescriptor* fd, jfloat value) {
apetushkov@9858 273 assert(h_oop.not_null(), "invariant");
apetushkov@9858 274 assert(fd != NULL, "invariant");
apetushkov@9858 275 h_oop->float_field_put(fd->offset(), value);
apetushkov@9858 276 }
apetushkov@9858 277
apetushkov@9858 278 static void write_double_field(const Handle& h_oop, fieldDescriptor* fd, jdouble value) {
apetushkov@9858 279 assert(h_oop.not_null(), "invariant");
apetushkov@9858 280 assert(fd != NULL, "invariant");
apetushkov@9858 281 h_oop->double_field_put(fd->offset(), value);
apetushkov@9858 282 }
apetushkov@9858 283
apetushkov@9858 284 static void write_long_field(const Handle& h_oop, fieldDescriptor* fd, jlong value) {
apetushkov@9858 285 assert(h_oop.not_null(), "invariant");
apetushkov@9858 286 assert(fd != NULL, "invariant");
apetushkov@9858 287 h_oop->long_field_put(fd->offset(), value);
apetushkov@9858 288 }
apetushkov@9858 289
apetushkov@9858 290 static void write_oop_field(const Handle& h_oop, fieldDescriptor* fd, const oop value) {
apetushkov@9858 291 assert(h_oop.not_null(), "invariant");
apetushkov@9858 292 assert(fd != NULL, "invariant");
apetushkov@9858 293 h_oop->obj_field_put(fd->offset(), value);
apetushkov@9858 294 }
apetushkov@9858 295
apetushkov@9858 296 static void write_specialized_field(JfrJavaArguments* args, const Handle& h_oop, fieldDescriptor* fd, bool static_field) {
apetushkov@9858 297 assert(args != NULL, "invariant");
apetushkov@9858 298 assert(h_oop.not_null(), "invariant");
apetushkov@9858 299 assert(fd != NULL, "invariant");
apetushkov@9858 300 assert(fd->offset() > 0, "invariant");
apetushkov@9858 301 assert(args->length() >= 1, "invariant");
apetushkov@9858 302
apetushkov@9858 303 // attempt must set a real value
apetushkov@9858 304 assert(args->param(1).get_type() != T_VOID, "invariant");
apetushkov@9858 305
apetushkov@9858 306 switch(fd->field_type()) {
apetushkov@9858 307 case T_BOOLEAN:
apetushkov@9858 308 case T_CHAR:
apetushkov@9858 309 case T_SHORT:
apetushkov@9858 310 case T_INT:
apetushkov@9858 311 write_int_field(h_oop, fd, args->param(1).get_jint());
apetushkov@9858 312 break;
apetushkov@9858 313 case T_FLOAT:
apetushkov@9858 314 write_float_field(h_oop, fd, args->param(1).get_jfloat());
apetushkov@9858 315 break;
apetushkov@9858 316 case T_DOUBLE:
apetushkov@9858 317 write_double_field(h_oop, fd, args->param(1).get_jdouble());
apetushkov@9858 318 break;
apetushkov@9858 319 case T_LONG:
apetushkov@9858 320 write_long_field(h_oop, fd, args->param(1).get_jlong());
apetushkov@9858 321 break;
apetushkov@9858 322 case T_OBJECT:
apetushkov@9858 323 write_oop_field(h_oop, fd, (oop)args->param(1).get_jobject());
apetushkov@9858 324 break;
apetushkov@9858 325 case T_ADDRESS:
apetushkov@9858 326 write_oop_field(h_oop, fd, JfrJavaSupport::resolve_non_null(args->param(1).get_jobject()));
apetushkov@9858 327 break;
apetushkov@9858 328 default:
apetushkov@9858 329 ShouldNotReachHere();
apetushkov@9858 330 }
apetushkov@9858 331 }
apetushkov@9858 332
apetushkov@9858 333 static void read_specialized_field(JavaValue* result, const Handle& h_oop, fieldDescriptor* fd) {
apetushkov@9858 334 assert(result != NULL, "invariant");
apetushkov@9858 335 assert(h_oop.not_null(), "invariant");
apetushkov@9858 336 assert(fd != NULL, "invariant");
apetushkov@9858 337 assert(fd->offset() > 0, "invariant");
apetushkov@9858 338
apetushkov@9858 339 switch(fd->field_type()) {
apetushkov@9858 340 case T_BOOLEAN:
apetushkov@9858 341 case T_CHAR:
apetushkov@9858 342 case T_SHORT:
apetushkov@9858 343 case T_INT:
apetushkov@9858 344 result->set_jint(h_oop->int_field(fd->offset()));
apetushkov@9858 345 break;
apetushkov@9858 346 case T_FLOAT:
apetushkov@9858 347 result->set_jfloat(h_oop->float_field(fd->offset()));
apetushkov@9858 348 break;
apetushkov@9858 349 case T_DOUBLE:
apetushkov@9858 350 result->set_jdouble(h_oop->double_field(fd->offset()));
apetushkov@9858 351 break;
apetushkov@9858 352 case T_LONG:
apetushkov@9858 353 result->set_jlong(h_oop->long_field(fd->offset()));
apetushkov@9858 354 break;
apetushkov@9858 355 case T_OBJECT:
apetushkov@9858 356 result->set_jobject((jobject)h_oop->obj_field(fd->offset()));
apetushkov@9858 357 break;
apetushkov@9858 358 default:
apetushkov@9858 359 ShouldNotReachHere();
apetushkov@9858 360 }
apetushkov@9858 361 }
apetushkov@9858 362
apetushkov@9858 363 static bool find_field(InstanceKlass* ik,
apetushkov@9858 364 Symbol* name_symbol,
apetushkov@9858 365 Symbol* signature_symbol,
apetushkov@9858 366 fieldDescriptor* fd,
apetushkov@9858 367 bool is_static = false,
apetushkov@9858 368 bool allow_super = false) {
apetushkov@9858 369 if (allow_super || is_static) {
apetushkov@9858 370 return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL;
apetushkov@9858 371 }
apetushkov@9858 372 return ik->find_local_field(name_symbol, signature_symbol, fd);
apetushkov@9858 373 }
apetushkov@9858 374
apetushkov@9858 375 static void lookup_field(JfrJavaArguments* args, InstanceKlass* klass, fieldDescriptor* fd, bool static_field) {
apetushkov@9858 376 assert(args != NULL, "invariant");
apetushkov@9858 377 assert(klass != NULL, "invariant");
apetushkov@9858 378 assert(klass->is_initialized(), "invariant");
apetushkov@9858 379 assert(fd != NULL, "invariant");
apetushkov@9858 380 find_field(klass, args->name(), args->signature(), fd, static_field, true);
apetushkov@9858 381 }
apetushkov@9858 382
apetushkov@9858 383 static void read_field(JfrJavaArguments* args, JavaValue* result, TRAPS) {
apetushkov@9858 384 assert(args != NULL, "invariant");
apetushkov@9858 385 assert(result != NULL, "invariant");
apetushkov@9858 386 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 387
apetushkov@9858 388 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass());
apetushkov@9858 389 klass->initialize(CHECK);
apetushkov@9858 390 const bool static_field = !args->has_receiver();
apetushkov@9858 391 fieldDescriptor fd;
apetushkov@9858 392 lookup_field(args, klass, &fd, static_field);
apetushkov@9858 393 assert(fd.offset() > 0, "invariant");
apetushkov@9858 394
apetushkov@9858 395 HandleMark hm(THREAD);
apetushkov@9858 396 Handle h_oop(static_field ? Handle(THREAD, klass->java_mirror()) : Handle(THREAD, args->receiver()));
apetushkov@9858 397 read_specialized_field(result, h_oop, &fd);
apetushkov@9858 398 }
apetushkov@9858 399
apetushkov@9858 400 static void write_field(JfrJavaArguments* args, JavaValue* result, TRAPS) {
apetushkov@9858 401 assert(args != NULL, "invariant");
apetushkov@9858 402 assert(result != NULL, "invariant");
apetushkov@9858 403 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 404
apetushkov@9858 405 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass());
apetushkov@9858 406 klass->initialize(CHECK);
apetushkov@9858 407
apetushkov@9858 408 const bool static_field = !args->has_receiver();
apetushkov@9858 409 fieldDescriptor fd;
apetushkov@9858 410 lookup_field(args, klass, &fd, static_field);
apetushkov@9858 411 assert(fd.offset() > 0, "invariant");
apetushkov@9858 412
apetushkov@9858 413 HandleMark hm(THREAD);
apetushkov@9858 414 Handle h_oop(static_field ? Handle(THREAD, klass->java_mirror()) : Handle(THREAD, args->receiver()));
apetushkov@9858 415 write_specialized_field(args, h_oop, &fd, static_field);
apetushkov@9858 416 }
apetushkov@9858 417
apetushkov@9858 418 void JfrJavaSupport::set_field(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 419 assert(args != NULL, "invariant");
apetushkov@9858 420 write_field(args, args->result(), THREAD);
apetushkov@9858 421 }
apetushkov@9858 422
apetushkov@9858 423 void JfrJavaSupport::get_field(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 424 assert(args != NULL, "invariant");
apetushkov@9858 425 read_field(args, args->result(), THREAD);
apetushkov@9858 426 }
apetushkov@9858 427
apetushkov@9858 428 void JfrJavaSupport::get_field_local_ref(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 429 assert(args != NULL, "invariant");
apetushkov@9858 430 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 431
apetushkov@9858 432 JavaValue* const result = args->result();
apetushkov@9858 433 assert(result != NULL, "invariant");
apetushkov@9858 434 assert(result->get_type() == T_OBJECT, "invariant");
apetushkov@9858 435
apetushkov@9858 436 read_field(args, result, CHECK);
apetushkov@9858 437 const oop obj = (const oop)result->get_jobject();
apetushkov@9858 438
apetushkov@9858 439 if (obj != NULL) {
apetushkov@9858 440 result->set_jobject(local_jni_handle(obj, THREAD));
apetushkov@9858 441 }
apetushkov@9858 442 }
apetushkov@9858 443
apetushkov@9858 444 void JfrJavaSupport::get_field_global_ref(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 445 assert(args != NULL, "invariant");
apetushkov@9858 446 DEBUG_ONLY(check_java_thread_in_vm(THREAD));
apetushkov@9858 447
apetushkov@9858 448 JavaValue* const result = args->result();
apetushkov@9858 449 assert(result != NULL, "invariant");
apetushkov@9858 450 assert(result->get_type() == T_OBJECT, "invariant");
apetushkov@9858 451 read_field(args, result, CHECK);
apetushkov@9858 452 const oop obj = (const oop)result->get_jobject();
apetushkov@9858 453 if (obj != NULL) {
apetushkov@9858 454 result->set_jobject(global_jni_handle(obj, THREAD));
apetushkov@9858 455 }
apetushkov@9858 456 }
apetushkov@9858 457
apetushkov@9858 458 /*
apetushkov@9858 459 * Misc
apetushkov@9858 460 */
apetushkov@9858 461 Klass* JfrJavaSupport::klass(const jobject handle) {
apetushkov@9858 462 const oop obj = resolve_non_null(handle);
apetushkov@9858 463 assert(obj != NULL, "invariant");
apetushkov@9858 464 return obj->klass();
apetushkov@9858 465 }
apetushkov@9858 466
apetushkov@9858 467 // caller needs ResourceMark
apetushkov@9858 468 const char* JfrJavaSupport::c_str(jstring string, Thread* t) {
apetushkov@9858 469 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 470 if (string == NULL) {
apetushkov@9858 471 return NULL;
apetushkov@9858 472 }
apetushkov@9858 473 const char* temp = NULL;
apetushkov@9858 474 const oop java_string = resolve_non_null(string);
apetushkov@9858 475 if (java_lang_String::value(java_string) != NULL) {
apetushkov@9858 476 const size_t length = java_lang_String::utf8_length(java_string);
apetushkov@9858 477 temp = NEW_RESOURCE_ARRAY_IN_THREAD(t, const char, (length + 1));
apetushkov@9858 478 if (temp == NULL) {
apetushkov@9858 479 JfrJavaSupport::throw_out_of_memory_error("Unable to allocate thread local native memory", t);
apetushkov@9858 480 return NULL;
apetushkov@9858 481 }
apetushkov@9858 482 assert(temp != NULL, "invariant");
apetushkov@9858 483 java_lang_String::as_utf8_string(java_string, const_cast<char*>(temp), (int) length + 1);
apetushkov@9858 484 }
apetushkov@9858 485 return temp;
apetushkov@9858 486 }
apetushkov@9858 487
apetushkov@9858 488 /*
apetushkov@9858 489 * Exceptions and errors
apetushkov@9858 490 */
apetushkov@9858 491 static void create_and_throw(Symbol* name, const char* message, TRAPS) {
apetushkov@9858 492 assert(name != NULL, "invariant");
apetushkov@9858 493 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 494 assert(!HAS_PENDING_EXCEPTION, "invariant");
apetushkov@9858 495 THROW_MSG(name, message);
apetushkov@9858 496 }
apetushkov@9858 497
apetushkov@9858 498 void JfrJavaSupport::throw_illegal_state_exception(const char* message, TRAPS) {
apetushkov@9858 499 create_and_throw(vmSymbols::java_lang_IllegalStateException(), message, THREAD);
apetushkov@9858 500 }
apetushkov@9858 501
apetushkov@9858 502 void JfrJavaSupport::throw_internal_error(const char* message, TRAPS) {
apetushkov@9858 503 create_and_throw(vmSymbols::java_lang_InternalError(), message, THREAD);
apetushkov@9858 504 }
apetushkov@9858 505
apetushkov@9858 506 void JfrJavaSupport::throw_illegal_argument_exception(const char* message, TRAPS) {
apetushkov@9858 507 create_and_throw(vmSymbols::java_lang_IllegalArgumentException(), message, THREAD);
apetushkov@9858 508 }
apetushkov@9858 509
apetushkov@9858 510 void JfrJavaSupport::throw_out_of_memory_error(const char* message, TRAPS) {
apetushkov@9858 511 create_and_throw(vmSymbols::java_lang_OutOfMemoryError(), message, THREAD);
apetushkov@9858 512 }
apetushkov@9858 513
apetushkov@9858 514 void JfrJavaSupport::throw_class_format_error(const char* message, TRAPS) {
apetushkov@9858 515 create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD);
apetushkov@9858 516 }
apetushkov@9858 517
jbachorik@9925 518 void JfrJavaSupport::throw_runtime_exception(const char* message, TRAPS) {
jbachorik@9925 519 create_and_throw(vmSymbols::java_lang_RuntimeException(), message, THREAD);
jbachorik@9925 520 }
jbachorik@9925 521
apetushkov@9858 522 void JfrJavaSupport::abort(jstring errorMsg, Thread* t) {
apetushkov@9858 523 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 524
apetushkov@9858 525 ResourceMark rm(t);
apetushkov@9858 526 const char* const error_msg = c_str(errorMsg, t);
apetushkov@9858 527 if (error_msg != NULL) {
apetushkov@9858 528 if (true) tty->print_cr("%s",error_msg);
apetushkov@9858 529 }
apetushkov@9858 530 if (true) tty->print_cr("%s", "An irrecoverable error in Jfr. Shutting down VM...");
apetushkov@9858 531 vm_abort();
apetushkov@9858 532 }
apetushkov@9858 533
apetushkov@9858 534 JfrJavaSupport::CAUSE JfrJavaSupport::_cause = JfrJavaSupport::VM_ERROR;
apetushkov@9858 535 void JfrJavaSupport::set_cause(jthrowable throwable, Thread* t) {
apetushkov@9858 536 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 537
apetushkov@9858 538 HandleMark hm(t);
apetushkov@9858 539 Handle ex(t, JNIHandles::resolve_external_guard(throwable));
apetushkov@9858 540
apetushkov@9858 541 if (ex.is_null()) {
apetushkov@9858 542 return;
apetushkov@9858 543 }
apetushkov@9858 544
apetushkov@9858 545 if (ex->is_a(SystemDictionary::OutOfMemoryError_klass())) {
apetushkov@9858 546 _cause = OUT_OF_MEMORY;
apetushkov@9858 547 return;
apetushkov@9858 548 }
apetushkov@9858 549 if (ex->is_a(SystemDictionary::StackOverflowError_klass())) {
apetushkov@9858 550 _cause = STACK_OVERFLOW;
apetushkov@9858 551 return;
apetushkov@9858 552 }
apetushkov@9858 553 if (ex->is_a(SystemDictionary::Error_klass())) {
apetushkov@9858 554 _cause = VM_ERROR;
apetushkov@9858 555 return;
apetushkov@9858 556 }
apetushkov@9858 557 if (ex->is_a(SystemDictionary::RuntimeException_klass())) {
apetushkov@9858 558 _cause = RUNTIME_EXCEPTION;
apetushkov@9858 559 return;
apetushkov@9858 560 }
apetushkov@9858 561 if (ex->is_a(SystemDictionary::Exception_klass())) {
apetushkov@9858 562 _cause = UNKNOWN;
apetushkov@9858 563 return;
apetushkov@9858 564 }
apetushkov@9858 565 }
apetushkov@9858 566
apetushkov@9858 567 void JfrJavaSupport::uncaught_exception(jthrowable throwable, Thread* t) {
apetushkov@9858 568 DEBUG_ONLY(check_java_thread_in_vm(t));
apetushkov@9858 569 assert(throwable != NULL, "invariant");
apetushkov@9858 570 set_cause(throwable, t);
apetushkov@9858 571 }
apetushkov@9858 572
apetushkov@9858 573 JfrJavaSupport::CAUSE JfrJavaSupport::cause() {
apetushkov@9858 574 return _cause;
apetushkov@9858 575 }
apetushkov@9858 576
apetushkov@9858 577 jlong JfrJavaSupport::jfr_thread_id(jobject target_thread) {
apetushkov@9858 578 // ThreadsListHandle tlh;
apetushkov@9858 579 // XXX is it correct and safe?
apetushkov@9858 580 JavaThread* native_thread = java_lang_Thread::thread(JNIHandles::resolve_non_null(target_thread));
apetushkov@9858 581 // (void)tlh.cv_internal_thread_to_JavaThread(target_thread, &native_thread, NULL);
apetushkov@9858 582 return native_thread != NULL ? JFR_THREAD_ID(native_thread) : 0;
apetushkov@9858 583 }

mercurial