45 #include "runtime/jniHandles.inline.hpp"
46 #include "runtime/timerTrace.hpp"
47 #include "runtime/vframe_hp.hpp"
48
49 JVMCIKlassHandle::JVMCIKlassHandle(Thread* thread, Klass* klass) {
50 _thread = thread;
51 _klass = klass;
52 if (klass != NULL) {
53 _holder = Handle(_thread, klass->klass_holder());
54 }
55 }
56
57 JVMCIKlassHandle& JVMCIKlassHandle::operator=(Klass* klass) {
58 _klass = klass;
59 if (klass != NULL) {
60 _holder = Handle(_thread, klass->klass_holder());
61 }
62 return *this;
63 }
64
65 void JNIHandleMark::push_jni_handle_block() {
66 JavaThread* thread = JavaThread::current();
67 if (thread != NULL) {
68 // Allocate a new block for JNI handles.
69 // Inlined code from jni_PushLocalFrame()
70 JNIHandleBlock* java_handles = ((JavaThread*)thread)->active_handles();
71 JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);
72 assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");
73 compile_handles->set_pop_frame_link(java_handles);
74 thread->set_active_handles(compile_handles);
75 }
76 }
77
78 void JNIHandleMark::pop_jni_handle_block() {
79 JavaThread* thread = JavaThread::current();
80 if (thread != NULL) {
81 // Release our JNI handle block
82 JNIHandleBlock* compile_handles = thread->active_handles();
83 JNIHandleBlock* java_handles = compile_handles->pop_frame_link();
84 thread->set_active_handles(java_handles);
85 compile_handles->set_pop_frame_link(NULL);
86 JNIHandleBlock::release_block(compile_handles, thread); // may block
87 }
88 }
89
90 class JVMCITraceMark : public StackObj {
91 const char* _msg;
92 public:
93 JVMCITraceMark(const char* msg) {
94 _msg = msg;
95 if (JVMCITraceLevel >= 1) {
96 tty->print_cr(PTR_FORMAT " JVMCITrace-1: Enter %s", p2i(JavaThread::current()), _msg);
97 }
98 }
99 ~JVMCITraceMark() {
100 if (JVMCITraceLevel >= 1) {
101 tty->print_cr(PTR_FORMAT " JVMCITrace-1: Exit %s", p2i(JavaThread::current()), _msg);
102 }
103 }
104 };
105
106
107 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
108 assert(_index < _args->length(), "out of bounds");
109 oop arg=((objArrayOop) (_args))->obj_at(_index++);
110 assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
111 return Handle(Thread::current(), arg);
112 }
113
114 // Entry to native method implementation that transitions current thread to '_thread_in_vm'.
115 #define C2V_VMENTRY(result_type, name, signature) \
116 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
117 JVMCITraceMark jtm("CompilerToVM::" #name); \
118 TRACE_CALL(result_type, jvmci_ ## name signature) \
119 JVMCI_VM_ENTRY_MARK; \
120 ResourceMark rm; \
121 JNI_JVMCIENV(env);
122
123 #define C2V_END }
124
125 jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);
126
127 C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv* env))
128 jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);
129 return config;
130 }
131
132 C2V_VMENTRY(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
133 #define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
134 #define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
135 JVMCIObject name = JVMCIENV->wrap(name_handle);
136 if (name.is_null()) {
137 JVMCI_THROW_NULL(NullPointerException);
138 }
139 const char* cstring = JVMCIENV->as_utf8_string(name);
140 JVMFlag* flag = JVMFlag::find_flag(cstring, strlen(cstring), /* allow_locked */ true, /* return_flag */ true);
141 if (flag == NULL) {
142 return c2vm;
143 }
144 if (flag->is_bool()) {
145 jvalue prim;
146 prim.z = flag->get_bool();
147 JVMCIObject box = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
148 return JVMCIENV->get_jobject(box);
149 } else if (flag->is_ccstr()) {
150 JVMCIObject value = JVMCIENV->create_string(flag->get_ccstr(), JVMCI_CHECK_NULL);
151 return JVMCIENV->get_jobject(value);
152 } else if (flag->is_intx()) {
153 RETURN_BOXED_LONG(flag->get_intx());
154 } else if (flag->is_int()) {
155 RETURN_BOXED_LONG(flag->get_int());
156 } else if (flag->is_uint()) {
157 RETURN_BOXED_LONG(flag->get_uint());
158 } else if (flag->is_uint64_t()) {
159 RETURN_BOXED_LONG(flag->get_uint64_t());
160 } else if (flag->is_size_t()) {
161 RETURN_BOXED_LONG(flag->get_size_t());
162 } else if (flag->is_uintx()) {
163 RETURN_BOXED_LONG(flag->get_uintx());
164 } else if (flag->is_double()) {
165 RETURN_BOXED_DOUBLE(flag->get_double());
166 } else {
167 JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type);
168 }
169 #undef RETURN_BOXED_LONG
170 #undef RETURN_BOXED_DOUBLE
171 C2V_END
172
173 C2V_VMENTRY(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
174 if (env != JavaThread::current()->jni_environment()) {
175 JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
176 }
177 if (oop_address == 0) {
178 JVMCI_THROW_MSG_NULL(InternalError, "Handle must be non-zero");
179 }
180 oop obj = *((oopDesc**) oop_address);
181 if (obj != NULL) {
182 oopDesc::verify(obj);
183 }
184 return JNIHandles::make_local(obj);
185 C2V_END
186
187 C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
188 methodHandle method = JVMCIENV->asMethod(jvmci_method);
189
190 int code_size = method->code_size();
191 jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
192
193 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
194 // iterate over all bytecodes and replace non-Java bytecodes
195
196 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
197 Bytecodes::Code code = s.code();
198 Bytecodes::Code raw_code = s.raw_code();
199 int bci = s.bci();
200 int len = s.instruction_size();
201
202 // Restore original byte code.
203 reconstituted_code[bci] = (jbyte) (s.is_wide()? Bytecodes::_wide : code);
204 if (len > 1) {
205 memcpy(reconstituted_code + (bci + 1), s.bcp()+1, len-1);
206 }
207
245
246 case Bytecodes::_fast_aldc_w: {
247 int cpc_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));
248 int cp_index = method->constants()->object_to_cp_index(cpc_index);
249 assert(cp_index < method->constants()->length(), "sanity check");
250 Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);
251 break;
252 }
253
254 default:
255 break;
256 }
257 }
258 }
259
260 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
261 JVMCIENV->copy_bytes_from(reconstituted_code, result, 0, code_size);
262 return JVMCIENV->get_jbyteArray(result);
263 C2V_END
264
265 C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
266 methodHandle method = JVMCIENV->asMethod(jvmci_method);
267 return method->exception_table_length();
268 C2V_END
269
270 C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
271 methodHandle method = JVMCIENV->asMethod(jvmci_method);
272 if (method->exception_table_length() == 0) {
273 return 0L;
274 }
275 return (jlong) (address) method->exception_table_start();
276 C2V_END
277
278 C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
279 if (env != JavaThread::current()->jni_environment()) {
280 JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
281 }
282
283 oop executable = JNIHandles::resolve(executable_handle);
284 oop mirror = NULL;
285 int slot = 0;
286
287 if (executable->klass() == SystemDictionary::reflect_Constructor_klass()) {
288 mirror = java_lang_reflect_Constructor::clazz(executable);
289 slot = java_lang_reflect_Constructor::slot(executable);
290 } else {
291 assert(executable->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
292 mirror = java_lang_reflect_Method::clazz(executable);
293 slot = java_lang_reflect_Method::slot(executable);
294 }
295 Klass* holder = java_lang_Class::as_Klass(mirror);
296 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
297 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
298 return JVMCIENV->get_jobject(result);
299 }
300
301 C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
302 methodHandle method;
303 JVMCIObject base_object = JVMCIENV->wrap(base);
304 if (base_object.is_null()) {
305 method = *((Method**)(offset));
306 } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
307 Handle obj = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
308 if (obj->is_a(SystemDictionary::ResolvedMethodName_klass())) {
309 method = (Method*) (intptr_t) obj->long_field(offset);
310 } else {
311 JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", obj->klass()->external_name()));
312 }
313 } else if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
314 method = JVMCIENV->asMethod(base_object);
315 }
316 if (method.is_null()) {
317 JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
318 }
319 assert (method.is_null() || method->is_method(), "invalid read");
320 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
321 return JVMCIENV->get_jobject(result);
322 }
323
324 C2V_VMENTRY(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
325 constantPoolHandle cp;
326 JVMCIObject object = JVMCIENV->wrap(object_handle);
327 if (object.is_null()) {
328 JVMCI_THROW_NULL(NullPointerException);
329 }
330 if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(object)) {
331 cp = JVMCIENV->asMethod(object)->constMethod()->constants();
332 } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(object)) {
333 cp = InstanceKlass::cast(JVMCIENV->asKlass(object))->constants();
334 } else {
335 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
336 err_msg("Unexpected type: %s", JVMCIENV->klass_name(object)));
337 }
338 assert(!cp.is_null(), "npe");
339
340 JVMCIObject result = JVMCIENV->get_jvmci_constant_pool(cp, JVMCI_CHECK_NULL);
341 return JVMCIENV->get_jobject(result);
342 }
343
344 C2V_VMENTRY(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
345 JVMCIKlassHandle klass(THREAD);
346 JVMCIObject base_object = JVMCIENV->wrap(base);
347 jlong base_address = 0;
348 if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) {
349 // klass = JVMCIENV->unhandle(base_object)->klass();
350 if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
351 Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
352 klass = base_oop->klass();
353 } else {
354 assert(false, "What types are we actually expecting here?");
355 }
356 } else if (!compressed) {
357 if (base_object.is_non_null()) {
358 if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
359 base_address = (intptr_t) JVMCIENV->asMethod(base_object);
360 } else if (JVMCIENV->isa_HotSpotConstantPool(base_object)) {
361 base_address = (intptr_t) JVMCIENV->asConstantPool(base_object);
362 } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
363 base_address = (intptr_t) JVMCIENV->asKlass(base_object);
364 } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
367 base_address = (jlong) (address) base_oop();
368 }
369 }
370 if (base_address == 0) {
371 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
372 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", JVMCIENV->klass_name(base_object), offset, compressed ? "true" : "false"));
373 }
374 }
375 klass = *((Klass**) (intptr_t) (base_address + offset));
376 } else {
377 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
378 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s",
379 base_object.is_non_null() ? JVMCIENV->klass_name(base_object) : "null",
380 offset, compressed ? "true" : "false"));
381 }
382 assert (klass == NULL || klass->is_klass(), "invalid read");
383 JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
384 return JVMCIENV->get_jobject(result);
385 }
386
387 C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
388 methodHandle method = JVMCIENV->asMethod(jvmci_method);
389 Klass* holder = JVMCIENV->asKlass(jvmci_type);
390 if (holder->is_interface()) {
391 JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
392 }
393
394 methodHandle ucm;
395 {
396 MutexLocker locker(Compile_lock);
397 ucm = Dependencies::find_unique_concrete_method(holder, method());
398 }
399 JVMCIObject result = JVMCIENV->get_jvmci_method(ucm, JVMCI_CHECK_NULL);
400 return JVMCIENV->get_jobject(result);
401 C2V_END
402
403 C2V_VMENTRY(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
404 Klass* klass = JVMCIENV->asKlass(jvmci_type);
405 if (!klass->is_interface()) {
406 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
407 err_msg("Expected interface type, got %s", klass->external_name()));
408 }
409 InstanceKlass* iklass = InstanceKlass::cast(klass);
410 JVMCIKlassHandle handle(THREAD);
411 {
412 // Need Compile_lock around implementor()
413 MutexLocker locker(Compile_lock);
414 handle = iklass->implementor();
415 }
416 JVMCIObject implementor = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
417 return JVMCIENV->get_jobject(implementor);
418 C2V_END
419
420 C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
421 methodHandle method = JVMCIENV->asMethod(jvmci_method);
422 return method->is_ignored_by_security_stack_walk();
423 C2V_END
424
425 C2V_VMENTRY(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
426 methodHandle method = JVMCIENV->asMethod(jvmci_method);
427 constantPoolHandle cp = method->constMethod()->constants();
428 assert(!cp.is_null(), "npe");
429 // don't inline method when constant pool contains a CONSTANT_Dynamic
430 return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
431 C2V_END
432
433 C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
434 methodHandle method = JVMCIENV->asMethod(jvmci_method);
435 return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();
436 C2V_END
437
438 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
439 methodHandle method = JVMCIENV->asMethod(jvmci_method);
440 return CompilerOracle::should_inline(method) || method->force_inline();
441 C2V_END
442
443 C2V_VMENTRY(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
444 JVMCIObject name = JVMCIENV->wrap(jname);
445 const char* str = JVMCIENV->as_utf8_string(name);
446 TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
447
448 if (class_name->utf8_length() <= 1) {
449 JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
450 }
451
452 JVMCIKlassHandle resolved_klass(THREAD);
453 Klass* accessing_klass = NULL;
454 Handle class_loader;
455 Handle protection_domain;
456 if (accessing_class != NULL) {
457 accessing_klass = JVMCIENV->asKlass(accessing_class);
458 class_loader = Handle(THREAD, accessing_klass->class_loader());
459 protection_domain = Handle(THREAD, accessing_klass->protection_domain());
460 } else {
461 // Use the System class loader
462 class_loader = Handle(THREAD, SystemDictionary::java_system_loader());
463 JVMCIENV->runtime()->initialize(JVMCIENV);
464 }
465
466 if (resolve) {
467 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
468 } else {
469 if (class_name->char_at(0) == 'L' &&
470 class_name->char_at(class_name->utf8_length()-1) == ';') {
471 // This is a name from a signature. Strip off the trimmings.
472 // Call recursive to keep scope of strippedsym.
473 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
474 class_name->utf8_length()-2,
475 CHECK_0);
476 resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
477 } else if (FieldType::is_array(class_name)) {
478 FieldArrayInfo fd;
479 // dimension and object_key in FieldArrayInfo are assigned as a side-effect
480 // of this call
481 BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
482 if (t == T_OBJECT) {
483 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
484 class_name->utf8_length()-2-fd.dimension(),
485 CHECK_0);
486 // naked oop "k" is OK here -- we assign back into it
487 resolved_klass = SystemDictionary::find(strippedsym,
488 class_loader,
489 protection_domain,
490 CHECK_0);
491 if (!resolved_klass.is_null()) {
492 resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0);
493 }
494 } else {
495 resolved_klass = TypeArrayKlass::cast(Universe::typeArrayKlassObj(t))->array_klass(fd.dimension(), CHECK_0);
496 }
497 } else {
498 resolved_klass = SystemDictionary::find(class_name, class_loader, protection_domain, CHECK_0);
499 }
500 }
501 JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
502 return JVMCIENV->get_jobject(result);
503 C2V_END
504
505 C2V_VMENTRY(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
506 if (env != JavaThread::current()->jni_environment()) {
507 JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
508 }
509 if (mirror == NULL) {
510 return NULL;
511 }
512 JVMCIKlassHandle klass(THREAD);
513 klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
514 if (klass == NULL) {
515 JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Primitive classes are unsupported");
516 }
517 JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
518 return JVMCIENV->get_jobject(result);
519 }
520
521 C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
522 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
523 oop result = cp->resolve_constant_at(index, CHECK_NULL);
524 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
525 C2V_END
526
527 C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
528 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
529 oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
530 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
531 C2V_END
532
533 C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
534 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
535 return cp->name_and_type_ref_index_at(index);
536 C2V_END
537
538 C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
539 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
540 JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);
541 return JVMCIENV->get_jobject(sym);
542 C2V_END
543
544 C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
545 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
546 JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);
547 return JVMCIENV->get_jobject(sym);
548 C2V_END
549
550 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
551 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
552 return cp->klass_ref_index_at(index);
553 C2V_END
554
555 C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
556 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
557 Klass* klass = cp->klass_at(index, CHECK_NULL);
558 JVMCIKlassHandle resolved_klass(THREAD, klass);
559 if (resolved_klass->is_instance_klass()) {
560 bool linked = InstanceKlass::cast(resolved_klass())->link_class_or_fail(CHECK_NULL);
561 if (!linked) {
562 return NULL;
563 }
564 }
565 JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
566 return JVMCIENV->get_jobject(klassObject);
567 C2V_END
568
569 C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
570 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
571 Klass* loading_klass = cp->pool_holder();
572 bool is_accessible = false;
573 JVMCIKlassHandle klass(THREAD, JVMCIRuntime::get_klass_by_index(cp, index, is_accessible, loading_klass));
574 Symbol* symbol = NULL;
575 if (klass.is_null()) {
576 constantTag tag = cp->tag_at(index);
577 if (tag.is_klass()) {
578 // The klass has been inserted into the constant pool
579 // very recently.
580 klass = cp->resolved_klass_at(index);
581 } else if (tag.is_symbol()) {
582 symbol = cp->symbol_at(index);
583 } else {
584 assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
585 symbol = cp->klass_name_at(index);
586 }
587 }
588 JVMCIObject result;
589 if (!klass.is_null()) {
590 result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
591 } else {
592 result = JVMCIENV->create_string(symbol, JVMCI_CHECK_NULL);
593 }
594 return JVMCIENV->get_jobject(result);
595 C2V_END
596
597 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
598 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
599 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
600 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));
601 C2V_END
602
603 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
604 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
605 InstanceKlass* pool_holder = cp->pool_holder();
606 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
607 methodHandle method = JVMCIRuntime::get_method_by_index(cp, index, bc, pool_holder);
608 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
609 return JVMCIENV->get_jobject(result);
610 C2V_END
611
612 C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
613 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
614 return cp->remap_instruction_operand_from_cache(index);
615 C2V_END
616
617 C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
618 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
619 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
620 fieldDescriptor fd;
621 LinkInfo link_info(cp, index, (jvmci_method != NULL) ? JVMCIENV->asMethod(jvmci_method) : NULL, CHECK_0);
622 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
623 JVMCIPrimitiveArray info = JVMCIENV->wrap(info_handle);
624 if (info.is_null() || JVMCIENV->get_length(info) != 3) {
625 JVMCI_ERROR_NULL("info must not be null and have a length of 3");
626 }
627 JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int());
628 JVMCIENV->put_int_at(info, 1, fd.offset());
629 JVMCIENV->put_int_at(info, 2, fd.index());
630 JVMCIKlassHandle handle(THREAD, fd.field_holder());
631 JVMCIObject field_holder = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
632 return JVMCIENV->get_jobject(field_holder);
633 C2V_END
634
635 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
636 Klass* klass = JVMCIENV->asKlass(jvmci_type);
637 Method* method = JVMCIENV->asMethod(jvmci_method);
638 if (klass->is_interface()) {
639 JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name()));
640 }
641 if (!method->method_holder()->is_interface()) {
642 JVMCI_THROW_MSG_0(InternalError, err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
643 }
644 if (!klass->is_instance_klass()) {
645 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
646 }
647 if (!InstanceKlass::cast(klass)->is_linked()) {
648 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name()));
649 }
650 return LinkResolver::vtable_index_of_interface_method(klass, method);
651 C2V_END
652
653 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
654 Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);
655 Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);
656 methodHandle method = JVMCIENV->asMethod(jvmci_method);
657
658 Klass* resolved = method->method_holder();
659 Symbol* h_name = method->name();
660 Symbol* h_signature = method->signature();
661
662 if (MethodHandles::is_signature_polymorphic_method(method())) {
663 // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.
664 return NULL;
665 }
666
667 if (method->name() == vmSymbols::clone_name() &&
668 resolved == SystemDictionary::Object_klass() &&
669 recv_klass->is_array_klass()) {
670 // Resolution of the clone method on arrays always returns Object.clone even though that method
671 // has protected access. There's some trickery in the access checking to make this all work out
672 // so it's necessary to pass in the array class as the resolved class to properly trigger this.
673 // Otherwise it's impossible to resolve the array clone methods through JVMCI. See
680 // Only do exact lookup if receiver klass has been linked. Otherwise,
681 // the vtable has not been setup, and the LinkResolver will fail.
682 if (recv_klass->is_array_klass() ||
683 (InstanceKlass::cast(recv_klass)->is_linked() && !recv_klass->is_interface())) {
684 if (resolved->is_interface()) {
685 m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info);
686 } else {
687 m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info);
688 }
689 }
690
691 if (m.is_null()) {
692 // Return NULL if there was a problem with lookup (uninitialized class, etc.)
693 return NULL;
694 }
695
696 JVMCIObject result = JVMCIENV->get_jvmci_method(m, JVMCI_CHECK_NULL);
697 return JVMCIENV->get_jobject(result);
698 C2V_END
699
700 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
701 Klass* klass = JVMCIENV->asKlass(jvmci_type);
702 assert(klass != NULL, "method must not be called for primitive types");
703 return Dependencies::find_finalizable_subclass(klass) != NULL;
704 C2V_END
705
706 C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
707 Klass* klass = JVMCIENV->asKlass(jvmci_type);
708 if (!klass->is_instance_klass()) {
709 return NULL;
710 }
711 InstanceKlass* iklass = InstanceKlass::cast(klass);
712 JVMCIObject result = JVMCIENV->get_jvmci_method(iklass->class_initializer(), JVMCI_CHECK_NULL);
713 return JVMCIENV->get_jobject(result);
714 C2V_END
715
716 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
717 address target_addr = (address) addr;
718 if (target_addr != 0x0) {
719 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
720 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
721 return MAX2(ABS(off_low), ABS(off_high));
722 }
723 return -1;
724 C2V_END
725
726 C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
727 methodHandle method = JVMCIENV->asMethod(jvmci_method);
728 method->set_not_c1_compilable();
729 method->set_not_c2_compilable();
730 method->set_dont_inline(true);
731 C2V_END
732
733 C2V_VMENTRY(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
734 jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))
735 HandleMark hm;
736 JNIHandleMark jni_hm;
737
738 JVMCIObject target_handle = JVMCIENV->wrap(target);
739 JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
740 CodeBlob* cb = NULL;
741 JVMCIObject installed_code_handle = JVMCIENV->wrap(installed_code);
742 JVMCIPrimitiveArray speculations_handle = JVMCIENV->wrap(speculations_obj);
743
744 int speculations_len = JVMCIENV->get_length(speculations_handle);
745 char* speculations = NEW_RESOURCE_ARRAY(char, speculations_len);
746 JVMCIENV->copy_bytes_to(speculations_handle, (jbyte*) speculations, 0, speculations_len);
747
748 JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
749
750 TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
751 bool is_immutable_PIC = JVMCIENV->get_HotSpotCompiledCode_isImmutablePIC(compiled_code_handle) > 0;
752
753 CodeInstaller installer(JVMCIENV, is_immutable_PIC);
754 JVMCI::CodeInstallResult result = installer.install(compiler,
755 target_handle,
756 compiled_code_handle,
774
775 if (result != JVMCI::ok) {
776 assert(cb == NULL, "should be");
777 } else {
778 if (installed_code_handle.is_non_null()) {
779 if (cb->is_nmethod()) {
780 assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type");
781 // Clear the link to an old nmethod first
782 JVMCIObject nmethod_mirror = installed_code_handle;
783 JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK_0);
784 } else {
785 assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");
786 }
787 // Initialize the link to the new code blob
788 JVMCIENV->initialize_installed_code(installed_code_handle, cb, JVMCI_CHECK_0);
789 }
790 }
791 return result;
792 C2V_END
793
794 C2V_VMENTRY(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
795 #if INCLUDE_AOT
796 HandleMark hm;
797 assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
798
799 JVMCIObject target_handle = JVMCIENV->wrap(target);
800 JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
801 JVMCIObject metadata_handle = JVMCIENV->wrap(metadata);
802
803 CodeMetadata code_metadata;
804
805 CodeInstaller installer(JVMCIENV, true /* immutable PIC compilation */);
806 JVMCI::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, JVMCI_CHECK_0);
807 if (result != JVMCI::ok) {
808 return result;
809 }
810
811 if (code_metadata.get_nr_pc_desc() > 0) {
812 int size = sizeof(PcDesc) * code_metadata.get_nr_pc_desc();
813 JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
814 JVMCIENV->copy_bytes_from((jbyte*) code_metadata.get_pc_desc(), array, 0, size);
855 int table_size = handler->size_in_bytes();
856 JVMCIPrimitiveArray exceptionArray = JVMCIENV->new_byteArray(table_size, JVMCI_CHECK_(JVMCI::cache_full));
857 if (table_size > 0) {
858 handler->copy_bytes_to((address) HotSpotJVMCI::resolve(exceptionArray)->byte_at_addr(0));
859 }
860 HotSpotJVMCI::HotSpotMetaData::set_exceptionBytes(JVMCIENV, metadata_handle, exceptionArray);
861
862 return result;
863 #else
864 JVMCI_THROW_MSG_0(InternalError, "unimplemented");
865 #endif
866 C2V_END
867
868 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv* env, jobject))
869 JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
870 CompilerStatistics* stats = compiler->stats();
871 stats->_standard.reset();
872 stats->_osr.reset();
873 C2V_END
874
875 C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
876 HandleMark hm;
877
878 if (installedCode == NULL) {
879 JVMCI_THROW_MSG_NULL(NullPointerException, "installedCode is null");
880 }
881
882 JVMCIObject installedCodeObject = JVMCIENV->wrap(installedCode);
883 CodeBlob* cb = JVMCIENV->asCodeBlob(installedCodeObject);
884 if (cb == NULL) {
885 return NULL;
886 }
887
888 // We don't want the stringStream buffer to resize during disassembly as it
889 // uses scoped resource memory. If a nested function called during disassembly uses
890 // a ResourceMark and the buffer expands within the scope of the mark,
891 // the buffer becomes garbage when that scope is exited. Experience shows that
892 // the disassembled code is typically about 10x the code size so a fixed buffer
893 // sized to 20x code size plus a fixed amount for header info should be sufficient.
894 int bufferSize = cb->code_size() * 20 + 1024;
895 char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);
896 stringStream st(buffer, bufferSize);
897 if (cb->is_nmethod()) {
898 nmethod* nm = (nmethod*) cb;
899 if (!nm->is_alive()) {
900 return NULL;
901 }
902 }
903 Disassembler::decode(cb, &st);
904 if (st.size() <= 0) {
905 return NULL;
906 }
907
908 JVMCIObject result = JVMCIENV->create_string(st.as_string(), JVMCI_CHECK_NULL);
909 return JVMCIENV->get_jobject(result);
910 C2V_END
911
912 C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
913 HandleMark hm;
914
915 methodHandle method = JVMCIENV->asMethod(jvmci_method);
916 JVMCIObject element = JVMCIENV->new_StackTraceElement(method, bci, JVMCI_CHECK_NULL);
917 return JVMCIENV->get_jobject(element);
918 C2V_END
919
920 C2V_VMENTRY(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
921 if (env != JavaThread::current()->jni_environment()) {
922 // The incoming arguments array would have to contain JavaConstants instead of regular objects
923 // and the return value would have to be wrapped as a JavaConstant.
924 JVMCI_THROW_MSG_NULL(InternalError, "Wrapping of arguments is currently unsupported");
925 }
926
927 HandleMark hm;
928
929 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
930 nmethod* nm = JVMCIENV->asNmethod(nmethod_mirror);
931 if (nm == NULL) {
932 JVMCI_THROW_NULL(InvalidInstalledCodeException);
933 }
934 methodHandle mh = nm->method();
935 Symbol* signature = mh->signature();
936 JavaCallArguments jca(mh->size_of_parameters());
937
938 JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
939 JavaValue result(jap.get_ret_type());
940 jca.set_alternative_target(nm);
941 JavaCalls::call(&result, mh, &jca, CHECK_NULL);
942
943 if (jap.get_ret_type() == T_VOID) {
944 return NULL;
945 } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
951 case T_BOOLEAN:
952 value->z = (jboolean) value->i;
953 break;
954 case T_BYTE:
955 value->b = (jbyte) value->i;
956 break;
957 case T_CHAR:
958 value->c = (jchar) value->i;
959 break;
960 case T_SHORT:
961 value->s = (jshort) value->i;
962 break;
963 default:
964 break;
965 }
966 JVMCIObject o = JVMCIENV->create_box(jap.get_ret_type(), value, JVMCI_CHECK_NULL);
967 return JVMCIENV->get_jobject(o);
968 }
969 C2V_END
970
971 C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
972 Method* method = JVMCIENV->asMethod(jvmci_method);
973 if (!method->has_linenumber_table()) {
974 return NULL;
975 }
976 u2 num_entries = 0;
977 CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table());
978 while (streamForSize.read_pair()) {
979 num_entries++;
980 }
981
982 CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
983 JVMCIPrimitiveArray result = JVMCIENV->new_longArray(2 * num_entries, JVMCI_CHECK_NULL);
984
985 int i = 0;
986 jlong value;
987 while (stream.read_pair()) {
988 value = ((long) stream.bci());
989 JVMCIENV->put_long_at(result, i, value);
990 value = ((long) stream.line());
991 JVMCIENV->put_long_at(result, i + 1, value);
992 i += 2;
993 }
994
995 return (jlongArray) JVMCIENV->get_jobject(result);
996 C2V_END
997
998 C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
999 Method* method = JVMCIENV->asMethod(jvmci_method);
1000 if (!method->has_localvariable_table()) {
1001 return 0;
1002 }
1003 return (jlong) (address) method->localvariable_table_start();
1004 C2V_END
1005
1006 C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
1007 Method* method = JVMCIENV->asMethod(jvmci_method);
1008 return method->localvariable_table_length();
1009 C2V_END
1010
1011 C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, jobject jvmci_method))
1012 Method* method = JVMCIENV->asMethod(jvmci_method);
1013 MethodCounters* mcs = method->method_counters();
1014 if (mcs != NULL) {
1015 mcs->clear_counters();
1016 }
1017 NOT_PRODUCT(method->set_compiled_invocation_count(0));
1018
1019 CompiledMethod* code = method->code();
1020 if (code != NULL) {
1021 code->make_not_entrant();
1022 }
1023
1024 MethodData* method_data = method->method_data();
1025 if (method_data == NULL) {
1026 ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
1027 method_data = MethodData::allocate(loader_data, method, CHECK);
1028 method->set_method_data(method_data);
1029 } else {
1030 method_data->initialize();
1031 }
1032 C2V_END
1033
1034
1035 C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))
1036 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
1037 JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
1038 C2V_END
1039
1040 C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
1041 oop ret = RawAccess<>::oop_load((oop*)(address)addr);
1042 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(ret));
1043 C2V_END
1044
1045 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv* env, jobject))
1046 JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);
1047 JavaThread::collect_counters(JVMCIENV, array);
1048 return (jlongArray) JVMCIENV->get_jobject(array);
1049 C2V_END
1050
1051 C2V_VMENTRY(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
1052 HandleMark hm;
1053 if (jvmci_method == NULL) {
1054 JVMCI_THROW_0(NullPointerException);
1055 }
1056 Method* method = JVMCIENV->asMethod(jvmci_method);
1057 if (entry_bci >= method->code_size() || entry_bci < -1) {
1058 JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Unexpected bci %d", entry_bci));
1059 }
1060 return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
1061 C2V_END
1062
1063
1064 C2V_VMENTRY(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
1065 MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
1066 return mdo != NULL && mdo->is_mature();
1067 C2V_END
1068
1069 C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
1070 Method* method = JVMCIENV->asMethod(jvmci_method);
1071 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
1072 C2V_END
1073
1074 C2V_VMENTRY(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
1075 JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
1076 return JVMCIENV->get_jobject(sym);
1077 C2V_END
1078
1079 bool matches(jobjectArray methods, Method* method, JVMCIEnv* JVMCIENV) {
1080 objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
1081
1082 for (int i = 0; i < methods_oop->length(); i++) {
1083 oop resolved = methods_oop->obj_at(i);
1084 if ((resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) && HotSpotJVMCI::asMethod(JVMCIENV, resolved) == method) {
1085 return true;
1086 }
1087 }
1088 return false;
1089 }
1090
1091 void call_interface(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
1092 CallInfo callinfo;
1093 Handle receiver = args->receiver();
1094 Klass* recvrKlass = receiver.is_null() ? (Klass*)NULL : receiver->klass();
1095 LinkInfo link_info(spec_klass, name, signature);
1096 LinkResolver::resolve_interface_call(
1097 callinfo, receiver, recvrKlass, link_info, true, CHECK);
1098 methodHandle method = callinfo.selected_method();
1099 assert(method.not_null(), "should have thrown exception");
1100
1101 // Invoke the method
1102 JavaCalls::call(result, method, args, CHECK);
1103 }
1104
1105 C2V_VMENTRY(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
1106
1107 if (!thread->has_last_Java_frame()) {
1108 return NULL;
1109 }
1110 Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
1111
1112 if (env != JavaThread::current()->jni_environment()) {
1113 JVMCI_THROW_MSG_NULL(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
1114 }
1115
1116 HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
1117 Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
1118
1119 StackFrameStream fst(thread);
1120 jobjectArray methods = initial_methods;
1121
1122 int frame_number = 0;
1123 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
1124
1125 while (true) {
1126 // look for the given method
1127 bool realloc_called = false;
1128 while (true) {
1129 StackValueCollection* locals = NULL;
1130 if (vf->is_compiled_frame()) {
1131 // compiled method frame
1132 compiledVFrame* cvf = compiledVFrame::cast(vf);
1133 if (methods == NULL || matches(methods, cvf->method(), JVMCIENV)) {
1134 if (initialSkip > 0) {
1266 C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1267 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1268 CallInfo callInfo;
1269 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);
1270 ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);
1271 cp_cache_entry->set_dynamic_call(cp, callInfo);
1272 C2V_END
1273
1274 C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1275 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1276 Klass* holder = cp->klass_ref_at(index, CHECK);
1277 Symbol* name = cp->name_ref_at(index);
1278 if (MethodHandles::is_signature_polymorphic_name(holder, name)) {
1279 CallInfo callInfo;
1280 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
1281 ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
1282 cp_cache_entry->set_method_handle(cp, callInfo);
1283 }
1284 C2V_END
1285
1286 C2V_VMENTRY(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1287 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1288 ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
1289 if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {
1290 // MethodHandle.invoke* --> LambdaForm?
1291 ResourceMark rm;
1292
1293 LinkInfo link_info(cp, index, CATCH);
1294
1295 Klass* resolved_klass = link_info.resolved_klass();
1296
1297 Symbol* name_sym = cp->name_ref_at(index);
1298
1299 vmassert(MethodHandles::is_method_handle_invoke_name(resolved_klass, name_sym), "!");
1300 vmassert(MethodHandles::is_signature_polymorphic_name(resolved_klass, name_sym), "!");
1301
1302 methodHandle adapter_method(cp_cache_entry->f1_as_method());
1303
1304 methodHandle resolved_method(adapter_method);
1305
1306 // Can we treat it as a regular invokevirtual?
1307 if (resolved_method->method_holder() == resolved_klass && resolved_method->name() == name_sym) {
1308 vmassert(!resolved_method->is_static(),"!");
1309 vmassert(MethodHandles::is_signature_polymorphic_method(resolved_method()),"!");
1310 vmassert(!MethodHandles::is_signature_polymorphic_static(resolved_method->intrinsic_id()), "!");
1311 vmassert(cp_cache_entry->appendix_if_resolved(cp) == NULL, "!");
1312
1313 methodHandle m(LinkResolver::linktime_resolve_virtual_method_or_null(link_info));
1314 vmassert(m == resolved_method, "!!");
1315 return -1;
1316 }
1317
1318 return Bytecodes::_invokevirtual;
1319 }
1320 if (cp_cache_entry->is_resolved(Bytecodes::_invokedynamic)) {
1321 return Bytecodes::_invokedynamic;
1322 }
1323 return -1;
1324 C2V_END
1325
1326
1327 C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
1328 JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);
1329 JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);
1330 JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);
1331 JVMCIENV->put_object_at(holders, 0, mh);
1332 JVMCIENV->put_object_at(holders, 1, vh);
1333 return JVMCIENV->get_jobject(holders);
1334 C2V_END
1335
1336 C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
1337 //see compute_recording_non_safepoints in debugInfroRec.cpp
1338 if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
1339 return true;
1340 }
1341 return DebugNonSafepoints;
1342 C2V_END
1343
1344 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
1345 C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_frame, bool invalidate))
1346 JVMCIObject hs_frame = JVMCIENV->wrap(_hs_frame);
1347 if (hs_frame.is_null()) {
1348 JVMCI_THROW_MSG(NullPointerException, "stack frame is null");
1349 }
1350
1351 if (env != JavaThread::current()->jni_environment()) {
1352 JVMCI_THROW_MSG(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
1353 }
1354
1355 JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);
1356
1357 // look for the given stack frame
1358 StackFrameStream fst(thread);
1359 intptr_t* stack_pointer = (intptr_t*) JVMCIENV->get_HotSpotStackFrameReference_stackPointer(hs_frame);
1360 while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
1361 fst.next();
1362 }
1363 if (fst.current()->sp() != stack_pointer) {
1364 JVMCI_THROW_MSG(IllegalStateException, "stack frame not found");
1365 }
1366
1367 if (invalidate) {
1368 if (!fst.current()->is_compiled_frame()) {
1369 JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");
1370 }
1371 assert(fst.current()->cb()->is_nmethod(), "nmethod expected");
1372 ((nmethod*) fst.current()->cb())->make_not_entrant();
1373 }
1448 for (int i2 = 0; i2 < monitors->length(); i2++) {
1449 cvf->update_monitor(i2, monitors->at(i2));
1450 }
1451 }
1452 }
1453
1454 // all locals are materialized by now
1455 JVMCIENV->set_HotSpotStackFrameReference_localIsVirtual(hs_frame, NULL);
1456 // update the locals array
1457 JVMCIObjectArray array = JVMCIENV->get_HotSpotStackFrameReference_locals(hs_frame);
1458 StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();
1459 for (int i = 0; i < locals->size(); i++) {
1460 StackValue* var = locals->at(i);
1461 if (var->type() == T_OBJECT) {
1462 JVMCIENV->put_object_at(array, i, HotSpotJVMCI::wrap(locals->at(i)->get_obj()()));
1463 }
1464 }
1465 HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);
1466 C2V_END
1467
1468 C2V_VMENTRY(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
1469 if (bytes == NULL) {
1470 JVMCI_THROW(NullPointerException);
1471 }
1472 JVMCIPrimitiveArray array = JVMCIENV->wrap(bytes);
1473
1474 // Check if offset and length are non negative.
1475 if (offset < 0 || length < 0) {
1476 JVMCI_THROW(ArrayIndexOutOfBoundsException);
1477 }
1478 // Check if the range is valid.
1479 int array_length = JVMCIENV->get_length(array);
1480 if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array_length)) {
1481 JVMCI_THROW(ArrayIndexOutOfBoundsException);
1482 }
1483 jbyte buffer[O_BUFLEN];
1484 while (length > 0) {
1485 int copy_len = MIN2(length, (jint)O_BUFLEN);
1486 JVMCIENV->copy_bytes_to(array, buffer, offset, copy_len);
1487 tty->write((char*) buffer, copy_len);
1488 length -= O_BUFLEN;
1489 offset += O_BUFLEN;
1490 }
1491 C2V_END
1492
1493 C2V_VMENTRY(void, flushDebugOutput, (JNIEnv* env, jobject))
1494 tty->flush();
1495 C2V_END
1496
1497 C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
1498 MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
1499 ProfileData* profile_data = mdo->data_at(position);
1500 if (mdo->is_valid(profile_data)) {
1501 return profile_data->size_in_bytes();
1502 }
1503 DataLayout* data = mdo->extra_data_base();
1504 DataLayout* end = mdo->extra_data_limit();
1505 for (;; data = mdo->next_extra(data)) {
1506 assert(data < end, "moved past end of extra data");
1507 profile_data = data->data_in();
1508 if (mdo->dp_to_di(profile_data->dp()) == position) {
1509 return profile_data->size_in_bytes();
1510 }
1511 }
1512 JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));
1513 C2V_END
1514
1515 C2V_VMENTRY(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
1516 #if INCLUDE_AOT
1517 Klass *k = (Klass*) (address) metaspace_klass;
1518 if (k->is_instance_klass()) {
1519 return InstanceKlass::cast(k)->get_stored_fingerprint();
1520 } else {
1521 return 0;
1522 }
1523 #else
1524 JVMCI_THROW_MSG_0(InternalError, "unimplemented");
1525 #endif
1526 C2V_END
1527
1528 C2V_VMENTRY(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
1529 InstanceKlass* k = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
1530 InstanceKlass* host = k->unsafe_anonymous_host();
1531 JVMCIKlassHandle handle(THREAD, host);
1532 JVMCIObject result = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
1533 return JVMCIENV->get_jobject(result);
1534 C2V_END
1535
1536 C2V_VMENTRY(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
1537 if (jvmci_type == NULL) {
1538 JVMCI_THROW_0(NullPointerException);
1539 }
1540
1541 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1542 if (klass == NULL) {
1543 JVMCI_THROW_0(NullPointerException);
1544 }
1545 if (!klass->is_instance_klass()) {
1546 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
1547 }
1548 InstanceKlass* iklass = InstanceKlass::cast(klass);
1549
1550 // Regular instance klass, fill in all local interfaces
1551 int size = iklass->local_interfaces()->length();
1552 JVMCIObjectArray interfaces = JVMCIENV->new_HotSpotResolvedObjectTypeImpl_array(size, JVMCI_CHECK_NULL);
1553 for (int index = 0; index < size; index++) {
1554 JVMCIKlassHandle klass(THREAD);
1555 Klass* k = iklass->local_interfaces()->at(index);
1556 klass = k;
1557 JVMCIObject type = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
1558 JVMCIENV->put_object_at(interfaces, index, type);
1559 }
1560 return JVMCIENV->get_jobject(interfaces);
1561 C2V_END
1562
1563 C2V_VMENTRY(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
1564 if (jvmci_type == NULL) {
1565 JVMCI_THROW_0(NullPointerException);
1566 }
1567
1568 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1569 oop mirror = klass->java_mirror();
1570 if (java_lang_Class::is_primitive(mirror) ||
1571 !java_lang_Class::as_Klass(mirror)->is_array_klass()) {
1572 return NULL;
1573 }
1574
1575 oop component_mirror = java_lang_Class::component_mirror(mirror);
1576 if (component_mirror == NULL) {
1577 return NULL;
1578 }
1579 Klass* component_klass = java_lang_Class::as_Klass(component_mirror);
1580 if (component_klass != NULL) {
1581 JVMCIKlassHandle klass_handle(THREAD);
1582 klass_handle = component_klass;
1583 JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
1584 return JVMCIENV->get_jobject(result);
1585 }
1586 BasicType type = java_lang_Class::primitive_type(component_mirror);
1587 JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type);
1588 return JVMCIENV->get_jobject(result);
1589 C2V_END
1590
1591 C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, jobject jvmci_type))
1592 if (jvmci_type == NULL) {
1593 JVMCI_THROW(NullPointerException);
1594 }
1595
1596 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1597 if (klass != NULL && klass->should_be_initialized()) {
1598 InstanceKlass* k = InstanceKlass::cast(klass);
1599 k->initialize(CHECK);
1600 }
1601 C2V_END
1602
1603 C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
1604 if (bytecode_frame_handle == NULL) {
1605 JVMCI_THROW_0(NullPointerException);
1606 }
1607
1608 JVMCIObject top_bytecode_frame = JVMCIENV->wrap(bytecode_frame_handle);
1609 JVMCIObject bytecode_frame = top_bytecode_frame;
1610 int size = 0;
1611 int callee_parameters = 0;
1612 int callee_locals = 0;
1613 Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
1614 int extra_args = method->max_stack() - JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
1615
1616 while (bytecode_frame.is_non_null()) {
1617 int locks = JVMCIENV->get_BytecodeFrame_numLocks(bytecode_frame);
1618 int temps = JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
1619 bool is_top_frame = (JVMCIENV->equals(bytecode_frame, top_bytecode_frame));
1620 Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
1621
1622 int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
1623 temps + callee_parameters,
1631 callee_parameters = method->size_of_parameters();
1632 callee_locals = method->max_locals();
1633 extra_args = 0;
1634 bytecode_frame = JVMCIENV->get_BytecodePosition_caller(bytecode_frame);
1635 }
1636 return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
1637 C2V_END
1638
1639 C2V_VMENTRY(void, compileToBytecode, (JNIEnv* env, jobject, jobject lambda_form_handle))
1640 Handle lambda_form = JVMCIENV->asConstant(JVMCIENV->wrap(lambda_form_handle), JVMCI_CHECK);
1641 if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) {
1642 TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK);
1643 JavaValue result(T_VOID);
1644 JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);
1645 } else {
1646 JVMCI_THROW_MSG(IllegalArgumentException,
1647 err_msg("Unexpected type: %s", lambda_form->klass()->external_name()))
1648 }
1649 C2V_END
1650
1651 C2V_VMENTRY(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
1652 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1653 return obj->identity_hash();
1654 C2V_END
1655
1656 C2V_VMENTRY(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
1657 Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1658 if (!java_lang_String::is_instance(str())) {
1659 return false;
1660 }
1661 int len;
1662 jchar* name = java_lang_String::as_unicode_string(str(), len, CHECK_0);
1663 return (StringTable::lookup(name, len) != NULL);
1664 C2V_END
1665
1666
1667 C2V_VMENTRY(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
1668 if (object == NULL) {
1669 JVMCI_THROW_0(NullPointerException);
1670 }
1671 Handle box = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
1672 BasicType type = java_lang_boxing_object::basic_type(box());
1673 jvalue result;
1674 if (java_lang_boxing_object::get_value(box(), &result) == T_ILLEGAL) {
1675 return NULL;
1676 }
1677 JVMCIObject boxResult = JVMCIENV->create_box(type, &result, JVMCI_CHECK_NULL);
1678 return JVMCIENV->get_jobject(boxResult);
1679 C2V_END
1680
1681 C2V_VMENTRY(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
1682 if (object == NULL) {
1683 JVMCI_THROW_0(NullPointerException);
1684 }
1685 JVMCIObject box = JVMCIENV->wrap(object);
1686 BasicType type = JVMCIENV->get_box_type(box);
1687 if (type == T_ILLEGAL) {
1688 return NULL;
1689 }
1690 jvalue value = JVMCIENV->get_boxed_value(type, box);
1691 JavaValue box_result(T_OBJECT);
1692 JavaCallArguments jargs;
1693 Klass* box_klass = NULL;
1694 Symbol* box_signature = NULL;
1695 #define BOX_CASE(bt, v, argtype, name) \
1696 case bt: \
1697 jargs.push_##argtype(value.v); \
1698 box_klass = SystemDictionary::name##_klass(); \
1699 box_signature = vmSymbols::name##_valueOf_signature(); \
1700 break
1701
1705 BOX_CASE(T_CHAR, c, int, Character);
1706 BOX_CASE(T_SHORT, s, int, Short);
1707 BOX_CASE(T_INT, i, int, Integer);
1708 BOX_CASE(T_LONG, j, long, Long);
1709 BOX_CASE(T_FLOAT, f, float, Float);
1710 BOX_CASE(T_DOUBLE, d, double, Double);
1711 default:
1712 ShouldNotReachHere();
1713 }
1714 #undef BOX_CASE
1715
1716 JavaCalls::call_static(&box_result,
1717 box_klass,
1718 vmSymbols::valueOf_name(),
1719 box_signature, &jargs, CHECK_NULL);
1720 oop hotspot_box = (oop) box_result.get_jobject();
1721 JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
1722 return JVMCIENV->get_jobject(result);
1723 C2V_END
1724
1725 C2V_VMENTRY(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
1726 if (holder == NULL) {
1727 JVMCI_THROW_0(NullPointerException);
1728 }
1729 Klass* klass = JVMCIENV->asKlass(holder);
1730 if (!klass->is_instance_klass()) {
1731 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
1732 return JVMCIENV->get_jobjectArray(methods);
1733 }
1734
1735 InstanceKlass* iklass = InstanceKlass::cast(klass);
1736 // Ensure class is linked
1737 iklass->link_class(CHECK_NULL);
1738
1739 GrowableArray<Method*> constructors_array;
1740 for (int i = 0; i < iklass->methods()->length(); i++) {
1741 Method* m = iklass->methods()->at(i);
1742 if (m->is_initializer() && !m->is_static()) {
1743 constructors_array.append(m);
1744 }
1745 }
1746 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);
1747 for (int i = 0; i < constructors_array.length(); i++) {
1748 JVMCIObject method = JVMCIENV->get_jvmci_method(constructors_array.at(i), JVMCI_CHECK_NULL);
1749 JVMCIENV->put_object_at(methods, i, method);
1750 }
1751 return JVMCIENV->get_jobjectArray(methods);
1752 C2V_END
1753
1754 C2V_VMENTRY(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
1755 if (holder == NULL) {
1756 JVMCI_THROW_0(NullPointerException);
1757 }
1758 Klass* klass = JVMCIENV->asKlass(holder);
1759 if (!klass->is_instance_klass()) {
1760 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
1761 return JVMCIENV->get_jobjectArray(methods);
1762 }
1763
1764 InstanceKlass* iklass = InstanceKlass::cast(klass);
1765 // Ensure class is linked
1766 iklass->link_class(CHECK_NULL);
1767
1768 GrowableArray<Method*> methods_array;
1769 for (int i = 0; i < iklass->methods()->length(); i++) {
1770 Method* m = iklass->methods()->at(i);
1771 if (!m->is_initializer() && !m->is_overpass()) {
1772 methods_array.append(m);
1773 }
1774 }
1775 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);
1776 for (int i = 0; i < methods_array.length(); i++) {
1777 JVMCIObject method = JVMCIENV->get_jvmci_method(methods_array.at(i), JVMCI_CHECK_NULL);
1778 JVMCIENV->put_object_at(methods, i, method);
1779 }
1780 return JVMCIENV->get_jobjectArray(methods);
1781 C2V_END
1782
1783 C2V_VMENTRY(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
1784 if (object == NULL || field == NULL) {
1785 JVMCI_THROW_0(NullPointerException);
1786 }
1787 JVMCIObject field_object = JVMCIENV->wrap(field);
1788 JVMCIObject java_type = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_type(field_object);
1789 int modifiers = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_modifiers(field_object);
1790 Klass* holder = JVMCIENV->asKlass(JVMCIENV->get_HotSpotResolvedJavaFieldImpl_holder(field_object));
1791 if (!holder->is_instance_klass()) {
1792 JVMCI_THROW_MSG_0(InternalError, err_msg("Holder %s must be instance klass", holder->external_name()));
1793 }
1794 InstanceKlass* ik = InstanceKlass::cast(holder);
1795 BasicType constant_type;
1796 if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(java_type)) {
1797 constant_type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(java_type), JVMCI_CHECK_NULL);
1798 } else {
1799 constant_type = T_OBJECT;
1800 }
1801 int displacement = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_offset(field_object);
1802 fieldDescriptor fd;
1803 if (!ik->find_local_field_from_offset(displacement, (modifiers & JVM_ACC_STATIC) != 0, &fd)) {
1831 return JVMCIENV->get_jobject(result);
1832 }
1833 case T_DOUBLE: {
1834 double f = is_volatile ? obj->double_field_acquire(displacement) : obj->double_field(displacement);
1835 JVMCIObject result = JVMCIENV->call_JavaConstant_forDouble(f, JVMCI_CHECK_NULL);
1836 return JVMCIENV->get_jobject(result);
1837 }
1838 case T_BOOLEAN: value = is_volatile ? obj->bool_field_acquire(displacement) : obj->bool_field(displacement); break;
1839 case T_BYTE: value = is_volatile ? obj->byte_field_acquire(displacement) : obj->byte_field(displacement); break;
1840 case T_SHORT: value = is_volatile ? obj->short_field_acquire(displacement) : obj->short_field(displacement); break;
1841 case T_CHAR: value = is_volatile ? obj->char_field_acquire(displacement) : obj->char_field(displacement); break;
1842 case T_INT: value = is_volatile ? obj->int_field_acquire(displacement) : obj->int_field(displacement); break;
1843 case T_LONG: value = is_volatile ? obj->long_field_acquire(displacement) : obj->long_field(displacement); break;
1844 default:
1845 ShouldNotReachHere();
1846 }
1847 JVMCIObject result = JVMCIENV->call_PrimitiveConstant_forTypeChar(type2char(constant_type), value, JVMCI_CHECK_NULL);
1848 return JVMCIENV->get_jobject(result);
1849 C2V_END
1850
1851 C2V_VMENTRY(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
1852 if (object == NULL || holder == NULL) {
1853 JVMCI_THROW_0(NullPointerException);
1854 }
1855 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1856 Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
1857 return obj->is_a(klass);
1858 C2V_END
1859
1860 C2V_VMENTRY(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
1861 if (holder == NULL || otherHolder == NULL) {
1862 JVMCI_THROW_0(NullPointerException);
1863 }
1864 Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
1865 Klass* otherKlass = JVMCIENV->asKlass(JVMCIENV->wrap(otherHolder));
1866 return otherKlass->is_subtype_of(klass);
1867 C2V_END
1868
1869 C2V_VMENTRY(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
1870 if (holder == NULL) {
1871 JVMCI_THROW_0(NullPointerException);
1872 }
1873 InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));
1874 if (ik->class_loader_data()->is_builtin_class_loader_data()) {
1875 return true;
1876 }
1877 return false;
1878 C2V_END
1879
1880 C2V_VMENTRY(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
1881 if (object == NULL) {
1882 JVMCI_THROW_0(NullPointerException);
1883 }
1884 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
1885 if (java_lang_Class::is_instance(obj())) {
1886 if (java_lang_Class::is_primitive(obj())) {
1887 JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()));
1888 return JVMCIENV->get_jobject(type);
1889 }
1890 Klass* klass = java_lang_Class::as_Klass(obj());
1891 JVMCIKlassHandle klass_handle(THREAD);
1892 klass_handle = klass;
1893 JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
1894 return JVMCIENV->get_jobject(type);
1895 }
1896 return NULL;
1897 C2V_END
1898
1899
1900 C2V_VMENTRY(jobject, asString, (JNIEnv* env, jobject, jobject object))
1901 if (object == NULL) {
1902 JVMCI_THROW_0(NullPointerException);
1903 }
1904 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
1905 const char* str = java_lang_String::as_utf8_string(obj());
1906 JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
1907 return JVMCIENV->get_jobject(result);
1908 C2V_END
1909
1910
1911 C2V_VMENTRY(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
1912 if (x == NULL || y == NULL) {
1913 JVMCI_THROW_0(NullPointerException);
1914 }
1915 return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);
1916 C2V_END
1917
1918 C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
1919 if (object == NULL) {
1920 JVMCI_THROW_0(NullPointerException);
1921 }
1922 JVMCIObject base_object = JVMCIENV->wrap(object);
1923 Handle mirror;
1924 if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
1925 mirror = Handle(THREAD, JVMCIENV->asKlass(base_object)->java_mirror());
1926 } else if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(base_object)) {
1927 mirror = JVMCIENV->asConstant(JVMCIENV->get_HotSpotResolvedPrimitiveType_mirror(base_object), JVMCI_CHECK_NULL);
1928 } else {
1929 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
1930 err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
1931 }
1932 JVMCIObject result = JVMCIENV->get_object_constant(mirror());
1933 return JVMCIENV->get_jobject(result);
1934 C2V_END
1935
1936
1937 C2V_VMENTRY(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
1938 if (x == NULL) {
1939 JVMCI_THROW_0(NullPointerException);
1940 }
1941 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
1942 if (xobj->klass()->is_array_klass()) {
1943 return arrayOop(xobj())->length();
1944 }
1945 return -1;
1946 C2V_END
1947
1948
1949 C2V_VMENTRY(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
1950 if (x == NULL) {
1951 JVMCI_THROW_0(NullPointerException);
1952 }
1953 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
1954 if (xobj->klass()->is_array_klass()) {
1955 arrayOop array = arrayOop(xobj());
1956 BasicType element_type = ArrayKlass::cast(array->klass())->element_type();
1957 if (index < 0 || index >= array->length()) {
1958 return NULL;
1959 }
1960 JVMCIObject result;
1961
1962 if (element_type == T_OBJECT) {
1963 result = JVMCIENV->get_object_constant(objArrayOop(xobj())->obj_at(index));
1964 if (result.is_null()) {
1965 result = JVMCIENV->get_JavaConstant_NULL_POINTER();
1966 }
1967 } else {
1968 jvalue value;
1969 switch (element_type) {
1970 case T_DOUBLE: value.d = typeArrayOop(xobj())->double_at(index); break;
1971 case T_FLOAT: value.f = typeArrayOop(xobj())->float_at(index); break;
1972 case T_LONG: value.j = typeArrayOop(xobj())->long_at(index); break;
1973 case T_INT: value.i = typeArrayOop(xobj())->int_at(index); break;
1974 case T_SHORT: value.s = typeArrayOop(xobj())->short_at(index); break;
1975 case T_CHAR: value.c = typeArrayOop(xobj())->char_at(index); break;
1976 case T_BYTE: value.b = typeArrayOop(xobj())->byte_at(index); break;
1977 case T_BOOLEAN: value.z = typeArrayOop(xobj())->byte_at(index) & 1; break;
1978 default: ShouldNotReachHere();
1979 }
1980 result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);
1981 }
1982 assert(!result.is_null(), "must have a value");
1983 return JVMCIENV->get_jobject(result);
1984 }
1985 return NULL;;
1986 C2V_END
1987
1988
1989 C2V_VMENTRY(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
1990 if (kind == NULL) {
1991 JVMCI_THROW_0(NullPointerException);
1992 }
1993 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
1994 return arrayOopDesc::header_size(type) * HeapWordSize;
1995 C2V_END
1996
1997 C2V_VMENTRY(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
1998 if (kind == NULL) {
1999 JVMCI_THROW_0(NullPointerException);
2000 }
2001 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
2002 return type2aelembytes(type);
2003 C2V_END
2004
2005 C2V_VMENTRY(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
2006 if (x == NULL) {
2007 JVMCI_THROW_0(NullPointerException);
2008 }
2009 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2010 return xobj->byte_field(displacement);
2011 }
2012
2013 C2V_VMENTRY(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
2014 if (x == NULL) {
2015 JVMCI_THROW_0(NullPointerException);
2016 }
2017 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2018 return xobj->short_field(displacement);
2019 }
2020
2021 C2V_VMENTRY(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
2022 if (x == NULL) {
2023 JVMCI_THROW_0(NullPointerException);
2024 }
2025 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2026 return xobj->int_field(displacement);
2027 }
2028
2029 C2V_VMENTRY(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
2030 if (x == NULL) {
2031 JVMCI_THROW_0(NullPointerException);
2032 }
2033 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2034 return xobj->long_field(displacement);
2035 }
2036
2037 C2V_VMENTRY(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
2038 if (x == NULL) {
2039 JVMCI_THROW_0(NullPointerException);
2040 }
2041 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2042 oop res = xobj->obj_field(displacement);
2043 JVMCIObject result = JVMCIENV->get_object_constant(res);
2044 return JVMCIENV->get_jobject(result);
2045 }
2046
2047 C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong h))
2048 jobject handle = (jobject)(address)h;
2049 if (handle != NULL) {
2050 assert(JVMCI::is_global_handle(handle), "Invalid delete of global JNI handle");
2051 *((oop*)handle) = NULL; // Mark the handle as deleted, allocate will reuse it
2052 }
2053 }
2054
2055 C2V_VMENTRY(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
2056 if (!UseJVMCINativeLibrary) {
2057 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
2058 }
2059 if (!JVMCIENV->is_hotspot()) {
2060 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "Cannot call registerNativeMethods from JVMCI shared library");
2061 }
2062 void* shared_library = JVMCIEnv::get_shared_library_handle();
2063 if (shared_library == NULL) {
2064 // Ensure the JVMCI shared library runtime is initialized.
2065 JVMCIEnv __peer_jvmci_env__(false, __FILE__, __LINE__);
2066 JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2067 HandleMark hm;
2068 JVMCIRuntime* runtime = JVMCI::compiler_runtime();
2069 JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
2070 if (peerEnv->has_pending_exception()) {
2071 peerEnv->describe_pending_exception(true);
2072 JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
2073 }
2074 shared_library = JVMCIEnv::get_shared_library_handle();
2075 }
2076
2077 if (shared_library == NULL) {
2078 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is unavailable");
2079 }
2080
2081 if (mirror == NULL) {
2082 JVMCI_THROW_0(NullPointerException);
2083 }
2084 Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
2085 if (klass == NULL || !klass->is_instance_klass()) {
2086 JVMCI_THROW_MSG_0(IllegalArgumentException, "clazz is for primitive type");
2087 }
2088
2089 InstanceKlass* iklass = InstanceKlass::cast(klass);
2090 for (int i = 0; i < iklass->methods()->length(); i++) {
2091 Method* method = iklass->methods()->at(i);
2092 if (method->is_native()) {
2093
2094 // Compute argument size
2095 int args_size = 1 // JNIEnv
2096 + (method->is_static() ? 1 : 0) // class for static methods
2097 + method->size_of_parameters(); // actual parameters
2098
2099 // 1) Try JNI short style
2100 stringStream st;
2101 char* pure_name = NativeLookup::pure_jni_name(method);
2102 os::print_jni_name_prefix_on(&st, args_size);
2103 st.print_raw(pure_name);
2104 os::print_jni_name_suffix_on(&st, args_size);
2105 char* jni_name = st.as_string();
2106
2107 address entry = (address) os::dll_lookup(shared_library, jni_name);
2108 if (entry == NULL) {
2109 // 2) Try JNI long style
2110 st.reset();
2111 char* long_name = NativeLookup::long_jni_name(method);
2112 os::print_jni_name_prefix_on(&st, args_size);
2113 st.print_raw(pure_name);
2114 st.print_raw(long_name);
2115 os::print_jni_name_suffix_on(&st, args_size);
2116 jni_name = st.as_string();
2117 entry = (address) os::dll_lookup(shared_library, jni_name);
2118 }
2119 if (entry == NULL) {
2120 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, method->name_and_sig_as_C_string());
2121 }
2122 if (method->has_native_function() && entry != method->native_function()) {
2123 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("Cannot overwrite existing native implementation for %s",
2124 method->name_and_sig_as_C_string()));
2125 }
2126 method->set_native_function(entry, Method::native_bind_event_is_interesting);
2127 if (PrintJNIResolving) {
2128 tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
2129 method->method_holder()->external_name(),
2130 method->name()->as_C_string());
2131 }
2132 }
2133 }
2134
2135 JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
2136 JVMCIPrimitiveArray result = JVMCIENV->new_longArray(4, JVMCI_CHECK_NULL);
2137 JVMCIENV->put_long_at(result, 0, (jlong) (address) javaVM);
2138 JVMCIENV->put_long_at(result, 1, (jlong) (address) javaVM->functions->reserved0);
2139 JVMCIENV->put_long_at(result, 2, (jlong) (address) javaVM->functions->reserved1);
2140 JVMCIENV->put_long_at(result, 3, (jlong) (address) javaVM->functions->reserved2);
2141 return (jlongArray) JVMCIENV->get_jobject(result);
2142 }
2143
2144 C2V_VMENTRY(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
2145 if (obj_handle == NULL) {
2146 return 0L;
2147 }
2148 JVMCIEnv __peer_jvmci_env__(!JVMCIENV->is_hotspot(), __FILE__, __LINE__);
2149 JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2150 JVMCIEnv* thisEnv = JVMCIENV;
2151
2152 JVMCIObject obj = thisEnv->wrap(obj_handle);
2153 JVMCIObject result;
2154 if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
2155 Method* method = thisEnv->asMethod(obj);
2156 result = peerEnv->get_jvmci_method(method, JVMCI_CHECK_0);
2157 } else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
2158 Klass* klass = thisEnv->asKlass(obj);
2159 JVMCIKlassHandle klass_handle(THREAD);
2160 klass_handle = klass;
2161 result = peerEnv->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
2162 } else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
2163 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
2164 result = peerEnv->get_jvmci_primitive_type(type);
2165 } else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
2166 thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
2167 Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
2168 result = peerEnv->get_object_constant(constant());
2199 if (peerEnv->is_hotspot()) {
2200 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2201 if (data == NULL) {
2202 JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");
2203 }
2204 if (data->get_nmethod_mirror(nm) != NULL) {
2205 JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod");
2206 }
2207 oop nmethod_mirror = HotSpotJVMCI::resolve(result);
2208 data->set_nmethod_mirror(nm, nmethod_mirror);
2209 }
2210 }
2211 }
2212 } else {
2213 JVMCI_THROW_MSG_0(IllegalArgumentException,
2214 err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));
2215 }
2216 return (jlong) peerEnv->make_global(result).as_jobject();
2217 }
2218
2219 C2V_VMENTRY(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
2220 if (obj_handle == 0L) {
2221 return NULL;
2222 }
2223 jobject global_handle = (jobject) obj_handle;
2224 JVMCIObject global_handle_obj = JVMCIENV->wrap((jobject) obj_handle);
2225 jobject result = JVMCIENV->make_local(global_handle_obj).as_jobject();
2226
2227 JVMCIENV->destroy_global(global_handle_obj);
2228 return result;
2229 }
2230
2231 C2V_VMENTRY(void, updateHotSpotNmethod, (JNIEnv* env, jobject, jobject code_handle))
2232 JVMCIObject code = JVMCIENV->wrap(code_handle);
2233 // Execute this operation for the side effect of updating the InstalledCode state
2234 JVMCIENV->asNmethod(code);
2235 }
2236
2237 C2V_VMENTRY(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
2238 JVMCIObject code = JVMCIENV->wrap(code_handle);
2239 CodeBlob* cb = JVMCIENV->asCodeBlob(code);
2240 if (cb == NULL) {
2241 return NULL;
2242 }
2243 int code_size = cb->code_size();
2244 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
2245 JVMCIENV->copy_bytes_from((jbyte*) cb->code_begin(), result, 0, code_size);
2246 return JVMCIENV->get_jbyteArray(result);
2247 }
2248
2249 C2V_VMENTRY(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
2250 if (env != JavaThread::current()->jni_environment()) {
2251 JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
2252 }
2253 methodHandle m = JVMCIENV->asMethod(jvmci_method);
2254 oop executable;
2255 if (m->is_initializer()) {
2256 if (m->is_static_initializer()) {
2257 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2258 "Cannot create java.lang.reflect.Method for class initializer");
2259 }
2260 executable = Reflection::new_constructor(m, CHECK_NULL);
2261 } else {
2262 executable = Reflection::new_method(m, false, CHECK_NULL);
2263 }
2264 return JNIHandles::make_local(THREAD, executable);
2265 }
2266
2267 C2V_VMENTRY(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
2268 if (env != JavaThread::current()->jni_environment()) {
2269 JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
2270 }
2271 Klass* klass = JVMCIENV->asKlass(jvmci_type);
2272 if (!klass->is_instance_klass()) {
2273 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2274 err_msg("Expected non-primitive type, got %s", klass->external_name()));
2275 }
2276 InstanceKlass* iklass = InstanceKlass::cast(klass);
2277 Array<u2>* fields = iklass->fields();
2278 if (index < 0 ||index > fields->length()) {
2279 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2280 err_msg("Field index %d out of bounds for %s", index, klass->external_name()));
2281 }
2282 fieldDescriptor fd(iklass, index);
2283 oop reflected = Reflection::new_field(&fd, CHECK_NULL);
2284 return JNIHandles::make_local(env, reflected);
2285 }
2286
2287 C2V_VMENTRY(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
2288 FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);
2289 int result_length = 0;
2290 for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {
2291 result_length++;
2292 }
2293 int current_length = 0;
2294 JVMCIObjectArray current_array = NULL;
2295 if (current != NULL) {
2296 current_array = JVMCIENV->wrap(current);
2297 current_length = JVMCIENV->get_length(current_array);
2298 if (current_length == result_length) {
2299 // No new failures
2300 return current;
2301 }
2302 }
2303 JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);
2304 int result_index = 0;
2305 for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {
2306 assert(fs != NULL, "npe");
2307 JVMCIPrimitiveArray entry;
2308 if (result_index < current_length) {
2309 entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index);
2310 } else {
2311 entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);
2312 JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());
2313 }
2314 JVMCIENV->put_object_at(result, result_index++, entry);
2315 }
2316 return JVMCIENV->get_jobjectArray(result);
2317 }
2318
2319 C2V_VMENTRY(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
2320 methodHandle method = JVMCIENV->asMethod(jvmci_method);
2321 MethodData* method_data = method->method_data();
2322 if (method_data == NULL) {
2323 ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
2324 method_data = MethodData::allocate(loader_data, method, CHECK_0);
2325 method->set_method_data(method_data);
2326 }
2327 return (jlong) method_data->get_failed_speculations_address();
2328 }
2329
2330 C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
2331 FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
2332 }
2333
2334 C2V_VMENTRY(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
2335 JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
2336 int speculation_len = JVMCIENV->get_length(speculation_handle);
2337 char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
2338 JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);
2339 return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
2340 }
2341
2342 #define CC (char*) /*cast a literal from (const char*)*/
2343 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
2344
2345 #define STRING "Ljava/lang/String;"
2346 #define OBJECT "Ljava/lang/Object;"
2347 #define CLASS "Ljava/lang/Class;"
2348 #define OBJECTCONSTANT "Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;"
2349 #define HANDLECONSTANT "Ljdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl;"
2350 #define EXECUTABLE "Ljava/lang/reflect/Executable;"
2351 #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;"
2352 #define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;"
2353 #define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;"
2354 #define BYTECODE_FRAME "Ljdk/vm/ci/code/BytecodeFrame;"
2414 {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
2415 {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE "J[B)I", FN_PTR(installCode)},
2416 {CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},
2417 {CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
2418 {CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
2419 {CC "executeHotSpotNmethod", CC "([" OBJECT HS_NMETHOD ")" OBJECT, FN_PTR(executeHotSpotNmethod)},
2420 {CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},
2421 {CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},
2422 {CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},
2423 {CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},
2424 {CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(invalidateHotSpotNmethod)},
2425 {CC "readUncompressedOop", CC "(J)" OBJECTCONSTANT, FN_PTR(readUncompressedOop)},
2426 {CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
2427 {CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},
2428 {CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},
2429 {CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
2430 {CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
2431 {CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},
2432 {CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
2433 {CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
2434 {CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
2435 {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
2436 {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
2437 {CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
2438 {CC "getHostClass", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getHostClass)},
2439 {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
2440 {CC "compileToBytecode", CC "(" OBJECTCONSTANT ")V", FN_PTR(compileToBytecode)},
2441 {CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)},
2442 {CC "getObjectAtAddress", CC "(J)" OBJECT, FN_PTR(getObjectAtAddress)},
2443 {CC "getInterfaces", CC "(" HS_RESOLVED_KLASS ")[" HS_RESOLVED_KLASS, FN_PTR(getInterfaces)},
2444 {CC "getComponentType", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_TYPE, FN_PTR(getComponentType)},
2445 {CC "ensureInitialized", CC "(" HS_RESOLVED_KLASS ")V", FN_PTR(ensureInitialized)},
2446 {CC "getIdentityHashCode", CC "(" OBJECTCONSTANT ")I", FN_PTR(getIdentityHashCode)},
2447 {CC "isInternedString", CC "(" OBJECTCONSTANT ")Z", FN_PTR(isInternedString)},
2448 {CC "unboxPrimitive", CC "(" OBJECTCONSTANT ")" OBJECT, FN_PTR(unboxPrimitive)},
2449 {CC "boxPrimitive", CC "(" OBJECT ")" OBJECTCONSTANT, FN_PTR(boxPrimitive)},
2450 {CC "getDeclaredConstructors", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredConstructors)},
2451 {CC "getDeclaredMethods", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredMethods)},
2452 {CC "readFieldValue", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_FIELD "Z)" JAVACONSTANT, FN_PTR(readFieldValue)},
2453 {CC "readFieldValue", CC "(" OBJECTCONSTANT HS_RESOLVED_FIELD "Z)" JAVACONSTANT, FN_PTR(readFieldValue)},
2454 {CC "isInstance", CC "(" HS_RESOLVED_KLASS OBJECTCONSTANT ")Z", FN_PTR(isInstance)},
2455 {CC "isAssignableFrom", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_KLASS ")Z", FN_PTR(isAssignableFrom)},
2456 {CC "isTrustedForIntrinsics", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(isTrustedForIntrinsics)},
2457 {CC "asJavaType", CC "(" OBJECTCONSTANT ")" HS_RESOLVED_TYPE, FN_PTR(asJavaType)},
2458 {CC "asString", CC "(" OBJECTCONSTANT ")" STRING, FN_PTR(asString)},
2459 {CC "equals", CC "(" OBJECTCONSTANT "J" OBJECTCONSTANT "J)Z", FN_PTR(equals)},
2460 {CC "getJavaMirror", CC "(" HS_RESOLVED_TYPE ")" OBJECTCONSTANT, FN_PTR(getJavaMirror)},
2461 {CC "getArrayLength", CC "(" OBJECTCONSTANT ")I", FN_PTR(getArrayLength)},
2462 {CC "readArrayElement", CC "(" OBJECTCONSTANT "I)Ljava/lang/Object;", FN_PTR(readArrayElement)},
2463 {CC "arrayBaseOffset", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayBaseOffset)},
2464 {CC "arrayIndexScale", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayIndexScale)},
2465 {CC "getByte", CC "(" OBJECTCONSTANT "J)B", FN_PTR(getByte)},
2466 {CC "getShort", CC "(" OBJECTCONSTANT "J)S", FN_PTR(getShort)},
2467 {CC "getInt", CC "(" OBJECTCONSTANT "J)I", FN_PTR(getInt)},
2468 {CC "getLong", CC "(" OBJECTCONSTANT "J)J", FN_PTR(getLong)},
2469 {CC "getObject", CC "(" OBJECTCONSTANT "J)" OBJECTCONSTANT, FN_PTR(getObject)},
2470 {CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
2471 {CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
2472 {CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
2473 {CC "unhand", CC "(J)" OBJECT, FN_PTR(unhand)},
2474 {CC "updateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(updateHotSpotNmethod)},
2475 {CC "getCode", CC "(" HS_INSTALLED_CODE ")[B", FN_PTR(getCode)},
2476 {CC "asReflectionExecutable", CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)},
2477 {CC "asReflectionField", CC "(" HS_RESOLVED_KLASS "I)" REFLECTION_FIELD, FN_PTR(asReflectionField)},
2478 {CC "getFailedSpeculations", CC "(J[[B)[[B", FN_PTR(getFailedSpeculations)},
2479 {CC "getFailedSpeculationsAddress", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getFailedSpeculationsAddress)},
2480 {CC "releaseFailedSpeculations", CC "(J)V", FN_PTR(releaseFailedSpeculations)},
2481 {CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)},
2482 };
2483
2484 int CompilerToVM::methods_count() {
2485 return sizeof(methods) / sizeof(JNINativeMethod);
2486 }
|
45 #include "runtime/jniHandles.inline.hpp"
46 #include "runtime/timerTrace.hpp"
47 #include "runtime/vframe_hp.hpp"
48
49 JVMCIKlassHandle::JVMCIKlassHandle(Thread* thread, Klass* klass) {
50 _thread = thread;
51 _klass = klass;
52 if (klass != NULL) {
53 _holder = Handle(_thread, klass->klass_holder());
54 }
55 }
56
57 JVMCIKlassHandle& JVMCIKlassHandle::operator=(Klass* klass) {
58 _klass = klass;
59 if (klass != NULL) {
60 _holder = Handle(_thread, klass->klass_holder());
61 }
62 return *this;
63 }
64
65 static void requireInHotSpot(const char* caller, JVMCI_TRAPS) {
66 if (!JVMCIENV->is_hotspot()) {
67 JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot call %s from JVMCI shared library", caller));
68 }
69 }
70
71 void JNIHandleMark::push_jni_handle_block(JavaThread* thread) {
72 if (thread != NULL) {
73 // Allocate a new block for JNI handles.
74 // Inlined code from jni_PushLocalFrame()
75 JNIHandleBlock* java_handles = thread->active_handles();
76 JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);
77 assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");
78 compile_handles->set_pop_frame_link(java_handles);
79 thread->set_active_handles(compile_handles);
80 }
81 }
82
83 void JNIHandleMark::pop_jni_handle_block(JavaThread* thread) {
84 if (thread != NULL) {
85 // Release our JNI handle block
86 JNIHandleBlock* compile_handles = thread->active_handles();
87 JNIHandleBlock* java_handles = compile_handles->pop_frame_link();
88 thread->set_active_handles(java_handles);
89 compile_handles->set_pop_frame_link(NULL);
90 JNIHandleBlock::release_block(compile_handles, thread); // may block
91 }
92 }
93
94 class JVMCITraceMark : public StackObj {
95 const char* _msg;
96 public:
97 JVMCITraceMark(const char* msg) {
98 _msg = msg;
99 if (JVMCITraceLevel >= 1) {
100 tty->print_cr(PTR_FORMAT " JVMCITrace-1: Enter %s", p2i(JavaThread::current()), _msg);
101 }
102 }
103 ~JVMCITraceMark() {
104 if (JVMCITraceLevel >= 1) {
105 tty->print_cr(PTR_FORMAT " JVMCITrace-1: Exit %s", p2i(JavaThread::current()), _msg);
106 }
107 }
108 };
109
110
111 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
112 assert(_index < _args->length(), "out of bounds");
113 oop arg=((objArrayOop) (_args))->obj_at(_index++);
114 assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
115 return Handle(Thread::current(), arg);
116 }
117
118 // Bring the JVMCI compiler thread into the VM state.
119 #define JVMCI_VM_ENTRY_MARK \
120 ThreadInVMfromNative __tiv(thread); \
121 ResetNoHandleMark rnhm; \
122 HandleMarkCleaner __hm(thread); \
123 Thread* THREAD = thread; \
124 debug_only(VMNativeEntryWrapper __vew;)
125
126 // Native method block that transitions current thread to '_thread_in_vm'.
127 #define C2V_BLOCK(result_type, name, signature) \
128 TRACE_CALL(result_type, jvmci_ ## name signature) \
129 JVMCI_VM_ENTRY_MARK; \
130 ResourceMark rm; \
131 JNI_JVMCIENV(thread, env);
132
133 static Thread* get_current_thread() {
134 return Thread::current_or_null_safe();
135 }
136
137 // Entry to native method implementation that transitions
138 // current thread to '_thread_in_vm'.
139 #define C2V_VMENTRY(result_type, name, signature) \
140 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
141 Thread* base_thread = get_current_thread(); \
142 if (base_thread == NULL) { \
143 env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
144 err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
145 return; \
146 } \
147 assert(base_thread->is_Java_thread(), "just checking");\
148 JavaThread* thread = (JavaThread*) base_thread; \
149 JVMCITraceMark jtm("CompilerToVM::" #name); \
150 C2V_BLOCK(result_type, name, signature)
151
152 #define C2V_VMENTRY_(result_type, name, signature, result) \
153 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
154 Thread* base_thread = get_current_thread(); \
155 if (base_thread == NULL) { \
156 env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
157 err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
158 return result; \
159 } \
160 assert(base_thread->is_Java_thread(), "just checking");\
161 JavaThread* thread = (JavaThread*) base_thread; \
162 JVMCITraceMark jtm("CompilerToVM::" #name); \
163 C2V_BLOCK(result_type, name, signature)
164
165 #define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)
166 #define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)
167
168 // Entry to native method implementation that does not transition
169 // current thread to '_thread_in_vm'.
170 #define C2V_VMENTRY_PREFIX(result_type, name, signature) \
171 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
172 Thread* base_thread = get_current_thread();
173
174 #define C2V_END }
175
176 #define JNI_THROW(caller, name, msg) do { \
177 jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
178 if (__throw_res != JNI_OK) { \
179 tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
180 } \
181 return; \
182 } while (0);
183
184 #define JNI_THROW_(caller, name, msg, result) do { \
185 jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
186 if (__throw_res != JNI_OK) { \
187 tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
188 } \
189 return result; \
190 } while (0)
191
192 jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);
193
194 C2V_VMENTRY_NULL(jobjectArray, readConfiguration, (JNIEnv* env))
195 jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);
196 return config;
197 }
198
199 C2V_VMENTRY_NULL(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
200 #define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
201 #define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
202 JVMCIObject name = JVMCIENV->wrap(name_handle);
203 if (name.is_null()) {
204 JVMCI_THROW_NULL(NullPointerException);
205 }
206 const char* cstring = JVMCIENV->as_utf8_string(name);
207 JVMFlag* flag = JVMFlag::find_flag(cstring, strlen(cstring), /* allow_locked */ true, /* return_flag */ true);
208 if (flag == NULL) {
209 return c2vm;
210 }
211 if (flag->is_bool()) {
212 jvalue prim;
213 prim.z = flag->get_bool();
214 JVMCIObject box = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
215 return JVMCIENV->get_jobject(box);
216 } else if (flag->is_ccstr()) {
217 JVMCIObject value = JVMCIENV->create_string(flag->get_ccstr(), JVMCI_CHECK_NULL);
218 return JVMCIENV->get_jobject(value);
219 } else if (flag->is_intx()) {
220 RETURN_BOXED_LONG(flag->get_intx());
221 } else if (flag->is_int()) {
222 RETURN_BOXED_LONG(flag->get_int());
223 } else if (flag->is_uint()) {
224 RETURN_BOXED_LONG(flag->get_uint());
225 } else if (flag->is_uint64_t()) {
226 RETURN_BOXED_LONG(flag->get_uint64_t());
227 } else if (flag->is_size_t()) {
228 RETURN_BOXED_LONG(flag->get_size_t());
229 } else if (flag->is_uintx()) {
230 RETURN_BOXED_LONG(flag->get_uintx());
231 } else if (flag->is_double()) {
232 RETURN_BOXED_DOUBLE(flag->get_double());
233 } else {
234 JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type);
235 }
236 #undef RETURN_BOXED_LONG
237 #undef RETURN_BOXED_DOUBLE
238 C2V_END
239
240 C2V_VMENTRY_NULL(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
241 requireInHotSpot("getObjectAtAddress", JVMCI_CHECK_NULL);
242 if (oop_address == 0) {
243 JVMCI_THROW_MSG_NULL(InternalError, "Handle must be non-zero");
244 }
245 oop obj = *((oopDesc**) oop_address);
246 if (obj != NULL) {
247 oopDesc::verify(obj);
248 }
249 return JNIHandles::make_local(obj);
250 C2V_END
251
252 C2V_VMENTRY_NULL(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
253 methodHandle method = JVMCIENV->asMethod(jvmci_method);
254
255 int code_size = method->code_size();
256 jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
257
258 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
259 // iterate over all bytecodes and replace non-Java bytecodes
260
261 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
262 Bytecodes::Code code = s.code();
263 Bytecodes::Code raw_code = s.raw_code();
264 int bci = s.bci();
265 int len = s.instruction_size();
266
267 // Restore original byte code.
268 reconstituted_code[bci] = (jbyte) (s.is_wide()? Bytecodes::_wide : code);
269 if (len > 1) {
270 memcpy(reconstituted_code + (bci + 1), s.bcp()+1, len-1);
271 }
272
310
311 case Bytecodes::_fast_aldc_w: {
312 int cpc_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));
313 int cp_index = method->constants()->object_to_cp_index(cpc_index);
314 assert(cp_index < method->constants()->length(), "sanity check");
315 Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);
316 break;
317 }
318
319 default:
320 break;
321 }
322 }
323 }
324
325 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
326 JVMCIENV->copy_bytes_from(reconstituted_code, result, 0, code_size);
327 return JVMCIENV->get_jbyteArray(result);
328 C2V_END
329
330 C2V_VMENTRY_0(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
331 methodHandle method = JVMCIENV->asMethod(jvmci_method);
332 return method->exception_table_length();
333 C2V_END
334
335 C2V_VMENTRY_0(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
336 methodHandle method = JVMCIENV->asMethod(jvmci_method);
337 if (method->exception_table_length() == 0) {
338 return 0L;
339 }
340 return (jlong) (address) method->exception_table_start();
341 C2V_END
342
343 C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
344 requireInHotSpot("asResolvedJavaMethod", JVMCI_CHECK_NULL);
345 oop executable = JNIHandles::resolve(executable_handle);
346 oop mirror = NULL;
347 int slot = 0;
348
349 if (executable->klass() == SystemDictionary::reflect_Constructor_klass()) {
350 mirror = java_lang_reflect_Constructor::clazz(executable);
351 slot = java_lang_reflect_Constructor::slot(executable);
352 } else {
353 assert(executable->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
354 mirror = java_lang_reflect_Method::clazz(executable);
355 slot = java_lang_reflect_Method::slot(executable);
356 }
357 Klass* holder = java_lang_Class::as_Klass(mirror);
358 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
359 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
360 return JVMCIENV->get_jobject(result);
361 }
362
363 C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
364 methodHandle method;
365 JVMCIObject base_object = JVMCIENV->wrap(base);
366 if (base_object.is_null()) {
367 method = *((Method**)(offset));
368 } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
369 Handle obj = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
370 if (obj->is_a(SystemDictionary::ResolvedMethodName_klass())) {
371 method = (Method*) (intptr_t) obj->long_field(offset);
372 } else {
373 JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", obj->klass()->external_name()));
374 }
375 } else if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
376 method = JVMCIENV->asMethod(base_object);
377 }
378 if (method.is_null()) {
379 JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
380 }
381 assert (method.is_null() || method->is_method(), "invalid read");
382 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
383 return JVMCIENV->get_jobject(result);
384 }
385
386 C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
387 constantPoolHandle cp;
388 JVMCIObject object = JVMCIENV->wrap(object_handle);
389 if (object.is_null()) {
390 JVMCI_THROW_NULL(NullPointerException);
391 }
392 if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(object)) {
393 cp = JVMCIENV->asMethod(object)->constMethod()->constants();
394 } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(object)) {
395 cp = InstanceKlass::cast(JVMCIENV->asKlass(object))->constants();
396 } else {
397 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
398 err_msg("Unexpected type: %s", JVMCIENV->klass_name(object)));
399 }
400 assert(!cp.is_null(), "npe");
401
402 JVMCIObject result = JVMCIENV->get_jvmci_constant_pool(cp, JVMCI_CHECK_NULL);
403 return JVMCIENV->get_jobject(result);
404 }
405
406 C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
407 JVMCIKlassHandle klass(THREAD);
408 JVMCIObject base_object = JVMCIENV->wrap(base);
409 jlong base_address = 0;
410 if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) {
411 // klass = JVMCIENV->unhandle(base_object)->klass();
412 if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
413 Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
414 klass = base_oop->klass();
415 } else {
416 assert(false, "What types are we actually expecting here?");
417 }
418 } else if (!compressed) {
419 if (base_object.is_non_null()) {
420 if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
421 base_address = (intptr_t) JVMCIENV->asMethod(base_object);
422 } else if (JVMCIENV->isa_HotSpotConstantPool(base_object)) {
423 base_address = (intptr_t) JVMCIENV->asConstantPool(base_object);
424 } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
425 base_address = (intptr_t) JVMCIENV->asKlass(base_object);
426 } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
429 base_address = (jlong) (address) base_oop();
430 }
431 }
432 if (base_address == 0) {
433 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
434 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", JVMCIENV->klass_name(base_object), offset, compressed ? "true" : "false"));
435 }
436 }
437 klass = *((Klass**) (intptr_t) (base_address + offset));
438 } else {
439 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
440 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s",
441 base_object.is_non_null() ? JVMCIENV->klass_name(base_object) : "null",
442 offset, compressed ? "true" : "false"));
443 }
444 assert (klass == NULL || klass->is_klass(), "invalid read");
445 JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
446 return JVMCIENV->get_jobject(result);
447 }
448
449 C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
450 methodHandle method = JVMCIENV->asMethod(jvmci_method);
451 Klass* holder = JVMCIENV->asKlass(jvmci_type);
452 if (holder->is_interface()) {
453 JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
454 }
455
456 methodHandle ucm;
457 {
458 MutexLocker locker(Compile_lock);
459 ucm = Dependencies::find_unique_concrete_method(holder, method());
460 }
461 JVMCIObject result = JVMCIENV->get_jvmci_method(ucm, JVMCI_CHECK_NULL);
462 return JVMCIENV->get_jobject(result);
463 C2V_END
464
465 C2V_VMENTRY_NULL(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
466 Klass* klass = JVMCIENV->asKlass(jvmci_type);
467 if (!klass->is_interface()) {
468 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
469 err_msg("Expected interface type, got %s", klass->external_name()));
470 }
471 InstanceKlass* iklass = InstanceKlass::cast(klass);
472 JVMCIKlassHandle handle(THREAD);
473 {
474 // Need Compile_lock around implementor()
475 MutexLocker locker(Compile_lock);
476 handle = iklass->implementor();
477 }
478 JVMCIObject implementor = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
479 return JVMCIENV->get_jobject(implementor);
480 C2V_END
481
482 C2V_VMENTRY_0(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
483 methodHandle method = JVMCIENV->asMethod(jvmci_method);
484 return method->is_ignored_by_security_stack_walk();
485 C2V_END
486
487 C2V_VMENTRY_0(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
488 methodHandle method = JVMCIENV->asMethod(jvmci_method);
489 constantPoolHandle cp = method->constMethod()->constants();
490 assert(!cp.is_null(), "npe");
491 // don't inline method when constant pool contains a CONSTANT_Dynamic
492 return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
493 C2V_END
494
495 C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
496 methodHandle method = JVMCIENV->asMethod(jvmci_method);
497 return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();
498 C2V_END
499
500 C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
501 methodHandle method = JVMCIENV->asMethod(jvmci_method);
502 return CompilerOracle::should_inline(method) || method->force_inline();
503 C2V_END
504
505 C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
506 JVMCIObject name = JVMCIENV->wrap(jname);
507 const char* str = JVMCIENV->as_utf8_string(name);
508 TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
509
510 if (class_name->utf8_length() <= 1) {
511 JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
512 }
513
514 JVMCIKlassHandle resolved_klass(THREAD);
515 Klass* accessing_klass = NULL;
516 Handle class_loader;
517 Handle protection_domain;
518 if (accessing_class != NULL) {
519 accessing_klass = JVMCIENV->asKlass(accessing_class);
520 class_loader = Handle(THREAD, accessing_klass->class_loader());
521 protection_domain = Handle(THREAD, accessing_klass->protection_domain());
522 } else {
523 // Use the System class loader
524 class_loader = Handle(THREAD, SystemDictionary::java_system_loader());
525 JVMCIENV->runtime()->initialize(JVMCIENV);
526 }
527
528 if (resolve) {
529 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
530 if (resolved_klass == NULL) {
531 JVMCI_THROW_MSG_NULL(ClassNotFoundException, str);
532 }
533 } else {
534 if (class_name->char_at(0) == 'L' &&
535 class_name->char_at(class_name->utf8_length()-1) == ';') {
536 // This is a name from a signature. Strip off the trimmings.
537 // Call recursive to keep scope of strippedsym.
538 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
539 class_name->utf8_length()-2,
540 CHECK_0);
541 resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
542 } else if (FieldType::is_array(class_name)) {
543 FieldArrayInfo fd;
544 // dimension and object_key in FieldArrayInfo are assigned as a side-effect
545 // of this call
546 BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
547 if (t == T_OBJECT) {
548 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
549 class_name->utf8_length()-2-fd.dimension(),
550 CHECK_0);
551 resolved_klass = SystemDictionary::find(strippedsym,
552 class_loader,
553 protection_domain,
554 CHECK_0);
555 if (!resolved_klass.is_null()) {
556 resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0);
557 }
558 } else {
559 resolved_klass = TypeArrayKlass::cast(Universe::typeArrayKlassObj(t))->array_klass(fd.dimension(), CHECK_0);
560 }
561 } else {
562 resolved_klass = SystemDictionary::find(class_name, class_loader, protection_domain, CHECK_0);
563 }
564 }
565 JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
566 return JVMCIENV->get_jobject(result);
567 C2V_END
568
569 C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
570 requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);
571 if (mirror == NULL) {
572 return NULL;
573 }
574 JVMCIKlassHandle klass(THREAD);
575 klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
576 if (klass == NULL) {
577 JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Primitive classes are unsupported");
578 }
579 JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
580 return JVMCIENV->get_jobject(result);
581 }
582
583 C2V_VMENTRY_NULL(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
584 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
585 oop result = cp->resolve_constant_at(index, CHECK_NULL);
586 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
587 C2V_END
588
589 C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
590 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
591 oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
592 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
593 C2V_END
594
595 C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
596 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
597 return cp->name_and_type_ref_index_at(index);
598 C2V_END
599
600 C2V_VMENTRY_NULL(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
601 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
602 JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);
603 return JVMCIENV->get_jobject(sym);
604 C2V_END
605
606 C2V_VMENTRY_NULL(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
607 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
608 JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);
609 return JVMCIENV->get_jobject(sym);
610 C2V_END
611
612 C2V_VMENTRY_0(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
613 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
614 return cp->klass_ref_index_at(index);
615 C2V_END
616
617 C2V_VMENTRY_NULL(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
618 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
619 Klass* klass = cp->klass_at(index, CHECK_NULL);
620 JVMCIKlassHandle resolved_klass(THREAD, klass);
621 if (resolved_klass->is_instance_klass()) {
622 InstanceKlass::cast(resolved_klass())->link_class(CHECK_NULL);
623 if (!InstanceKlass::cast(resolved_klass())->is_linked()) {
624 // link_class() should not return here if there is an issue.
625 JVMCI_THROW_MSG_NULL(InternalError, err_msg("Class %s must be linked", resolved_klass()->external_name()));
626 }
627 }
628 JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
629 return JVMCIENV->get_jobject(klassObject);
630 C2V_END
631
632 C2V_VMENTRY_NULL(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
633 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
634 Klass* loading_klass = cp->pool_holder();
635 bool is_accessible = false;
636 JVMCIKlassHandle klass(THREAD, JVMCIRuntime::get_klass_by_index(cp, index, is_accessible, loading_klass));
637 Symbol* symbol = NULL;
638 if (klass.is_null()) {
639 constantTag tag = cp->tag_at(index);
640 if (tag.is_klass()) {
641 // The klass has been inserted into the constant pool
642 // very recently.
643 klass = cp->resolved_klass_at(index);
644 } else if (tag.is_symbol()) {
645 symbol = cp->symbol_at(index);
646 } else {
647 assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
648 symbol = cp->klass_name_at(index);
649 }
650 }
651 JVMCIObject result;
652 if (!klass.is_null()) {
653 result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
654 } else {
655 result = JVMCIENV->create_string(symbol, JVMCI_CHECK_NULL);
656 }
657 return JVMCIENV->get_jobject(result);
658 C2V_END
659
660 C2V_VMENTRY_NULL(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
661 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
662 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
663 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));
664 C2V_END
665
666 C2V_VMENTRY_NULL(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
667 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
668 InstanceKlass* pool_holder = cp->pool_holder();
669 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
670 methodHandle method = JVMCIRuntime::get_method_by_index(cp, index, bc, pool_holder);
671 JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
672 return JVMCIENV->get_jobject(result);
673 C2V_END
674
675 C2V_VMENTRY_0(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
676 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
677 return cp->remap_instruction_operand_from_cache(index);
678 C2V_END
679
680 C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
681 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
682 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
683 fieldDescriptor fd;
684 LinkInfo link_info(cp, index, (jvmci_method != NULL) ? JVMCIENV->asMethod(jvmci_method) : NULL, CHECK_0);
685 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
686 JVMCIPrimitiveArray info = JVMCIENV->wrap(info_handle);
687 if (info.is_null() || JVMCIENV->get_length(info) != 3) {
688 JVMCI_ERROR_NULL("info must not be null and have a length of 3");
689 }
690 JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int());
691 JVMCIENV->put_int_at(info, 1, fd.offset());
692 JVMCIENV->put_int_at(info, 2, fd.index());
693 JVMCIKlassHandle handle(THREAD, fd.field_holder());
694 JVMCIObject field_holder = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
695 return JVMCIENV->get_jobject(field_holder);
696 C2V_END
697
698 C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
699 Klass* klass = JVMCIENV->asKlass(jvmci_type);
700 Method* method = JVMCIENV->asMethod(jvmci_method);
701 if (klass->is_interface()) {
702 JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name()));
703 }
704 if (!method->method_holder()->is_interface()) {
705 JVMCI_THROW_MSG_0(InternalError, err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
706 }
707 if (!klass->is_instance_klass()) {
708 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
709 }
710 if (!InstanceKlass::cast(klass)->is_linked()) {
711 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name()));
712 }
713 return LinkResolver::vtable_index_of_interface_method(klass, method);
714 C2V_END
715
716 C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
717 Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);
718 Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);
719 methodHandle method = JVMCIENV->asMethod(jvmci_method);
720
721 Klass* resolved = method->method_holder();
722 Symbol* h_name = method->name();
723 Symbol* h_signature = method->signature();
724
725 if (MethodHandles::is_signature_polymorphic_method(method())) {
726 // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.
727 return NULL;
728 }
729
730 if (method->name() == vmSymbols::clone_name() &&
731 resolved == SystemDictionary::Object_klass() &&
732 recv_klass->is_array_klass()) {
733 // Resolution of the clone method on arrays always returns Object.clone even though that method
734 // has protected access. There's some trickery in the access checking to make this all work out
735 // so it's necessary to pass in the array class as the resolved class to properly trigger this.
736 // Otherwise it's impossible to resolve the array clone methods through JVMCI. See
743 // Only do exact lookup if receiver klass has been linked. Otherwise,
744 // the vtable has not been setup, and the LinkResolver will fail.
745 if (recv_klass->is_array_klass() ||
746 (InstanceKlass::cast(recv_klass)->is_linked() && !recv_klass->is_interface())) {
747 if (resolved->is_interface()) {
748 m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info);
749 } else {
750 m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info);
751 }
752 }
753
754 if (m.is_null()) {
755 // Return NULL if there was a problem with lookup (uninitialized class, etc.)
756 return NULL;
757 }
758
759 JVMCIObject result = JVMCIENV->get_jvmci_method(m, JVMCI_CHECK_NULL);
760 return JVMCIENV->get_jobject(result);
761 C2V_END
762
763 C2V_VMENTRY_0(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
764 Klass* klass = JVMCIENV->asKlass(jvmci_type);
765 assert(klass != NULL, "method must not be called for primitive types");
766 return Dependencies::find_finalizable_subclass(klass) != NULL;
767 C2V_END
768
769 C2V_VMENTRY_NULL(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
770 Klass* klass = JVMCIENV->asKlass(jvmci_type);
771 if (!klass->is_instance_klass()) {
772 return NULL;
773 }
774 InstanceKlass* iklass = InstanceKlass::cast(klass);
775 JVMCIObject result = JVMCIENV->get_jvmci_method(iklass->class_initializer(), JVMCI_CHECK_NULL);
776 return JVMCIENV->get_jobject(result);
777 C2V_END
778
779 C2V_VMENTRY_0(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
780 address target_addr = (address) addr;
781 if (target_addr != 0x0) {
782 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
783 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
784 return MAX2(ABS(off_low), ABS(off_high));
785 }
786 return -1;
787 C2V_END
788
789 C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
790 methodHandle method = JVMCIENV->asMethod(jvmci_method);
791 method->set_not_c1_compilable();
792 method->set_not_c2_compilable();
793 method->set_dont_inline(true);
794 C2V_END
795
796 C2V_VMENTRY_0(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
797 jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))
798 HandleMark hm;
799 JNIHandleMark jni_hm(thread);
800
801 JVMCIObject target_handle = JVMCIENV->wrap(target);
802 JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
803 CodeBlob* cb = NULL;
804 JVMCIObject installed_code_handle = JVMCIENV->wrap(installed_code);
805 JVMCIPrimitiveArray speculations_handle = JVMCIENV->wrap(speculations_obj);
806
807 int speculations_len = JVMCIENV->get_length(speculations_handle);
808 char* speculations = NEW_RESOURCE_ARRAY(char, speculations_len);
809 JVMCIENV->copy_bytes_to(speculations_handle, (jbyte*) speculations, 0, speculations_len);
810
811 JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
812
813 TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
814 bool is_immutable_PIC = JVMCIENV->get_HotSpotCompiledCode_isImmutablePIC(compiled_code_handle) > 0;
815
816 CodeInstaller installer(JVMCIENV, is_immutable_PIC);
817 JVMCI::CodeInstallResult result = installer.install(compiler,
818 target_handle,
819 compiled_code_handle,
837
838 if (result != JVMCI::ok) {
839 assert(cb == NULL, "should be");
840 } else {
841 if (installed_code_handle.is_non_null()) {
842 if (cb->is_nmethod()) {
843 assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type");
844 // Clear the link to an old nmethod first
845 JVMCIObject nmethod_mirror = installed_code_handle;
846 JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK_0);
847 } else {
848 assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");
849 }
850 // Initialize the link to the new code blob
851 JVMCIENV->initialize_installed_code(installed_code_handle, cb, JVMCI_CHECK_0);
852 }
853 }
854 return result;
855 C2V_END
856
857 C2V_VMENTRY_0(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
858 #if INCLUDE_AOT
859 HandleMark hm;
860 assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
861
862 JVMCIObject target_handle = JVMCIENV->wrap(target);
863 JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
864 JVMCIObject metadata_handle = JVMCIENV->wrap(metadata);
865
866 CodeMetadata code_metadata;
867
868 CodeInstaller installer(JVMCIENV, true /* immutable PIC compilation */);
869 JVMCI::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, JVMCI_CHECK_0);
870 if (result != JVMCI::ok) {
871 return result;
872 }
873
874 if (code_metadata.get_nr_pc_desc() > 0) {
875 int size = sizeof(PcDesc) * code_metadata.get_nr_pc_desc();
876 JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
877 JVMCIENV->copy_bytes_from((jbyte*) code_metadata.get_pc_desc(), array, 0, size);
918 int table_size = handler->size_in_bytes();
919 JVMCIPrimitiveArray exceptionArray = JVMCIENV->new_byteArray(table_size, JVMCI_CHECK_(JVMCI::cache_full));
920 if (table_size > 0) {
921 handler->copy_bytes_to((address) HotSpotJVMCI::resolve(exceptionArray)->byte_at_addr(0));
922 }
923 HotSpotJVMCI::HotSpotMetaData::set_exceptionBytes(JVMCIENV, metadata_handle, exceptionArray);
924
925 return result;
926 #else
927 JVMCI_THROW_MSG_0(InternalError, "unimplemented");
928 #endif
929 C2V_END
930
931 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv* env, jobject))
932 JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
933 CompilerStatistics* stats = compiler->stats();
934 stats->_standard.reset();
935 stats->_osr.reset();
936 C2V_END
937
938 C2V_VMENTRY_NULL(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
939 HandleMark hm;
940
941 if (installedCode == NULL) {
942 JVMCI_THROW_MSG_NULL(NullPointerException, "installedCode is null");
943 }
944
945 JVMCIObject installedCodeObject = JVMCIENV->wrap(installedCode);
946 CodeBlob* cb = JVMCIENV->asCodeBlob(installedCodeObject);
947 if (cb == NULL) {
948 return NULL;
949 }
950
951 // We don't want the stringStream buffer to resize during disassembly as it
952 // uses scoped resource memory. If a nested function called during disassembly uses
953 // a ResourceMark and the buffer expands within the scope of the mark,
954 // the buffer becomes garbage when that scope is exited. Experience shows that
955 // the disassembled code is typically about 10x the code size so a fixed buffer
956 // sized to 20x code size plus a fixed amount for header info should be sufficient.
957 int bufferSize = cb->code_size() * 20 + 1024;
958 char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);
959 stringStream st(buffer, bufferSize);
960 if (cb->is_nmethod()) {
961 nmethod* nm = (nmethod*) cb;
962 if (!nm->is_alive()) {
963 return NULL;
964 }
965 }
966 Disassembler::decode(cb, &st);
967 if (st.size() <= 0) {
968 return NULL;
969 }
970
971 JVMCIObject result = JVMCIENV->create_string(st.as_string(), JVMCI_CHECK_NULL);
972 return JVMCIENV->get_jobject(result);
973 C2V_END
974
975 C2V_VMENTRY_NULL(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
976 HandleMark hm;
977
978 methodHandle method = JVMCIENV->asMethod(jvmci_method);
979 JVMCIObject element = JVMCIENV->new_StackTraceElement(method, bci, JVMCI_CHECK_NULL);
980 return JVMCIENV->get_jobject(element);
981 C2V_END
982
983 C2V_VMENTRY_NULL(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
984 // The incoming arguments array would have to contain JavaConstants instead of regular objects
985 // and the return value would have to be wrapped as a JavaConstant.
986 requireInHotSpot("executeHotSpotNmethod", JVMCI_CHECK_NULL);
987
988 HandleMark hm;
989
990 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
991 nmethod* nm = JVMCIENV->asNmethod(nmethod_mirror);
992 if (nm == NULL) {
993 JVMCI_THROW_NULL(InvalidInstalledCodeException);
994 }
995 methodHandle mh = nm->method();
996 Symbol* signature = mh->signature();
997 JavaCallArguments jca(mh->size_of_parameters());
998
999 JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
1000 JavaValue result(jap.get_ret_type());
1001 jca.set_alternative_target(nm);
1002 JavaCalls::call(&result, mh, &jca, CHECK_NULL);
1003
1004 if (jap.get_ret_type() == T_VOID) {
1005 return NULL;
1006 } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
1012 case T_BOOLEAN:
1013 value->z = (jboolean) value->i;
1014 break;
1015 case T_BYTE:
1016 value->b = (jbyte) value->i;
1017 break;
1018 case T_CHAR:
1019 value->c = (jchar) value->i;
1020 break;
1021 case T_SHORT:
1022 value->s = (jshort) value->i;
1023 break;
1024 default:
1025 break;
1026 }
1027 JVMCIObject o = JVMCIENV->create_box(jap.get_ret_type(), value, JVMCI_CHECK_NULL);
1028 return JVMCIENV->get_jobject(o);
1029 }
1030 C2V_END
1031
1032 C2V_VMENTRY_NULL(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
1033 Method* method = JVMCIENV->asMethod(jvmci_method);
1034 if (!method->has_linenumber_table()) {
1035 return NULL;
1036 }
1037 u2 num_entries = 0;
1038 CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table());
1039 while (streamForSize.read_pair()) {
1040 num_entries++;
1041 }
1042
1043 CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
1044 JVMCIPrimitiveArray result = JVMCIENV->new_longArray(2 * num_entries, JVMCI_CHECK_NULL);
1045
1046 int i = 0;
1047 jlong value;
1048 while (stream.read_pair()) {
1049 value = ((long) stream.bci());
1050 JVMCIENV->put_long_at(result, i, value);
1051 value = ((long) stream.line());
1052 JVMCIENV->put_long_at(result, i + 1, value);
1053 i += 2;
1054 }
1055
1056 return (jlongArray) JVMCIENV->get_jobject(result);
1057 C2V_END
1058
1059 C2V_VMENTRY_0(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
1060 Method* method = JVMCIENV->asMethod(jvmci_method);
1061 if (!method->has_localvariable_table()) {
1062 return 0;
1063 }
1064 return (jlong) (address) method->localvariable_table_start();
1065 C2V_END
1066
1067 C2V_VMENTRY_0(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
1068 Method* method = JVMCIENV->asMethod(jvmci_method);
1069 return method->localvariable_table_length();
1070 C2V_END
1071
1072 C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, jobject jvmci_method))
1073 Method* method = JVMCIENV->asMethod(jvmci_method);
1074 MethodCounters* mcs = method->method_counters();
1075 if (mcs != NULL) {
1076 mcs->clear_counters();
1077 }
1078 NOT_PRODUCT(method->set_compiled_invocation_count(0));
1079
1080 CompiledMethod* code = method->code();
1081 if (code != NULL) {
1082 code->make_not_entrant();
1083 }
1084
1085 MethodData* method_data = method->method_data();
1086 if (method_data == NULL) {
1087 ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
1088 method_data = MethodData::allocate(loader_data, method, CHECK);
1089 method->set_method_data(method_data);
1090 } else {
1091 method_data->initialize();
1092 }
1093 C2V_END
1094
1095
1096 C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))
1097 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
1098 JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
1099 C2V_END
1100
1101 C2V_VMENTRY_NULL(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
1102 oop ret = RawAccess<>::oop_load((oop*)(address)addr);
1103 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(ret));
1104 C2V_END
1105
1106 C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))
1107 // Returns a zero length array if counters aren't enabled
1108 JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);
1109 if (JVMCICounterSize > 0) {
1110 jlong* temp_array = NEW_RESOURCE_ARRAY(jlong, JVMCICounterSize);
1111 JavaThread::collect_counters(temp_array, JVMCICounterSize);
1112 JVMCIENV->copy_longs_from(temp_array, array, 0, JVMCICounterSize);
1113 }
1114 return (jlongArray) JVMCIENV->get_jobject(array);
1115 C2V_END
1116
1117 C2V_VMENTRY_0(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
1118 HandleMark hm;
1119 if (jvmci_method == NULL) {
1120 JVMCI_THROW_0(NullPointerException);
1121 }
1122 Method* method = JVMCIENV->asMethod(jvmci_method);
1123 if (entry_bci >= method->code_size() || entry_bci < -1) {
1124 JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Unexpected bci %d", entry_bci));
1125 }
1126 return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
1127 C2V_END
1128
1129
1130 C2V_VMENTRY_0(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
1131 MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
1132 return mdo != NULL && mdo->is_mature();
1133 C2V_END
1134
1135 C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
1136 Method* method = JVMCIENV->asMethod(jvmci_method);
1137 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
1138 C2V_END
1139
1140 C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
1141 JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
1142 return JVMCIENV->get_jobject(sym);
1143 C2V_END
1144
1145 bool matches(jobjectArray methods, Method* method, JVMCIEnv* JVMCIENV) {
1146 objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
1147
1148 for (int i = 0; i < methods_oop->length(); i++) {
1149 oop resolved = methods_oop->obj_at(i);
1150 if ((resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) && HotSpotJVMCI::asMethod(JVMCIENV, resolved) == method) {
1151 return true;
1152 }
1153 }
1154 return false;
1155 }
1156
1157 void call_interface(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
1158 CallInfo callinfo;
1159 Handle receiver = args->receiver();
1160 Klass* recvrKlass = receiver.is_null() ? (Klass*)NULL : receiver->klass();
1161 LinkInfo link_info(spec_klass, name, signature);
1162 LinkResolver::resolve_interface_call(
1163 callinfo, receiver, recvrKlass, link_info, true, CHECK);
1164 methodHandle method = callinfo.selected_method();
1165 assert(method.not_null(), "should have thrown exception");
1166
1167 // Invoke the method
1168 JavaCalls::call(result, method, args, CHECK);
1169 }
1170
1171 C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
1172
1173 if (!thread->has_last_Java_frame()) {
1174 return NULL;
1175 }
1176 Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
1177
1178 requireInHotSpot("iterateFrames", JVMCI_CHECK_NULL);
1179
1180 HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
1181 Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
1182
1183 StackFrameStream fst(thread);
1184 jobjectArray methods = initial_methods;
1185
1186 int frame_number = 0;
1187 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
1188
1189 while (true) {
1190 // look for the given method
1191 bool realloc_called = false;
1192 while (true) {
1193 StackValueCollection* locals = NULL;
1194 if (vf->is_compiled_frame()) {
1195 // compiled method frame
1196 compiledVFrame* cvf = compiledVFrame::cast(vf);
1197 if (methods == NULL || matches(methods, cvf->method(), JVMCIENV)) {
1198 if (initialSkip > 0) {
1330 C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1331 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1332 CallInfo callInfo;
1333 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);
1334 ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);
1335 cp_cache_entry->set_dynamic_call(cp, callInfo);
1336 C2V_END
1337
1338 C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1339 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1340 Klass* holder = cp->klass_ref_at(index, CHECK);
1341 Symbol* name = cp->name_ref_at(index);
1342 if (MethodHandles::is_signature_polymorphic_name(holder, name)) {
1343 CallInfo callInfo;
1344 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
1345 ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
1346 cp_cache_entry->set_method_handle(cp, callInfo);
1347 }
1348 C2V_END
1349
1350 C2V_VMENTRY_0(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
1351 constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
1352 ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
1353 if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {
1354 // MethodHandle.invoke* --> LambdaForm?
1355 ResourceMark rm;
1356
1357 LinkInfo link_info(cp, index, CATCH);
1358
1359 Klass* resolved_klass = link_info.resolved_klass();
1360
1361 Symbol* name_sym = cp->name_ref_at(index);
1362
1363 vmassert(MethodHandles::is_method_handle_invoke_name(resolved_klass, name_sym), "!");
1364 vmassert(MethodHandles::is_signature_polymorphic_name(resolved_klass, name_sym), "!");
1365
1366 methodHandle adapter_method(cp_cache_entry->f1_as_method());
1367
1368 methodHandle resolved_method(adapter_method);
1369
1370 // Can we treat it as a regular invokevirtual?
1371 if (resolved_method->method_holder() == resolved_klass && resolved_method->name() == name_sym) {
1372 vmassert(!resolved_method->is_static(),"!");
1373 vmassert(MethodHandles::is_signature_polymorphic_method(resolved_method()),"!");
1374 vmassert(!MethodHandles::is_signature_polymorphic_static(resolved_method->intrinsic_id()), "!");
1375 vmassert(cp_cache_entry->appendix_if_resolved(cp) == NULL, "!");
1376
1377 methodHandle m(LinkResolver::linktime_resolve_virtual_method_or_null(link_info));
1378 vmassert(m == resolved_method, "!!");
1379 return -1;
1380 }
1381
1382 return Bytecodes::_invokevirtual;
1383 }
1384 if (cp_cache_entry->is_resolved(Bytecodes::_invokedynamic)) {
1385 return Bytecodes::_invokedynamic;
1386 }
1387 return -1;
1388 C2V_END
1389
1390
1391 C2V_VMENTRY_NULL(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
1392 JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);
1393 JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);
1394 JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);
1395 JVMCIENV->put_object_at(holders, 0, mh);
1396 JVMCIENV->put_object_at(holders, 1, vh);
1397 return JVMCIENV->get_jobject(holders);
1398 C2V_END
1399
1400 C2V_VMENTRY_0(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
1401 //see compute_recording_non_safepoints in debugInfroRec.cpp
1402 if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
1403 return true;
1404 }
1405 return DebugNonSafepoints;
1406 C2V_END
1407
1408 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
1409 C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_frame, bool invalidate))
1410 JVMCIObject hs_frame = JVMCIENV->wrap(_hs_frame);
1411 if (hs_frame.is_null()) {
1412 JVMCI_THROW_MSG(NullPointerException, "stack frame is null");
1413 }
1414
1415 requireInHotSpot("materializeVirtualObjects", JVMCI_CHECK);
1416
1417 JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);
1418
1419 // look for the given stack frame
1420 StackFrameStream fst(thread);
1421 intptr_t* stack_pointer = (intptr_t*) JVMCIENV->get_HotSpotStackFrameReference_stackPointer(hs_frame);
1422 while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
1423 fst.next();
1424 }
1425 if (fst.current()->sp() != stack_pointer) {
1426 JVMCI_THROW_MSG(IllegalStateException, "stack frame not found");
1427 }
1428
1429 if (invalidate) {
1430 if (!fst.current()->is_compiled_frame()) {
1431 JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");
1432 }
1433 assert(fst.current()->cb()->is_nmethod(), "nmethod expected");
1434 ((nmethod*) fst.current()->cb())->make_not_entrant();
1435 }
1510 for (int i2 = 0; i2 < monitors->length(); i2++) {
1511 cvf->update_monitor(i2, monitors->at(i2));
1512 }
1513 }
1514 }
1515
1516 // all locals are materialized by now
1517 JVMCIENV->set_HotSpotStackFrameReference_localIsVirtual(hs_frame, NULL);
1518 // update the locals array
1519 JVMCIObjectArray array = JVMCIENV->get_HotSpotStackFrameReference_locals(hs_frame);
1520 StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();
1521 for (int i = 0; i < locals->size(); i++) {
1522 StackValue* var = locals->at(i);
1523 if (var->type() == T_OBJECT) {
1524 JVMCIENV->put_object_at(array, i, HotSpotJVMCI::wrap(locals->at(i)->get_obj()()));
1525 }
1526 }
1527 HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);
1528 C2V_END
1529
1530 // Creates a scope where the current thread is attached and detached
1531 // from HotSpot if it wasn't already attached when entering the scope.
1532 extern "C" void jio_printf(const char *fmt, ...);
1533 class AttachDetach : public StackObj {
1534 public:
1535 bool _attached;
1536 AttachDetach(JNIEnv* env, Thread* current_thread) {
1537 if (current_thread == NULL) {
1538 extern struct JavaVM_ main_vm;
1539 JNIEnv* hotspotEnv;
1540 jint res = main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
1541 _attached = res == JNI_OK;
1542 static volatile int report_attach_error = 0;
1543 if (res != JNI_OK && report_attach_error == 0 && Atomic::cmpxchg(1, &report_attach_error, 0) == 0) {
1544 // Only report an attach error once
1545 jio_printf("Warning: attaching current thread to VM failed with %d (future attach errors are suppressed)\n", res);
1546 }
1547 } else {
1548 _attached = false;
1549 }
1550 }
1551 ~AttachDetach() {
1552 if (_attached && get_current_thread() != NULL) {
1553 extern struct JavaVM_ main_vm;
1554 jint res = main_vm.DetachCurrentThread();
1555 static volatile int report_detach_error = 0;
1556 if (res != JNI_OK && report_detach_error == 0 && Atomic::cmpxchg(1, &report_detach_error, 0) == 0) {
1557 // Only report an attach error once
1558 jio_printf("Warning: detaching current thread from VM failed with %d (future attach errors are suppressed)\n", res);
1559 }
1560 }
1561 }
1562 };
1563
1564 C2V_VMENTRY_PREFIX(jint, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length, bool flush, bool can_throw))
1565 AttachDetach ad(env, base_thread);
1566 bool use_tty = true;
1567 if (base_thread == NULL) {
1568 if (!ad._attached) {
1569 // Can only use tty if the current thread is attached
1570 return 0;
1571 }
1572 base_thread = get_current_thread();
1573 }
1574 JVMCITraceMark jtm("writeDebugOutput");
1575 assert(base_thread->is_Java_thread(), "just checking");
1576 JavaThread* thread = (JavaThread*) base_thread;
1577 C2V_BLOCK(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
1578 if (bytes == NULL) {
1579 if (can_throw) {
1580 JVMCI_THROW_0(NullPointerException);
1581 }
1582 return -1;
1583 }
1584 JVMCIPrimitiveArray array = JVMCIENV->wrap(bytes);
1585
1586 // Check if offset and length are non negative.
1587 if (offset < 0 || length < 0) {
1588 if (can_throw) {
1589 JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
1590 }
1591 return -2;
1592 }
1593 // Check if the range is valid.
1594 int array_length = JVMCIENV->get_length(array);
1595 if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array_length)) {
1596 if (can_throw) {
1597 JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
1598 }
1599 return -2;
1600 }
1601 jbyte buffer[O_BUFLEN];
1602 while (length > 0) {
1603 int copy_len = MIN2(length, (jint)O_BUFLEN);
1604 JVMCIENV->copy_bytes_to(array, buffer, offset, copy_len);
1605 tty->write((char*) buffer, copy_len);
1606 length -= O_BUFLEN;
1607 offset += O_BUFLEN;
1608 }
1609 if (flush) {
1610 tty->flush();
1611 }
1612 return 0;
1613 C2V_END
1614
1615 C2V_VMENTRY(void, flushDebugOutput, (JNIEnv* env, jobject))
1616 tty->flush();
1617 C2V_END
1618
1619 C2V_VMENTRY_0(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
1620 MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
1621 ProfileData* profile_data = mdo->data_at(position);
1622 if (mdo->is_valid(profile_data)) {
1623 return profile_data->size_in_bytes();
1624 }
1625 DataLayout* data = mdo->extra_data_base();
1626 DataLayout* end = mdo->extra_data_limit();
1627 for (;; data = mdo->next_extra(data)) {
1628 assert(data < end, "moved past end of extra data");
1629 profile_data = data->data_in();
1630 if (mdo->dp_to_di(profile_data->dp()) == position) {
1631 return profile_data->size_in_bytes();
1632 }
1633 }
1634 JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));
1635 C2V_END
1636
1637 C2V_VMENTRY_0(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
1638 #if INCLUDE_AOT
1639 Klass *k = (Klass*) (address) metaspace_klass;
1640 if (k->is_instance_klass()) {
1641 return InstanceKlass::cast(k)->get_stored_fingerprint();
1642 } else {
1643 return 0;
1644 }
1645 #else
1646 JVMCI_THROW_MSG_0(InternalError, "unimplemented");
1647 #endif
1648 C2V_END
1649
1650 C2V_VMENTRY_NULL(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
1651 InstanceKlass* k = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
1652 InstanceKlass* host = k->unsafe_anonymous_host();
1653 JVMCIKlassHandle handle(THREAD, host);
1654 JVMCIObject result = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
1655 return JVMCIENV->get_jobject(result);
1656 C2V_END
1657
1658 C2V_VMENTRY_NULL(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
1659 if (jvmci_type == NULL) {
1660 JVMCI_THROW_0(NullPointerException);
1661 }
1662
1663 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1664 if (klass == NULL) {
1665 JVMCI_THROW_0(NullPointerException);
1666 }
1667 if (!klass->is_instance_klass()) {
1668 JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
1669 }
1670 InstanceKlass* iklass = InstanceKlass::cast(klass);
1671
1672 // Regular instance klass, fill in all local interfaces
1673 int size = iklass->local_interfaces()->length();
1674 JVMCIObjectArray interfaces = JVMCIENV->new_HotSpotResolvedObjectTypeImpl_array(size, JVMCI_CHECK_NULL);
1675 for (int index = 0; index < size; index++) {
1676 JVMCIKlassHandle klass(THREAD);
1677 Klass* k = iklass->local_interfaces()->at(index);
1678 klass = k;
1679 JVMCIObject type = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
1680 JVMCIENV->put_object_at(interfaces, index, type);
1681 }
1682 return JVMCIENV->get_jobject(interfaces);
1683 C2V_END
1684
1685 C2V_VMENTRY_NULL(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
1686 if (jvmci_type == NULL) {
1687 JVMCI_THROW_0(NullPointerException);
1688 }
1689
1690 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1691 oop mirror = klass->java_mirror();
1692 if (java_lang_Class::is_primitive(mirror) ||
1693 !java_lang_Class::as_Klass(mirror)->is_array_klass()) {
1694 return NULL;
1695 }
1696
1697 oop component_mirror = java_lang_Class::component_mirror(mirror);
1698 if (component_mirror == NULL) {
1699 return NULL;
1700 }
1701 Klass* component_klass = java_lang_Class::as_Klass(component_mirror);
1702 if (component_klass != NULL) {
1703 JVMCIKlassHandle klass_handle(THREAD);
1704 klass_handle = component_klass;
1705 JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
1706 return JVMCIENV->get_jobject(result);
1707 }
1708 BasicType type = java_lang_Class::primitive_type(component_mirror);
1709 JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type);
1710 return JVMCIENV->get_jobject(result);
1711 C2V_END
1712
1713 C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, jobject jvmci_type))
1714 if (jvmci_type == NULL) {
1715 JVMCI_THROW(NullPointerException);
1716 }
1717
1718 Klass* klass = JVMCIENV->asKlass(jvmci_type);
1719 if (klass != NULL && klass->should_be_initialized()) {
1720 InstanceKlass* k = InstanceKlass::cast(klass);
1721 k->initialize(CHECK);
1722 }
1723 C2V_END
1724
1725 C2V_VMENTRY_0(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
1726 if (bytecode_frame_handle == NULL) {
1727 JVMCI_THROW_0(NullPointerException);
1728 }
1729
1730 JVMCIObject top_bytecode_frame = JVMCIENV->wrap(bytecode_frame_handle);
1731 JVMCIObject bytecode_frame = top_bytecode_frame;
1732 int size = 0;
1733 int callee_parameters = 0;
1734 int callee_locals = 0;
1735 Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
1736 int extra_args = method->max_stack() - JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
1737
1738 while (bytecode_frame.is_non_null()) {
1739 int locks = JVMCIENV->get_BytecodeFrame_numLocks(bytecode_frame);
1740 int temps = JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
1741 bool is_top_frame = (JVMCIENV->equals(bytecode_frame, top_bytecode_frame));
1742 Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
1743
1744 int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
1745 temps + callee_parameters,
1753 callee_parameters = method->size_of_parameters();
1754 callee_locals = method->max_locals();
1755 extra_args = 0;
1756 bytecode_frame = JVMCIENV->get_BytecodePosition_caller(bytecode_frame);
1757 }
1758 return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
1759 C2V_END
1760
1761 C2V_VMENTRY(void, compileToBytecode, (JNIEnv* env, jobject, jobject lambda_form_handle))
1762 Handle lambda_form = JVMCIENV->asConstant(JVMCIENV->wrap(lambda_form_handle), JVMCI_CHECK);
1763 if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) {
1764 TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK);
1765 JavaValue result(T_VOID);
1766 JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);
1767 } else {
1768 JVMCI_THROW_MSG(IllegalArgumentException,
1769 err_msg("Unexpected type: %s", lambda_form->klass()->external_name()))
1770 }
1771 C2V_END
1772
1773 C2V_VMENTRY_0(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
1774 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1775 return obj->identity_hash();
1776 C2V_END
1777
1778 C2V_VMENTRY_0(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
1779 Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1780 if (!java_lang_String::is_instance(str())) {
1781 return false;
1782 }
1783 int len;
1784 jchar* name = java_lang_String::as_unicode_string(str(), len, CHECK_0);
1785 return (StringTable::lookup(name, len) != NULL);
1786 C2V_END
1787
1788
1789 C2V_VMENTRY_NULL(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
1790 if (object == NULL) {
1791 JVMCI_THROW_0(NullPointerException);
1792 }
1793 Handle box = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
1794 BasicType type = java_lang_boxing_object::basic_type(box());
1795 jvalue result;
1796 if (java_lang_boxing_object::get_value(box(), &result) == T_ILLEGAL) {
1797 return NULL;
1798 }
1799 JVMCIObject boxResult = JVMCIENV->create_box(type, &result, JVMCI_CHECK_NULL);
1800 return JVMCIENV->get_jobject(boxResult);
1801 C2V_END
1802
1803 C2V_VMENTRY_NULL(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
1804 if (object == NULL) {
1805 JVMCI_THROW_0(NullPointerException);
1806 }
1807 JVMCIObject box = JVMCIENV->wrap(object);
1808 BasicType type = JVMCIENV->get_box_type(box);
1809 if (type == T_ILLEGAL) {
1810 return NULL;
1811 }
1812 jvalue value = JVMCIENV->get_boxed_value(type, box);
1813 JavaValue box_result(T_OBJECT);
1814 JavaCallArguments jargs;
1815 Klass* box_klass = NULL;
1816 Symbol* box_signature = NULL;
1817 #define BOX_CASE(bt, v, argtype, name) \
1818 case bt: \
1819 jargs.push_##argtype(value.v); \
1820 box_klass = SystemDictionary::name##_klass(); \
1821 box_signature = vmSymbols::name##_valueOf_signature(); \
1822 break
1823
1827 BOX_CASE(T_CHAR, c, int, Character);
1828 BOX_CASE(T_SHORT, s, int, Short);
1829 BOX_CASE(T_INT, i, int, Integer);
1830 BOX_CASE(T_LONG, j, long, Long);
1831 BOX_CASE(T_FLOAT, f, float, Float);
1832 BOX_CASE(T_DOUBLE, d, double, Double);
1833 default:
1834 ShouldNotReachHere();
1835 }
1836 #undef BOX_CASE
1837
1838 JavaCalls::call_static(&box_result,
1839 box_klass,
1840 vmSymbols::valueOf_name(),
1841 box_signature, &jargs, CHECK_NULL);
1842 oop hotspot_box = (oop) box_result.get_jobject();
1843 JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
1844 return JVMCIENV->get_jobject(result);
1845 C2V_END
1846
1847 C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
1848 if (holder == NULL) {
1849 JVMCI_THROW_0(NullPointerException);
1850 }
1851 Klass* klass = JVMCIENV->asKlass(holder);
1852 if (!klass->is_instance_klass()) {
1853 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
1854 return JVMCIENV->get_jobjectArray(methods);
1855 }
1856
1857 InstanceKlass* iklass = InstanceKlass::cast(klass);
1858 // Ensure class is linked
1859 iklass->link_class(CHECK_NULL);
1860
1861 GrowableArray<Method*> constructors_array;
1862 for (int i = 0; i < iklass->methods()->length(); i++) {
1863 Method* m = iklass->methods()->at(i);
1864 if (m->is_initializer() && !m->is_static()) {
1865 constructors_array.append(m);
1866 }
1867 }
1868 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);
1869 for (int i = 0; i < constructors_array.length(); i++) {
1870 JVMCIObject method = JVMCIENV->get_jvmci_method(constructors_array.at(i), JVMCI_CHECK_NULL);
1871 JVMCIENV->put_object_at(methods, i, method);
1872 }
1873 return JVMCIENV->get_jobjectArray(methods);
1874 C2V_END
1875
1876 C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
1877 if (holder == NULL) {
1878 JVMCI_THROW_0(NullPointerException);
1879 }
1880 Klass* klass = JVMCIENV->asKlass(holder);
1881 if (!klass->is_instance_klass()) {
1882 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
1883 return JVMCIENV->get_jobjectArray(methods);
1884 }
1885
1886 InstanceKlass* iklass = InstanceKlass::cast(klass);
1887 // Ensure class is linked
1888 iklass->link_class(CHECK_NULL);
1889
1890 GrowableArray<Method*> methods_array;
1891 for (int i = 0; i < iklass->methods()->length(); i++) {
1892 Method* m = iklass->methods()->at(i);
1893 if (!m->is_initializer() && !m->is_overpass()) {
1894 methods_array.append(m);
1895 }
1896 }
1897 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);
1898 for (int i = 0; i < methods_array.length(); i++) {
1899 JVMCIObject method = JVMCIENV->get_jvmci_method(methods_array.at(i), JVMCI_CHECK_NULL);
1900 JVMCIENV->put_object_at(methods, i, method);
1901 }
1902 return JVMCIENV->get_jobjectArray(methods);
1903 C2V_END
1904
1905 C2V_VMENTRY_NULL(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
1906 if (object == NULL || field == NULL) {
1907 JVMCI_THROW_0(NullPointerException);
1908 }
1909 JVMCIObject field_object = JVMCIENV->wrap(field);
1910 JVMCIObject java_type = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_type(field_object);
1911 int modifiers = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_modifiers(field_object);
1912 Klass* holder = JVMCIENV->asKlass(JVMCIENV->get_HotSpotResolvedJavaFieldImpl_holder(field_object));
1913 if (!holder->is_instance_klass()) {
1914 JVMCI_THROW_MSG_0(InternalError, err_msg("Holder %s must be instance klass", holder->external_name()));
1915 }
1916 InstanceKlass* ik = InstanceKlass::cast(holder);
1917 BasicType constant_type;
1918 if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(java_type)) {
1919 constant_type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(java_type), JVMCI_CHECK_NULL);
1920 } else {
1921 constant_type = T_OBJECT;
1922 }
1923 int displacement = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_offset(field_object);
1924 fieldDescriptor fd;
1925 if (!ik->find_local_field_from_offset(displacement, (modifiers & JVM_ACC_STATIC) != 0, &fd)) {
1953 return JVMCIENV->get_jobject(result);
1954 }
1955 case T_DOUBLE: {
1956 double f = is_volatile ? obj->double_field_acquire(displacement) : obj->double_field(displacement);
1957 JVMCIObject result = JVMCIENV->call_JavaConstant_forDouble(f, JVMCI_CHECK_NULL);
1958 return JVMCIENV->get_jobject(result);
1959 }
1960 case T_BOOLEAN: value = is_volatile ? obj->bool_field_acquire(displacement) : obj->bool_field(displacement); break;
1961 case T_BYTE: value = is_volatile ? obj->byte_field_acquire(displacement) : obj->byte_field(displacement); break;
1962 case T_SHORT: value = is_volatile ? obj->short_field_acquire(displacement) : obj->short_field(displacement); break;
1963 case T_CHAR: value = is_volatile ? obj->char_field_acquire(displacement) : obj->char_field(displacement); break;
1964 case T_INT: value = is_volatile ? obj->int_field_acquire(displacement) : obj->int_field(displacement); break;
1965 case T_LONG: value = is_volatile ? obj->long_field_acquire(displacement) : obj->long_field(displacement); break;
1966 default:
1967 ShouldNotReachHere();
1968 }
1969 JVMCIObject result = JVMCIENV->call_PrimitiveConstant_forTypeChar(type2char(constant_type), value, JVMCI_CHECK_NULL);
1970 return JVMCIENV->get_jobject(result);
1971 C2V_END
1972
1973 C2V_VMENTRY_0(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
1974 if (object == NULL || holder == NULL) {
1975 JVMCI_THROW_0(NullPointerException);
1976 }
1977 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
1978 Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
1979 return obj->is_a(klass);
1980 C2V_END
1981
1982 C2V_VMENTRY_0(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
1983 if (holder == NULL || otherHolder == NULL) {
1984 JVMCI_THROW_0(NullPointerException);
1985 }
1986 Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
1987 Klass* otherKlass = JVMCIENV->asKlass(JVMCIENV->wrap(otherHolder));
1988 return otherKlass->is_subtype_of(klass);
1989 C2V_END
1990
1991 C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
1992 if (holder == NULL) {
1993 JVMCI_THROW_0(NullPointerException);
1994 }
1995 InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));
1996 if (ik->class_loader_data()->is_builtin_class_loader_data()) {
1997 return true;
1998 }
1999 return false;
2000 C2V_END
2001
2002 C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
2003 if (object == NULL) {
2004 JVMCI_THROW_0(NullPointerException);
2005 }
2006 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2007 if (java_lang_Class::is_instance(obj())) {
2008 if (java_lang_Class::is_primitive(obj())) {
2009 JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()));
2010 return JVMCIENV->get_jobject(type);
2011 }
2012 Klass* klass = java_lang_Class::as_Klass(obj());
2013 JVMCIKlassHandle klass_handle(THREAD);
2014 klass_handle = klass;
2015 JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
2016 return JVMCIENV->get_jobject(type);
2017 }
2018 return NULL;
2019 C2V_END
2020
2021
2022 C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))
2023 if (object == NULL) {
2024 JVMCI_THROW_0(NullPointerException);
2025 }
2026 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2027 const char* str = java_lang_String::as_utf8_string(obj());
2028 JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
2029 return JVMCIENV->get_jobject(result);
2030 C2V_END
2031
2032
2033 C2V_VMENTRY_0(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
2034 if (x == NULL || y == NULL) {
2035 JVMCI_THROW_0(NullPointerException);
2036 }
2037 return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);
2038 C2V_END
2039
2040 C2V_VMENTRY_NULL(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
2041 if (object == NULL) {
2042 JVMCI_THROW_0(NullPointerException);
2043 }
2044 JVMCIObject base_object = JVMCIENV->wrap(object);
2045 Handle mirror;
2046 if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
2047 mirror = Handle(THREAD, JVMCIENV->asKlass(base_object)->java_mirror());
2048 } else if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(base_object)) {
2049 mirror = JVMCIENV->asConstant(JVMCIENV->get_HotSpotResolvedPrimitiveType_mirror(base_object), JVMCI_CHECK_NULL);
2050 } else {
2051 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2052 err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
2053 }
2054 JVMCIObject result = JVMCIENV->get_object_constant(mirror());
2055 return JVMCIENV->get_jobject(result);
2056 C2V_END
2057
2058
2059 C2V_VMENTRY_0(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
2060 if (x == NULL) {
2061 JVMCI_THROW_0(NullPointerException);
2062 }
2063 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2064 if (xobj->klass()->is_array_klass()) {
2065 return arrayOop(xobj())->length();
2066 }
2067 return -1;
2068 C2V_END
2069
2070
2071 C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
2072 if (x == NULL) {
2073 JVMCI_THROW_0(NullPointerException);
2074 }
2075 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
2076 if (xobj->klass()->is_array_klass()) {
2077 arrayOop array = arrayOop(xobj());
2078 BasicType element_type = ArrayKlass::cast(array->klass())->element_type();
2079 if (index < 0 || index >= array->length()) {
2080 return NULL;
2081 }
2082 JVMCIObject result;
2083
2084 if (element_type == T_OBJECT) {
2085 result = JVMCIENV->get_object_constant(objArrayOop(xobj())->obj_at(index));
2086 if (result.is_null()) {
2087 result = JVMCIENV->get_JavaConstant_NULL_POINTER();
2088 }
2089 } else {
2090 jvalue value;
2091 switch (element_type) {
2092 case T_DOUBLE: value.d = typeArrayOop(xobj())->double_at(index); break;
2093 case T_FLOAT: value.f = typeArrayOop(xobj())->float_at(index); break;
2094 case T_LONG: value.j = typeArrayOop(xobj())->long_at(index); break;
2095 case T_INT: value.i = typeArrayOop(xobj())->int_at(index); break;
2096 case T_SHORT: value.s = typeArrayOop(xobj())->short_at(index); break;
2097 case T_CHAR: value.c = typeArrayOop(xobj())->char_at(index); break;
2098 case T_BYTE: value.b = typeArrayOop(xobj())->byte_at(index); break;
2099 case T_BOOLEAN: value.z = typeArrayOop(xobj())->byte_at(index) & 1; break;
2100 default: ShouldNotReachHere();
2101 }
2102 result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);
2103 }
2104 assert(!result.is_null(), "must have a value");
2105 return JVMCIENV->get_jobject(result);
2106 }
2107 return NULL;;
2108 C2V_END
2109
2110
2111 C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
2112 if (kind == NULL) {
2113 JVMCI_THROW_0(NullPointerException);
2114 }
2115 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
2116 return arrayOopDesc::header_size(type) * HeapWordSize;
2117 C2V_END
2118
2119 C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
2120 if (kind == NULL) {
2121 JVMCI_THROW_0(NullPointerException);
2122 }
2123 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
2124 return type2aelembytes(type);
2125 C2V_END
2126
2127 C2V_VMENTRY_0(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
2128 if (x == NULL) {
2129 JVMCI_THROW_0(NullPointerException);
2130 }
2131 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2132 return xobj->byte_field(displacement);
2133 }
2134
2135 C2V_VMENTRY_0(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
2136 if (x == NULL) {
2137 JVMCI_THROW_0(NullPointerException);
2138 }
2139 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2140 return xobj->short_field(displacement);
2141 }
2142
2143 C2V_VMENTRY_0(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
2144 if (x == NULL) {
2145 JVMCI_THROW_0(NullPointerException);
2146 }
2147 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2148 return xobj->int_field(displacement);
2149 }
2150
2151 C2V_VMENTRY_0(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
2152 if (x == NULL) {
2153 JVMCI_THROW_0(NullPointerException);
2154 }
2155 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2156 return xobj->long_field(displacement);
2157 }
2158
2159 C2V_VMENTRY_NULL(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
2160 if (x == NULL) {
2161 JVMCI_THROW_0(NullPointerException);
2162 }
2163 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
2164 oop res = xobj->obj_field(displacement);
2165 JVMCIObject result = JVMCIENV->get_object_constant(res);
2166 return JVMCIENV->get_jobject(result);
2167 }
2168
2169 C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong h))
2170 jobject handle = (jobject)(address)h;
2171 if (handle != NULL) {
2172 assert(JVMCI::is_global_handle(handle), "Invalid delete of global JNI handle");
2173 *((oop*)handle) = NULL; // Mark the handle as deleted, allocate will reuse it
2174 }
2175 }
2176
2177 static void requireJVMCINativeLibrary(JVMCI_TRAPS) {
2178 if (!UseJVMCINativeLibrary) {
2179 JVMCI_THROW_MSG(UnsupportedOperationException, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
2180 }
2181 }
2182
2183 static JavaVM* requireNativeLibraryJavaVM(const char* caller, JVMCI_TRAPS) {
2184 JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
2185 if (javaVM == NULL) {
2186 JVMCI_THROW_MSG_NULL(IllegalStateException, err_msg("Require JVMCI shared library to be initialized in %s", caller));
2187 }
2188 return javaVM;
2189 }
2190
2191 C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
2192 requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
2193 requireInHotSpot("registerNativeMethods", JVMCI_CHECK_NULL);
2194 void* shared_library = JVMCIEnv::get_shared_library_handle();
2195 if (shared_library == NULL) {
2196 // Ensure the JVMCI shared library runtime is initialized.
2197 JVMCIEnv __peer_jvmci_env__(thread, false, __FILE__, __LINE__);
2198 JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2199 HandleMark hm;
2200 JVMCIRuntime* runtime = JVMCI::compiler_runtime();
2201 JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
2202 if (peerEnv->has_pending_exception()) {
2203 peerEnv->describe_pending_exception(true);
2204 }
2205 shared_library = JVMCIEnv::get_shared_library_handle();
2206 if (shared_library == NULL) {
2207 JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
2208 }
2209 }
2210
2211 if (mirror == NULL) {
2212 JVMCI_THROW_0(NullPointerException);
2213 }
2214 Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
2215 if (klass == NULL || !klass->is_instance_klass()) {
2216 JVMCI_THROW_MSG_0(IllegalArgumentException, "clazz is for primitive type");
2217 }
2218
2219 InstanceKlass* iklass = InstanceKlass::cast(klass);
2220 for (int i = 0; i < iklass->methods()->length(); i++) {
2221 Method* method = iklass->methods()->at(i);
2222 if (method->is_native()) {
2223
2224 // Compute argument size
2225 int args_size = 1 // JNIEnv
2226 + (method->is_static() ? 1 : 0) // class for static methods
2227 + method->size_of_parameters(); // actual parameters
2228
2229 // 1) Try JNI short style
2230 stringStream st;
2231 char* pure_name = NativeLookup::pure_jni_name(method);
2232 os::print_jni_name_prefix_on(&st, args_size);
2233 st.print_raw(pure_name);
2234 os::print_jni_name_suffix_on(&st, args_size);
2235 char* jni_name = st.as_string();
2236
2237 address entry = (address) os::dll_lookup(shared_library, jni_name);
2238 if (entry == NULL) {
2239 // 2) Try JNI long style
2240 st.reset();
2241 char* long_name = NativeLookup::long_jni_name(method);
2242 os::print_jni_name_prefix_on(&st, args_size);
2243 st.print_raw(pure_name);
2244 st.print_raw(long_name);
2245 os::print_jni_name_suffix_on(&st, args_size);
2246 char* jni_long_name = st.as_string();
2247 entry = (address) os::dll_lookup(shared_library, jni_long_name);
2248 if (entry == NULL) {
2249 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [neither %s nor %s exist in %s]",
2250 method->name_and_sig_as_C_string(),
2251 jni_name, jni_long_name, JVMCIEnv::get_shared_library_path()));
2252 }
2253 }
2254
2255 if (method->has_native_function() && entry != method->native_function()) {
2256 JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT "]",
2257 method->name_and_sig_as_C_string(), p2i(method->native_function()), p2i(entry)));
2258 }
2259 method->set_native_function(entry, Method::native_bind_event_is_interesting);
2260 if (PrintJNIResolving) {
2261 tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
2262 method->method_holder()->external_name(),
2263 method->name()->as_C_string());
2264 }
2265 }
2266 }
2267
2268 JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
2269 JVMCIPrimitiveArray result = JVMCIENV->new_longArray(4, JVMCI_CHECK_NULL);
2270 JVMCIENV->put_long_at(result, 0, (jlong) (address) javaVM);
2271 JVMCIENV->put_long_at(result, 1, (jlong) (address) javaVM->functions->reserved0);
2272 JVMCIENV->put_long_at(result, 2, (jlong) (address) javaVM->functions->reserved1);
2273 JVMCIENV->put_long_at(result, 3, (jlong) (address) javaVM->functions->reserved2);
2274 return (jlongArray) JVMCIENV->get_jobject(result);
2275 }
2276
2277 C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))
2278 if (base_thread == NULL) {
2279 // Called from unattached JVMCI shared library thread
2280 return false;
2281 }
2282 JVMCITraceMark jtm("isCurrentThreadAttached");
2283 assert(base_thread->is_Java_thread(), "just checking");
2284 JavaThread* thread = (JavaThread*) base_thread;
2285 if (thread->jni_environment() == env) {
2286 C2V_BLOCK(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject))
2287 requireJVMCINativeLibrary(JVMCI_CHECK_0);
2288 JavaVM* javaVM = requireNativeLibraryJavaVM("isCurrentThreadAttached", JVMCI_CHECK_0);
2289 JNIEnv* peerEnv;
2290 return javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK;
2291 }
2292 return true;
2293 C2V_END
2294
2295 C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
2296 if (base_thread == NULL) {
2297 // Called from unattached JVMCI shared library thread
2298 extern struct JavaVM_ main_vm;
2299 JNIEnv* hotspotEnv;
2300 jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**)&hotspotEnv, NULL) :
2301 main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
2302 if (res != JNI_OK) {
2303 JNI_THROW_("attachCurrentThread", InternalError, err_msg("Trying to attach thread returned %d", res), false);
2304 }
2305 return true;
2306 }
2307 JVMCITraceMark jtm("attachCurrentThread");
2308 assert(base_thread->is_Java_thread(), "just checking");\
2309 JavaThread* thread = (JavaThread*) base_thread;
2310 if (thread->jni_environment() == env) {
2311 // Called from HotSpot
2312 C2V_BLOCK(jboolean, attachCurrentThread, (JNIEnv* env, jobject, jboolean))
2313 requireJVMCINativeLibrary(JVMCI_CHECK_0);
2314 JavaVM* javaVM = requireNativeLibraryJavaVM("attachCurrentThread", JVMCI_CHECK_0);
2315 JavaVMAttachArgs attach_args;
2316 attach_args.version = JNI_VERSION_1_2;
2317 attach_args.name = thread->name();
2318 attach_args.group = NULL;
2319 JNIEnv* peerEnv;
2320 if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK) {
2321 return false;
2322 }
2323 jint res = as_daemon ? javaVM->AttachCurrentThreadAsDaemon((void**)&peerEnv, &attach_args) :
2324 javaVM->AttachCurrentThread((void**)&peerEnv, &attach_args);
2325 if (res == JNI_OK) {
2326 guarantee(peerEnv != NULL, "must be");
2327 return true;
2328 }
2329 JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name));
2330 }
2331 // Called from JVMCI shared library
2332 return false;
2333 C2V_END
2334
2335 C2V_VMENTRY_PREFIX(void, detachCurrentThread, (JNIEnv* env, jobject c2vm))
2336 if (base_thread == NULL) {
2337 // Called from unattached JVMCI shared library thread
2338 JNI_THROW("detachCurrentThread", IllegalStateException, err_msg("Cannot detach non-attached thread"));
2339 }
2340 JVMCITraceMark jtm("detachCurrentThread");
2341 assert(base_thread->is_Java_thread(), "just checking");\
2342 JavaThread* thread = (JavaThread*) base_thread;
2343 if (thread->jni_environment() == env) {
2344 // Called from HotSpot
2345 C2V_BLOCK(void, detachCurrentThread, (JNIEnv* env, jobject))
2346 requireJVMCINativeLibrary(JVMCI_CHECK);
2347 requireInHotSpot("detachCurrentThread", JVMCI_CHECK);
2348 JavaVM* javaVM = requireNativeLibraryJavaVM("detachCurrentThread", JVMCI_CHECK);
2349 JNIEnv* peerEnv;
2350 if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) != JNI_OK) {
2351 JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot detach non-attached thread: %s", thread->name()));
2352 }
2353 jint res = javaVM->DetachCurrentThread();
2354 if (res != JNI_OK) {
2355 JVMCI_THROW_MSG(InternalError, err_msg("Error %d while attaching %s", res, thread->name()));
2356 }
2357 } else {
2358 // Called from attached JVMCI shared library thread
2359 extern struct JavaVM_ main_vm;
2360 jint res = main_vm.DetachCurrentThread();
2361 if (res != JNI_OK) {
2362 JNI_THROW("detachCurrentThread", InternalError, err_msg("Cannot detach non-attached thread"));
2363 }
2364 }
2365 C2V_END
2366
2367 C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
2368 requireJVMCINativeLibrary(JVMCI_CHECK_0);
2369 if (obj_handle == NULL) {
2370 return 0L;
2371 }
2372 JVMCIEnv __peer_jvmci_env__(thread, !JVMCIENV->is_hotspot(), __FILE__, __LINE__);
2373 JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2374 JVMCIEnv* thisEnv = JVMCIENV;
2375
2376 JVMCIObject obj = thisEnv->wrap(obj_handle);
2377 JVMCIObject result;
2378 if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
2379 Method* method = thisEnv->asMethod(obj);
2380 result = peerEnv->get_jvmci_method(method, JVMCI_CHECK_0);
2381 } else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
2382 Klass* klass = thisEnv->asKlass(obj);
2383 JVMCIKlassHandle klass_handle(THREAD);
2384 klass_handle = klass;
2385 result = peerEnv->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
2386 } else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
2387 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
2388 result = peerEnv->get_jvmci_primitive_type(type);
2389 } else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
2390 thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
2391 Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
2392 result = peerEnv->get_object_constant(constant());
2423 if (peerEnv->is_hotspot()) {
2424 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2425 if (data == NULL) {
2426 JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");
2427 }
2428 if (data->get_nmethod_mirror(nm) != NULL) {
2429 JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod");
2430 }
2431 oop nmethod_mirror = HotSpotJVMCI::resolve(result);
2432 data->set_nmethod_mirror(nm, nmethod_mirror);
2433 }
2434 }
2435 }
2436 } else {
2437 JVMCI_THROW_MSG_0(IllegalArgumentException,
2438 err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));
2439 }
2440 return (jlong) peerEnv->make_global(result).as_jobject();
2441 }
2442
2443 C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
2444 requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
2445 if (obj_handle == 0L) {
2446 return NULL;
2447 }
2448 jobject global_handle = (jobject) obj_handle;
2449 JVMCIObject global_handle_obj = JVMCIENV->wrap((jobject) obj_handle);
2450 jobject result = JVMCIENV->make_local(global_handle_obj).as_jobject();
2451
2452 JVMCIENV->destroy_global(global_handle_obj);
2453 return result;
2454 }
2455
2456 C2V_VMENTRY(void, updateHotSpotNmethod, (JNIEnv* env, jobject, jobject code_handle))
2457 JVMCIObject code = JVMCIENV->wrap(code_handle);
2458 // Execute this operation for the side effect of updating the InstalledCode state
2459 JVMCIENV->asNmethod(code);
2460 }
2461
2462 C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
2463 JVMCIObject code = JVMCIENV->wrap(code_handle);
2464 CodeBlob* cb = JVMCIENV->asCodeBlob(code);
2465 if (cb == NULL) {
2466 return NULL;
2467 }
2468 int code_size = cb->code_size();
2469 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
2470 JVMCIENV->copy_bytes_from((jbyte*) cb->code_begin(), result, 0, code_size);
2471 return JVMCIENV->get_jbyteArray(result);
2472 }
2473
2474 C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
2475 requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
2476 methodHandle m = JVMCIENV->asMethod(jvmci_method);
2477 oop executable;
2478 if (m->is_initializer()) {
2479 if (m->is_static_initializer()) {
2480 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2481 "Cannot create java.lang.reflect.Method for class initializer");
2482 }
2483 executable = Reflection::new_constructor(m, CHECK_NULL);
2484 } else {
2485 executable = Reflection::new_method(m, false, CHECK_NULL);
2486 }
2487 return JNIHandles::make_local(THREAD, executable);
2488 }
2489
2490 C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
2491 requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL);
2492 Klass* klass = JVMCIENV->asKlass(jvmci_type);
2493 if (!klass->is_instance_klass()) {
2494 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2495 err_msg("Expected non-primitive type, got %s", klass->external_name()));
2496 }
2497 InstanceKlass* iklass = InstanceKlass::cast(klass);
2498 Array<u2>* fields = iklass->fields();
2499 if (index < 0 ||index > fields->length()) {
2500 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2501 err_msg("Field index %d out of bounds for %s", index, klass->external_name()));
2502 }
2503 fieldDescriptor fd(iklass, index);
2504 oop reflected = Reflection::new_field(&fd, CHECK_NULL);
2505 return JNIHandles::make_local(env, reflected);
2506 }
2507
2508 C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
2509 FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);
2510 int result_length = 0;
2511 for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {
2512 result_length++;
2513 }
2514 int current_length = 0;
2515 JVMCIObjectArray current_array = NULL;
2516 if (current != NULL) {
2517 current_array = JVMCIENV->wrap(current);
2518 current_length = JVMCIENV->get_length(current_array);
2519 if (current_length == result_length) {
2520 // No new failures
2521 return current;
2522 }
2523 }
2524 JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);
2525 int result_index = 0;
2526 for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {
2527 assert(fs != NULL, "npe");
2528 JVMCIPrimitiveArray entry;
2529 if (result_index < current_length) {
2530 entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index);
2531 } else {
2532 entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);
2533 JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());
2534 }
2535 JVMCIENV->put_object_at(result, result_index++, entry);
2536 }
2537 return JVMCIENV->get_jobjectArray(result);
2538 }
2539
2540 C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
2541 methodHandle method = JVMCIENV->asMethod(jvmci_method);
2542 MethodData* method_data = method->method_data();
2543 if (method_data == NULL) {
2544 ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
2545 method_data = MethodData::allocate(loader_data, method, CHECK_0);
2546 method->set_method_data(method_data);
2547 }
2548 return (jlong) method_data->get_failed_speculations_address();
2549 }
2550
2551 C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
2552 FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
2553 }
2554
2555 C2V_VMENTRY_0(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
2556 JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
2557 int speculation_len = JVMCIENV->get_length(speculation_handle);
2558 char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
2559 JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);
2560 return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
2561 }
2562
2563 #define CC (char*) /*cast a literal from (const char*)*/
2564 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
2565
2566 #define STRING "Ljava/lang/String;"
2567 #define OBJECT "Ljava/lang/Object;"
2568 #define CLASS "Ljava/lang/Class;"
2569 #define OBJECTCONSTANT "Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;"
2570 #define HANDLECONSTANT "Ljdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl;"
2571 #define EXECUTABLE "Ljava/lang/reflect/Executable;"
2572 #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;"
2573 #define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;"
2574 #define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;"
2575 #define BYTECODE_FRAME "Ljdk/vm/ci/code/BytecodeFrame;"
2635 {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
2636 {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE "J[B)I", FN_PTR(installCode)},
2637 {CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},
2638 {CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
2639 {CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
2640 {CC "executeHotSpotNmethod", CC "([" OBJECT HS_NMETHOD ")" OBJECT, FN_PTR(executeHotSpotNmethod)},
2641 {CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},
2642 {CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},
2643 {CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},
2644 {CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},
2645 {CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(invalidateHotSpotNmethod)},
2646 {CC "readUncompressedOop", CC "(J)" OBJECTCONSTANT, FN_PTR(readUncompressedOop)},
2647 {CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
2648 {CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},
2649 {CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},
2650 {CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
2651 {CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
2652 {CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},
2653 {CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
2654 {CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
2655 {CC "writeDebugOutput", CC "([BIIZZ)I", FN_PTR(writeDebugOutput)},
2656 {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
2657 {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
2658 {CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
2659 {CC "getHostClass", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getHostClass)},
2660 {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
2661 {CC "compileToBytecode", CC "(" OBJECTCONSTANT ")V", FN_PTR(compileToBytecode)},
2662 {CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)},
2663 {CC "getObjectAtAddress", CC "(J)" OBJECT, FN_PTR(getObjectAtAddress)},
2664 {CC "getInterfaces", CC "(" HS_RESOLVED_KLASS ")[" HS_RESOLVED_KLASS, FN_PTR(getInterfaces)},
2665 {CC "getComponentType", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_TYPE, FN_PTR(getComponentType)},
2666 {CC "ensureInitialized", CC "(" HS_RESOLVED_KLASS ")V", FN_PTR(ensureInitialized)},
2667 {CC "getIdentityHashCode", CC "(" OBJECTCONSTANT ")I", FN_PTR(getIdentityHashCode)},
2668 {CC "isInternedString", CC "(" OBJECTCONSTANT ")Z", FN_PTR(isInternedString)},
2669 {CC "unboxPrimitive", CC "(" OBJECTCONSTANT ")" OBJECT, FN_PTR(unboxPrimitive)},
2670 {CC "boxPrimitive", CC "(" OBJECT ")" OBJECTCONSTANT, FN_PTR(boxPrimitive)},
2671 {CC "getDeclaredConstructors", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredConstructors)},
2672 {CC "getDeclaredMethods", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredMethods)},
2673 {CC "readFieldValue", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_FIELD "Z)" JAVACONSTANT, FN_PTR(readFieldValue)},
2674 {CC "readFieldValue", CC "(" OBJECTCONSTANT HS_RESOLVED_FIELD "Z)" JAVACONSTANT, FN_PTR(readFieldValue)},
2675 {CC "isInstance", CC "(" HS_RESOLVED_KLASS OBJECTCONSTANT ")Z", FN_PTR(isInstance)},
2676 {CC "isAssignableFrom", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_KLASS ")Z", FN_PTR(isAssignableFrom)},
2677 {CC "isTrustedForIntrinsics", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(isTrustedForIntrinsics)},
2678 {CC "asJavaType", CC "(" OBJECTCONSTANT ")" HS_RESOLVED_TYPE, FN_PTR(asJavaType)},
2679 {CC "asString", CC "(" OBJECTCONSTANT ")" STRING, FN_PTR(asString)},
2680 {CC "equals", CC "(" OBJECTCONSTANT "J" OBJECTCONSTANT "J)Z", FN_PTR(equals)},
2681 {CC "getJavaMirror", CC "(" HS_RESOLVED_TYPE ")" OBJECTCONSTANT, FN_PTR(getJavaMirror)},
2682 {CC "getArrayLength", CC "(" OBJECTCONSTANT ")I", FN_PTR(getArrayLength)},
2683 {CC "readArrayElement", CC "(" OBJECTCONSTANT "I)Ljava/lang/Object;", FN_PTR(readArrayElement)},
2684 {CC "arrayBaseOffset", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayBaseOffset)},
2685 {CC "arrayIndexScale", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayIndexScale)},
2686 {CC "getByte", CC "(" OBJECTCONSTANT "J)B", FN_PTR(getByte)},
2687 {CC "getShort", CC "(" OBJECTCONSTANT "J)S", FN_PTR(getShort)},
2688 {CC "getInt", CC "(" OBJECTCONSTANT "J)I", FN_PTR(getInt)},
2689 {CC "getLong", CC "(" OBJECTCONSTANT "J)J", FN_PTR(getLong)},
2690 {CC "getObject", CC "(" OBJECTCONSTANT "J)" OBJECTCONSTANT, FN_PTR(getObject)},
2691 {CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
2692 {CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
2693 {CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
2694 {CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
2695 {CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
2696 {CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
2697 {CC "unhand", CC "(J)" OBJECT, FN_PTR(unhand)},
2698 {CC "updateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(updateHotSpotNmethod)},
2699 {CC "getCode", CC "(" HS_INSTALLED_CODE ")[B", FN_PTR(getCode)},
2700 {CC "asReflectionExecutable", CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)},
2701 {CC "asReflectionField", CC "(" HS_RESOLVED_KLASS "I)" REFLECTION_FIELD, FN_PTR(asReflectionField)},
2702 {CC "getFailedSpeculations", CC "(J[[B)[[B", FN_PTR(getFailedSpeculations)},
2703 {CC "getFailedSpeculationsAddress", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getFailedSpeculationsAddress)},
2704 {CC "releaseFailedSpeculations", CC "(J)V", FN_PTR(releaseFailedSpeculations)},
2705 {CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)},
2706 };
2707
2708 int CompilerToVM::methods_count() {
2709 return sizeof(methods) / sizeof(JNINativeMethod);
2710 }
|