147 return;
148 }
149 Handle arg = next_arg(type);
150 int box_offset = java_lang_boxing_object::value_offset(type);
151 switch (type) {
152 case T_BOOLEAN: _jca->push_int(arg->bool_field(box_offset)); break;
153 case T_CHAR: _jca->push_int(arg->char_field(box_offset)); break;
154 case T_SHORT: _jca->push_int(arg->short_field(box_offset)); break;
155 case T_BYTE: _jca->push_int(arg->byte_field(box_offset)); break;
156 case T_INT: _jca->push_int(arg->int_field(box_offset)); break;
157 case T_LONG: _jca->push_long(arg->long_field(box_offset)); break;
158 case T_FLOAT: _jca->push_float(arg->float_field(box_offset)); break;
159 case T_DOUBLE: _jca->push_double(arg->double_field(box_offset)); break;
160 default: ShouldNotReachHere();
161 }
162 }
163 };
164
165 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
166 assert(_index < _args->length(), "out of bounds");
167 oop arg=((objArrayOop) (_args))->obj_at(_index++);
168 assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
169 return Handle(Thread::current(), arg);
170 }
171
172 // Bring the JVMCI compiler thread into the VM state.
173 #define JVMCI_VM_ENTRY_MARK \
174 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \
175 ThreadInVMfromNative __tiv(thread); \
176 HandleMarkCleaner __hm(thread); \
177 JavaThread* THREAD = thread; \
178 DEBUG_ONLY(VMNativeEntryWrapper __vew;)
179
180 // Native method block that transitions current thread to '_thread_in_vm'.
181 // Note: CompilerThreadCanCallJava must precede JVMCIENV_FROM_JNI so that
182 // the translation of an uncaught exception in the JVMCIEnv does not make
183 // a Java call when __is_hotspot == false.
184 #define C2V_BLOCK(result_type, name, signature) \
185 JVMCI_VM_ENTRY_MARK; \
186 ResourceMark rm; \
187 bool __is_hotspot = env == thread->jni_environment(); \
787 // 1. Put -Dtest.jvmci.oome_in_lookupConstantInPool=<trace> on the command line to
788 // discover possible values for step 2.
789 // Example output:
790 //
791 // CompilerToVM.lookupConstantInPool: "Overflow: String length out of range"{0x00000007ffeb2960}
792 // CompilerToVM.lookupConstantInPool: "null"{0x00000007ffebdfe8}
793 // CompilerToVM.lookupConstantInPool: "Maximum lock count exceeded"{0x00000007ffec4f90}
794 // CompilerToVM.lookupConstantInPool: "Negative length"{0x00000007ffec4468}
795 //
796 // 2. Choose a value shown in step 1.
797 // Example: -Dtest.jvmci.oome_in_lookupConstantInPool=Negative
798 const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.oome_in_lookupConstantInPool");
799 if (val != nullptr) {
800 const char* str = obj->print_value_string();
801 if (strstr(val, "<trace>") != nullptr) {
802 tty->print_cr("CompilerToVM.lookupConstantInPool: %s", str);
803 } else if (strstr(str, val) != nullptr) {
804 Handle garbage;
805 while (true) {
806 // Trigger an OutOfMemoryError
807 objArrayOop next = oopFactory::new_objectArray(0x7FFFFFFF, CHECK_NULL);
808 next->obj_at_put(0, garbage());
809 garbage = Handle(THREAD, next);
810 }
811 }
812 }
813 #endif
814 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));
815 C2V_END
816
817 C2V_VMENTRY_0(jint, getNumIndyEntries, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp)))
818 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
819 if (cp->cache()->resolved_indy_entries() == nullptr) {
820 return 0;
821 }
822 return cp->resolved_indy_entries_length();
823 C2V_END
824
825 C2V_VMENTRY_NULL(jobjectArray, resolveBootstrapMethod, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
826 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
827 constantTag tag = cp->tag_at(index);
866 JVMCIObject bsmi_method = JVMCIENV->get_jvmci_method(methodHandle(THREAD, java_lang_invoke_MemberName::vmtarget(member())), JVMCI_CHECK_NULL);
867 JVMCIENV->put_object_at(bsmi, 0, bsmi_method);
868
869 JVMCIObject bsmi_name = JVMCIENV->create_string(bootstrap_specifier.name(), JVMCI_CHECK_NULL);
870 JVMCIENV->put_object_at(bsmi, 1, bsmi_name);
871
872 Handle type_arg = bootstrap_specifier.type_arg();
873 JVMCIObject bsmi_type = JVMCIENV->get_object_constant(type_arg());
874 JVMCIENV->put_object_at(bsmi, 2, bsmi_type);
875
876 Handle arg_values = bootstrap_specifier.arg_values();
877 if (arg_values.not_null()) {
878 if (!arg_values->is_array()) {
879 JVMCIENV->put_object_at(bsmi, 3, JVMCIENV->get_object_constant(arg_values()));
880 } else if (arg_values->is_objArray()) {
881 objArrayHandle args_array = objArrayHandle(THREAD, (objArrayOop) arg_values());
882 int len = args_array->length();
883 JVMCIObjectArray arguments = JVMCIENV->new_JavaConstant_array(len, JVMCI_CHECK_NULL);
884 JVMCIENV->put_object_at(bsmi, 3, arguments);
885 for (int i = 0; i < len; i++) {
886 oop x = args_array->obj_at(i);
887 if (x != nullptr) {
888 JVMCIENV->put_object_at(arguments, i, JVMCIENV->get_object_constant(x));
889 } else {
890 JVMCIENV->put_object_at(arguments, i, JVMCIENV->get_JavaConstant_NULL_POINTER());
891 }
892 }
893 } else if (arg_values->is_typeArray()) {
894 typeArrayHandle bsci = typeArrayHandle(THREAD, (typeArrayOop) arg_values());
895 JVMCIPrimitiveArray arguments = JVMCIENV->new_intArray(bsci->length(), JVMCI_CHECK_NULL);
896 JVMCIENV->put_object_at(bsmi, 3, arguments);
897 for (int i = 0; i < bsci->length(); i++) {
898 JVMCIENV->put_int_at(arguments, i, bsci->int_at(i));
899 }
900 }
901 }
902 return JVMCIENV->get_jobjectArray(bsmi);
903 C2V_END
904
905 C2V_VMENTRY_0(jint, bootstrapArgumentIndexAt, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint cpi, jint index))
906 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
1279
1280 HandleMark hm(THREAD);
1281
1282 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
1283 methodHandle mh;
1284 {
1285 // Reduce the scope of JVMCINMethodHandle so that it isn't alive across the Java call. Once the
1286 // nmethod has been validated and the method is fetched from the nmethod it's fine for the
1287 // nmethod to be reclaimed if necessary.
1288 JVMCINMethodHandle nmethod_handle(THREAD);
1289 nmethod* nm = JVMCIENV->get_nmethod(nmethod_mirror, nmethod_handle);
1290 if (nm == nullptr || !nm->is_in_use()) {
1291 JVMCI_THROW_NULL(InvalidInstalledCodeException);
1292 }
1293 methodHandle nmh(THREAD, nm->method());
1294 mh = nmh;
1295 }
1296 Symbol* signature = mh->signature();
1297 JavaCallArguments jca(mh->size_of_parameters());
1298
1299 JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
1300 JavaValue result(jap.return_type());
1301 jca.set_alternative_target(Handle(THREAD, JNIHandles::resolve(nmethod_mirror.as_jobject())));
1302 JavaCalls::call(&result, mh, &jca, CHECK_NULL);
1303
1304 if (jap.return_type() == T_VOID) {
1305 return nullptr;
1306 } else if (is_reference_type(jap.return_type())) {
1307 return JNIHandles::make_local(THREAD, result.get_oop());
1308 } else {
1309 jvalue *value = (jvalue *) result.get_value_addr();
1310 // Narrow the value down if required (Important on big endian machines)
1311 switch (jap.return_type()) {
1312 case T_BOOLEAN:
1313 value->z = (jboolean) value->i;
1314 break;
1315 case T_BYTE:
1316 value->b = (jbyte) value->i;
1317 break;
1318 case T_CHAR:
1319 value->c = (jchar) value->i;
1454 C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, ARGUMENT_PAIR(method), int entry_bci, int comp_level))
1455 Method* method = UNPACK_PAIR(Method, method);
1456 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != nullptr;
1457 C2V_END
1458
1459 C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
1460 JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
1461 return JVMCIENV->get_jobject(sym);
1462 C2V_END
1463
1464 C2V_VMENTRY_NULL(jobject, getSignatureName, (JNIEnv* env, jobject, jlong klass_pointer))
1465 Klass* klass = UNPACK_PAIR(Klass, klass);
1466 JVMCIObject signature = JVMCIENV->create_string(klass->signature_name(), JVMCI_CHECK_NULL);
1467 return JVMCIENV->get_jobject(signature);
1468 C2V_END
1469
1470 /*
1471 * Used by matches() to convert a ResolvedJavaMethod[] to an array of Method*.
1472 */
1473 static GrowableArray<Method*>* init_resolved_methods(jobjectArray methods, JVMCIEnv* JVMCIENV) {
1474 objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
1475 GrowableArray<Method*>* resolved_methods = new GrowableArray<Method*>(methods_oop->length());
1476 for (int i = 0; i < methods_oop->length(); i++) {
1477 oop resolved = methods_oop->obj_at(i);
1478 Method* resolved_method = nullptr;
1479 if (resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) {
1480 resolved_method = HotSpotJVMCI::asMethod(JVMCIENV, resolved);
1481 }
1482 resolved_methods->append(resolved_method);
1483 }
1484 return resolved_methods;
1485 }
1486
1487 /*
1488 * Used by c2v_iterateFrames to check if `method` matches one of the ResolvedJavaMethods in the `methods` array.
1489 * The ResolvedJavaMethod[] array is converted to a Method* array that is then cached in the resolved_methods_ref in/out parameter.
1490 * In case of a match, the matching ResolvedJavaMethod is returned in matched_jvmci_method_ref.
1491 */
1492 static bool matches(jobjectArray methods, Method* method, GrowableArray<Method*>** resolved_methods_ref, Handle* matched_jvmci_method_ref, Thread* THREAD, JVMCIEnv* JVMCIENV) {
1493 GrowableArray<Method*>* resolved_methods = *resolved_methods_ref;
1494 if (resolved_methods == nullptr) {
1495 resolved_methods = init_resolved_methods(methods, JVMCIENV);
1496 *resolved_methods_ref = resolved_methods;
1497 }
1498 assert(method != nullptr, "method should not be null");
1499 assert(resolved_methods->length() == ((objArrayOop) JNIHandles::resolve(methods))->length(), "arrays must have the same length");
1500 for (int i = 0; i < resolved_methods->length(); i++) {
1501 Method* m = resolved_methods->at(i);
1502 if (m == method) {
1503 *matched_jvmci_method_ref = Handle(THREAD, ((objArrayOop) JNIHandles::resolve(methods))->obj_at(i));
1504 return true;
1505 }
1506 }
1507 return false;
1508 }
1509
1510 /*
1511 * Resolves an interface call to a concrete method handle.
1512 */
1513 static methodHandle resolve_interface_call(Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
1514 CallInfo callinfo;
1515 Handle receiver = args->receiver();
1516 Klass* recvrKlass = receiver.is_null() ? (Klass*)nullptr : receiver->klass();
1517 LinkInfo link_info(spec_klass, name, signature);
1518 LinkResolver::resolve_interface_call(
1519 callinfo, receiver, recvrKlass, link_info, true, CHECK_(methodHandle()));
1520 methodHandle method(THREAD, callinfo.selected_method());
1521 assert(method.not_null(), "should have thrown exception");
1522 return method;
1523 }
1610 if (vf->is_compiled_frame()) {
1611 // compiled method frame
1612 compiledVFrame* cvf = compiledVFrame::cast(vf);
1613
1614 ScopeDesc* scope = cvf->scope();
1615 // native wrappers do not have a scope
1616 if (scope != nullptr && scope->objects() != nullptr) {
1617 prev_cvf = cvf;
1618
1619 GrowableArray<ScopeValue*>* objects = nullptr;
1620 if (!realloc_called) {
1621 objects = scope->objects();
1622 } else {
1623 // some object might already have been re-allocated, only reallocate the non-allocated ones
1624 objects = get_unallocated_objects_or_null(scope->objects());
1625 }
1626
1627 if (objects != nullptr) {
1628 RegisterMap reg_map(vf->register_map());
1629 bool realloc_failures = Deoptimization::realloc_objects(thread, vf->frame_pointer(), ®_map, objects, CHECK_NULL);
1630 Deoptimization::reassign_fields(vf->frame_pointer(), ®_map, objects, realloc_failures, false);
1631 realloc_called = true;
1632 }
1633
1634 GrowableArray<ScopeValue*>* local_values = scope->locals();
1635 for (int i = 0; i < local_values->length(); i++) {
1636 ScopeValue* value = local_values->at(i);
1637 assert(!value->is_object_merge(), "Should not be.");
1638 if (value->is_object()) {
1639 if (localIsVirtual_h.is_null()) {
1640 typeArrayOop array_oop = oopFactory::new_boolArray(local_values->length(), CHECK_NULL);
1641 localIsVirtual_h = typeArrayHandle(THREAD, array_oop);
1642 }
1643 localIsVirtual_h->bool_at_put(i, true);
1644 }
1645 }
1646 }
1647
1648 locals = cvf->locals();
1649 frame_number = cvf->vframe_id();
1650 } else {
1654 locals = ivf->locals();
1655 }
1656 assert(bci == vf->bci(), "wrong bci");
1657 assert(method == vf->method(), "wrong method");
1658
1659 Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
1660 HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), bci);
1661 if (matched_jvmci_method.is_null()) {
1662 methodHandle mh(THREAD, method);
1663 JVMCIObject jvmci_method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);
1664 matched_jvmci_method = Handle(THREAD, JNIHandles::resolve(jvmci_method.as_jobject()));
1665 }
1666 HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), matched_jvmci_method());
1667 HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), localIsVirtual_h());
1668
1669 HotSpotJVMCI::HotSpotStackFrameReference::set_compilerToVM(JVMCIENV, frame_reference(), JNIHandles::resolve(compilerToVM));
1670 HotSpotJVMCI::HotSpotStackFrameReference::set_stackPointer(JVMCIENV, frame_reference(), (jlong) frame_id);
1671 HotSpotJVMCI::HotSpotStackFrameReference::set_frameNumber(JVMCIENV, frame_reference(), frame_number);
1672
1673 // initialize the locals array
1674 objArrayOop array_oop = oopFactory::new_objectArray(locals->size(), CHECK_NULL);
1675 objArrayHandle array(THREAD, array_oop);
1676 for (int i = 0; i < locals->size(); i++) {
1677 StackValue* var = locals->at(i);
1678 if (var->type() == T_OBJECT) {
1679 array->obj_at_put(i, locals->at(i)->get_obj()());
1680 }
1681 }
1682 HotSpotJVMCI::HotSpotStackFrameReference::set_locals(JVMCIENV, frame_reference(), array());
1683 HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, frame_reference(), JNI_FALSE);
1684
1685 JavaValue result(T_OBJECT);
1686 JavaCallArguments args(visitor);
1687 if (visitor_method.is_null()) {
1688 visitor_method = resolve_interface_call(HotSpotJVMCI::InspectedFrameVisitor::klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);
1689 }
1690
1691 args.push_oop(frame_reference);
1692 JavaCalls::call(&result, visitor_method, &args, CHECK_NULL);
1693 if (result.get_oop() != nullptr) {
1694 return JNIHandles::make_local(thread, result.get_oop());
1695 }
1861 break;
1862 }
1863 vf = vf->sender();
1864 }
1865
1866 int last_frame_number = JVMCIENV->get_HotSpotStackFrameReference_frameNumber(hs_frame);
1867 if (last_frame_number >= virtualFrames->length()) {
1868 JVMCI_THROW_MSG(IllegalStateException, "invalid frame number");
1869 }
1870
1871 // Reallocate the non-escaping objects and restore their fields.
1872 assert (virtualFrames->at(last_frame_number)->scope() != nullptr,"invalid scope");
1873 GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects();
1874
1875 if (objects == nullptr) {
1876 // no objects to materialize
1877 return;
1878 }
1879
1880 bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, CHECK);
1881 Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false);
1882
1883 for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) {
1884 compiledVFrame* cvf = virtualFrames->at(frame_index);
1885
1886 GrowableArray<ScopeValue*>* scopedValues = cvf->scope()->locals();
1887 StackValueCollection* locals = cvf->locals();
1888 if (locals != nullptr) {
1889 for (int i2 = 0; i2 < locals->size(); i2++) {
1890 StackValue* var = locals->at(i2);
1891 assert(!scopedValues->at(i2)->is_object_merge(), "Should not be.");
1892 if (var->type() == T_OBJECT && scopedValues->at(i2)->is_object()) {
1893 jvalue val;
1894 val.l = cast_from_oop<jobject>(locals->at(i2)->get_obj()());
1895 cvf->update_local(T_OBJECT, i2, val);
1896 }
1897 }
1898 }
1899
1900 GrowableArray<ScopeValue*>* scopeExpressions = cvf->scope()->expressions();
1901 StackValueCollection* expressions = cvf->expressions();
2026 JVMCI_THROW_NULL(NullPointerException);
2027 }
2028
2029 if (!klass->is_array_klass()) {
2030 return nullptr;
2031 }
2032 oop mirror = klass->java_mirror();
2033 oop component_mirror = java_lang_Class::component_mirror(mirror);
2034 if (component_mirror == nullptr) {
2035 JVMCI_THROW_MSG_NULL(NullPointerException,
2036 err_msg("Component mirror for array class %s is null", klass->external_name()))
2037 }
2038
2039 Klass* component_klass = java_lang_Class::as_Klass(component_mirror);
2040 if (component_klass != nullptr) {
2041 JVMCIKlassHandle klass_handle(THREAD, component_klass);
2042 JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
2043 return JVMCIENV->get_jobject(result);
2044 }
2045 BasicType type = java_lang_Class::primitive_type(component_mirror);
2046 JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type);
2047 return JVMCIENV->get_jobject(result);
2048 C2V_END
2049
2050 C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2051 Klass* klass = UNPACK_PAIR(Klass, klass);
2052 if (klass == nullptr) {
2053 JVMCI_THROW(NullPointerException);
2054 }
2055 if (klass->should_be_initialized()) {
2056 InstanceKlass* k = InstanceKlass::cast(klass);
2057 k->initialize(CHECK);
2058 }
2059 C2V_END
2060
2061 C2V_VMENTRY(void, ensureLinked, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2062 CompilerThreadCanCallJava canCallJava(thread, true); // Linking requires Java calls
2063 Klass* klass = UNPACK_PAIR(Klass, klass);
2064 if (klass == nullptr) {
2065 JVMCI_THROW(NullPointerException);
2066 }
2189 box_signature, &jargs, CHECK_NULL);
2190 oop hotspot_box = box_result.get_oop();
2191 JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
2192 return JVMCIENV->get_jobject(result);
2193 C2V_END
2194
2195 C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2196 Klass* klass = UNPACK_PAIR(Klass, klass);
2197 if (klass == nullptr) {
2198 JVMCI_THROW_NULL(NullPointerException);
2199 }
2200 if (!klass->is_instance_klass()) {
2201 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2202 return JVMCIENV->get_jobjectArray(methods);
2203 }
2204
2205 InstanceKlass* iklass = InstanceKlass::cast(klass);
2206 GrowableArray<Method*> constructors_array;
2207 for (int i = 0; i < iklass->methods()->length(); i++) {
2208 Method* m = iklass->methods()->at(i);
2209 if (m->is_object_initializer()) {
2210 constructors_array.append(m);
2211 }
2212 }
2213 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);
2214 for (int i = 0; i < constructors_array.length(); i++) {
2215 methodHandle ctor(THREAD, constructors_array.at(i));
2216 JVMCIObject method = JVMCIENV->get_jvmci_method(ctor, JVMCI_CHECK_NULL);
2217 JVMCIENV->put_object_at(methods, i, method);
2218 }
2219 return JVMCIENV->get_jobjectArray(methods);
2220 C2V_END
2221
2222 C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2223 Klass* klass = UNPACK_PAIR(Klass, klass);
2224 if (klass == nullptr) {
2225 JVMCI_THROW_NULL(NullPointerException);
2226 }
2227 if (!klass->is_instance_klass()) {
2228 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2229 return JVMCIENV->get_jobjectArray(methods);
2230 }
2231
2232 InstanceKlass* iklass = InstanceKlass::cast(klass);
2233 GrowableArray<Method*> methods_array;
2234 for (int i = 0; i < iklass->methods()->length(); i++) {
2235 Method* m = iklass->methods()->at(i);
2236 if (!m->is_object_initializer() && !m->is_static_initializer() && !m->is_overpass()) {
2237 methods_array.append(m);
2238 }
2239 }
2240 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);
2241 for (int i = 0; i < methods_array.length(); i++) {
2242 methodHandle mh(THREAD, methods_array.at(i));
2243 JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);
2244 JVMCIENV->put_object_at(methods, i, method);
2245 }
2246 return JVMCIENV->get_jobjectArray(methods);
2247 C2V_END
2248
2249 C2V_VMENTRY_NULL(jobjectArray, getAllMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2250 Klass* klass = UNPACK_PAIR(Klass, klass);
2251 if (klass == nullptr) {
2252 JVMCI_THROW_NULL(NullPointerException);
2253 }
2254 if (!klass->is_instance_klass()) {
2255 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2256 return JVMCIENV->get_jobjectArray(methods);
2441
2442 C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2443 Klass* klass = UNPACK_PAIR(Klass, klass);
2444 if (klass == nullptr) {
2445 JVMCI_THROW_0(NullPointerException);
2446 }
2447 InstanceKlass* ik = InstanceKlass::cast(klass);
2448 if (ik->class_loader_data()->is_boot_class_loader_data() || ik->class_loader_data()->is_platform_class_loader_data()) {
2449 return true;
2450 }
2451 return false;
2452 C2V_END
2453
2454 C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
2455 if (object == nullptr) {
2456 JVMCI_THROW_NULL(NullPointerException);
2457 }
2458 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2459 if (java_lang_Class::is_instance(obj())) {
2460 if (java_lang_Class::is_primitive(obj())) {
2461 JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()));
2462 return JVMCIENV->get_jobject(type);
2463 }
2464 Klass* klass = java_lang_Class::as_Klass(obj());
2465 JVMCIKlassHandle klass_handle(THREAD);
2466 klass_handle = klass;
2467 JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
2468 return JVMCIENV->get_jobject(type);
2469 }
2470 return nullptr;
2471 C2V_END
2472
2473
2474 C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))
2475 if (object == nullptr) {
2476 JVMCI_THROW_NULL(NullPointerException);
2477 }
2478 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2479 const char* str = java_lang_String::as_utf8_string(obj());
2480 JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
2481 return JVMCIENV->get_jobject(result);
2509 return arrayOop(xobj())->length();
2510 }
2511 return -1;
2512 C2V_END
2513
2514
2515 C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
2516 if (x == nullptr) {
2517 JVMCI_THROW_NULL(NullPointerException);
2518 }
2519 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
2520 if (xobj->klass()->is_array_klass()) {
2521 arrayOop array = arrayOop(xobj());
2522 BasicType element_type = ArrayKlass::cast(array->klass())->element_type();
2523 if (index < 0 || index >= array->length()) {
2524 return nullptr;
2525 }
2526 JVMCIObject result;
2527
2528 if (element_type == T_OBJECT) {
2529 result = JVMCIENV->get_object_constant(objArrayOop(xobj())->obj_at(index));
2530 if (result.is_null()) {
2531 result = JVMCIENV->get_JavaConstant_NULL_POINTER();
2532 }
2533 } else {
2534 jvalue value;
2535 switch (element_type) {
2536 case T_DOUBLE: value.d = typeArrayOop(xobj())->double_at(index); break;
2537 case T_FLOAT: value.f = typeArrayOop(xobj())->float_at(index); break;
2538 case T_LONG: value.j = typeArrayOop(xobj())->long_at(index); break;
2539 case T_INT: value.i = typeArrayOop(xobj())->int_at(index); break;
2540 case T_SHORT: value.s = typeArrayOop(xobj())->short_at(index); break;
2541 case T_CHAR: value.c = typeArrayOop(xobj())->char_at(index); break;
2542 case T_BYTE: value.b = typeArrayOop(xobj())->byte_at(index); break;
2543 case T_BOOLEAN: value.z = typeArrayOop(xobj())->byte_at(index) & 1; break;
2544 default: ShouldNotReachHere();
2545 }
2546 result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);
2547 }
2548 assert(!result.is_null(), "must have a value");
2549 return JVMCIENV->get_jobject(result);
2847 if (obj_handle == nullptr) {
2848 return 0L;
2849 }
2850 PEER_JVMCIENV_FROM_THREAD(THREAD, !JVMCIENV->is_hotspot());
2851 CompilerThreadCanCallJava canCallJava(thread, PEER_JVMCIENV->is_hotspot());
2852 PEER_JVMCIENV->check_init(JVMCI_CHECK_0);
2853
2854 JVMCIEnv* thisEnv = JVMCIENV;
2855 JVMCIObject obj = thisEnv->wrap(obj_handle);
2856 JVMCIObject result;
2857 if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
2858 methodHandle method(THREAD, thisEnv->asMethod(obj));
2859 result = PEER_JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_0);
2860 } else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
2861 Klass* klass = thisEnv->asKlass(obj);
2862 JVMCIKlassHandle klass_handle(THREAD);
2863 klass_handle = klass;
2864 result = PEER_JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
2865 } else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
2866 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
2867 result = PEER_JVMCIENV->get_jvmci_primitive_type(type);
2868 } else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
2869 thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
2870 Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
2871 result = PEER_JVMCIENV->get_object_constant(constant());
2872 } else if (thisEnv->isa_HotSpotNmethod(obj)) {
2873 if (PEER_JVMCIENV->is_hotspot()) {
2874 JVMCINMethodHandle nmethod_handle(THREAD);
2875 nmethod* nm = JVMCIENV->get_nmethod(obj, nmethod_handle);
2876 if (nm != nullptr) {
2877 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2878 if (data != nullptr) {
2879 // Only the mirror in the HotSpot heap is accessible
2880 // through JVMCINMethodData
2881 oop nmethod_mirror = data->get_nmethod_mirror(nm);
2882 if (nmethod_mirror != nullptr) {
2883 result = HotSpotJVMCI::wrap(nmethod_mirror);
2884 }
2885 }
2886 }
2887 }
2956 C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
2957 JVMCIObject code = JVMCIENV->wrap(code_handle);
2958 CodeBlob* cb = JVMCIENV->get_code_blob(code);
2959 if (cb == nullptr) {
2960 return nullptr;
2961 }
2962 // Make a resource copy of code before the allocation causes a safepoint
2963 int code_size = cb->code_size();
2964 jbyte* code_bytes = NEW_RESOURCE_ARRAY(jbyte, code_size);
2965 memcpy(code_bytes, (jbyte*) cb->code_begin(), code_size);
2966
2967 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
2968 JVMCIENV->copy_bytes_from(code_bytes, result, 0, code_size);
2969 return JVMCIENV->get_jbyteArray(result);
2970 C2V_END
2971
2972 C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
2973 requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
2974 methodHandle m(THREAD, UNPACK_PAIR(Method, method));
2975 oop executable;
2976 if (m->is_object_initializer()) {
2977 executable = Reflection::new_constructor(m, CHECK_NULL);
2978 } else if (m->is_static_initializer()) {
2979 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2980 "Cannot create java.lang.reflect.Method for class initializer");
2981 } else {
2982 executable = Reflection::new_method(m, false, CHECK_NULL);
2983 }
2984 return JNIHandles::make_local(THREAD, executable);
2985 C2V_END
2986
2987 // Checks that `index` denotes a non-injected field in `klass`
2988 static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) {
2989 if (!klass->is_instance_klass()) {
2990 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2991 err_msg("Expected non-primitive type, got %s", klass->external_name()));
2992 }
2993 InstanceKlass* iklass = InstanceKlass::cast(klass);
2994 if (index < 0 || index >= iklass->java_fields_count()) {
2995 if (index >= 0 && index < iklass->total_fields_count()) {
2996 fieldDescriptor fd(iklass, index);
2997 if (fd.is_injected()) {
2998 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2999 err_msg("Cannot get Field for injected %s.%s", klass->external_name(), fd.name()->as_C_string()));
3000 }
3104 int result_length = 0;
3105 for (FailedSpeculation* fs = head; fs != nullptr; fs = fs->next()) {
3106 result_length++;
3107 }
3108 int current_length = 0;
3109 JVMCIObjectArray current_array = nullptr;
3110 if (current != nullptr) {
3111 current_array = JVMCIENV->wrap(current);
3112 current_length = JVMCIENV->get_length(current_array);
3113 if (current_length == result_length) {
3114 // No new failures
3115 return current;
3116 }
3117 }
3118 JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);
3119 int result_index = 0;
3120 for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {
3121 assert(fs != nullptr, "npe");
3122 JVMCIPrimitiveArray entry;
3123 if (result_index < current_length) {
3124 entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index);
3125 } else {
3126 entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);
3127 JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());
3128 }
3129 JVMCIENV->put_object_at(result, result_index++, entry);
3130 }
3131 return JVMCIENV->get_jobjectArray(result);
3132 C2V_END
3133
3134 C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
3135 methodHandle method(THREAD, UNPACK_PAIR(Method, method));
3136 MethodData* method_data = get_profiling_method_data(method, CHECK_0);
3137 return (jlong) method_data->get_failed_speculations_address();
3138 C2V_END
3139
3140 C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
3141 FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
3142 C2V_END
3143
3144 C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
|
147 return;
148 }
149 Handle arg = next_arg(type);
150 int box_offset = java_lang_boxing_object::value_offset(type);
151 switch (type) {
152 case T_BOOLEAN: _jca->push_int(arg->bool_field(box_offset)); break;
153 case T_CHAR: _jca->push_int(arg->char_field(box_offset)); break;
154 case T_SHORT: _jca->push_int(arg->short_field(box_offset)); break;
155 case T_BYTE: _jca->push_int(arg->byte_field(box_offset)); break;
156 case T_INT: _jca->push_int(arg->int_field(box_offset)); break;
157 case T_LONG: _jca->push_long(arg->long_field(box_offset)); break;
158 case T_FLOAT: _jca->push_float(arg->float_field(box_offset)); break;
159 case T_DOUBLE: _jca->push_double(arg->double_field(box_offset)); break;
160 default: ShouldNotReachHere();
161 }
162 }
163 };
164
165 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
166 assert(_index < _args->length(), "out of bounds");
167 oop arg = refArrayOop(_args)->obj_at(_index++);
168 assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
169 return Handle(Thread::current(), arg);
170 }
171
172 // Bring the JVMCI compiler thread into the VM state.
173 #define JVMCI_VM_ENTRY_MARK \
174 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \
175 ThreadInVMfromNative __tiv(thread); \
176 HandleMarkCleaner __hm(thread); \
177 JavaThread* THREAD = thread; \
178 DEBUG_ONLY(VMNativeEntryWrapper __vew;)
179
180 // Native method block that transitions current thread to '_thread_in_vm'.
181 // Note: CompilerThreadCanCallJava must precede JVMCIENV_FROM_JNI so that
182 // the translation of an uncaught exception in the JVMCIEnv does not make
183 // a Java call when __is_hotspot == false.
184 #define C2V_BLOCK(result_type, name, signature) \
185 JVMCI_VM_ENTRY_MARK; \
186 ResourceMark rm; \
187 bool __is_hotspot = env == thread->jni_environment(); \
787 // 1. Put -Dtest.jvmci.oome_in_lookupConstantInPool=<trace> on the command line to
788 // discover possible values for step 2.
789 // Example output:
790 //
791 // CompilerToVM.lookupConstantInPool: "Overflow: String length out of range"{0x00000007ffeb2960}
792 // CompilerToVM.lookupConstantInPool: "null"{0x00000007ffebdfe8}
793 // CompilerToVM.lookupConstantInPool: "Maximum lock count exceeded"{0x00000007ffec4f90}
794 // CompilerToVM.lookupConstantInPool: "Negative length"{0x00000007ffec4468}
795 //
796 // 2. Choose a value shown in step 1.
797 // Example: -Dtest.jvmci.oome_in_lookupConstantInPool=Negative
798 const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.oome_in_lookupConstantInPool");
799 if (val != nullptr) {
800 const char* str = obj->print_value_string();
801 if (strstr(val, "<trace>") != nullptr) {
802 tty->print_cr("CompilerToVM.lookupConstantInPool: %s", str);
803 } else if (strstr(str, val) != nullptr) {
804 Handle garbage;
805 while (true) {
806 // Trigger an OutOfMemoryError
807 refArrayOop next = oopFactory::new_objectArray(0x7FFFFFFF, CHECK_NULL);
808 next->obj_at_put(0, garbage());
809 garbage = Handle(THREAD, next);
810 }
811 }
812 }
813 #endif
814 return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));
815 C2V_END
816
817 C2V_VMENTRY_0(jint, getNumIndyEntries, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp)))
818 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
819 if (cp->cache()->resolved_indy_entries() == nullptr) {
820 return 0;
821 }
822 return cp->resolved_indy_entries_length();
823 C2V_END
824
825 C2V_VMENTRY_NULL(jobjectArray, resolveBootstrapMethod, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
826 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
827 constantTag tag = cp->tag_at(index);
866 JVMCIObject bsmi_method = JVMCIENV->get_jvmci_method(methodHandle(THREAD, java_lang_invoke_MemberName::vmtarget(member())), JVMCI_CHECK_NULL);
867 JVMCIENV->put_object_at(bsmi, 0, bsmi_method);
868
869 JVMCIObject bsmi_name = JVMCIENV->create_string(bootstrap_specifier.name(), JVMCI_CHECK_NULL);
870 JVMCIENV->put_object_at(bsmi, 1, bsmi_name);
871
872 Handle type_arg = bootstrap_specifier.type_arg();
873 JVMCIObject bsmi_type = JVMCIENV->get_object_constant(type_arg());
874 JVMCIENV->put_object_at(bsmi, 2, bsmi_type);
875
876 Handle arg_values = bootstrap_specifier.arg_values();
877 if (arg_values.not_null()) {
878 if (!arg_values->is_array()) {
879 JVMCIENV->put_object_at(bsmi, 3, JVMCIENV->get_object_constant(arg_values()));
880 } else if (arg_values->is_objArray()) {
881 objArrayHandle args_array = objArrayHandle(THREAD, (objArrayOop) arg_values());
882 int len = args_array->length();
883 JVMCIObjectArray arguments = JVMCIENV->new_JavaConstant_array(len, JVMCI_CHECK_NULL);
884 JVMCIENV->put_object_at(bsmi, 3, arguments);
885 for (int i = 0; i < len; i++) {
886 oop x = args_array->obj_at(i, CHECK_NULL);
887 if (x != nullptr) {
888 JVMCIENV->put_object_at(arguments, i, JVMCIENV->get_object_constant(x));
889 } else {
890 JVMCIENV->put_object_at(arguments, i, JVMCIENV->get_JavaConstant_NULL_POINTER());
891 }
892 }
893 } else if (arg_values->is_typeArray()) {
894 typeArrayHandle bsci = typeArrayHandle(THREAD, (typeArrayOop) arg_values());
895 JVMCIPrimitiveArray arguments = JVMCIENV->new_intArray(bsci->length(), JVMCI_CHECK_NULL);
896 JVMCIENV->put_object_at(bsmi, 3, arguments);
897 for (int i = 0; i < bsci->length(); i++) {
898 JVMCIENV->put_int_at(arguments, i, bsci->int_at(i));
899 }
900 }
901 }
902 return JVMCIENV->get_jobjectArray(bsmi);
903 C2V_END
904
905 C2V_VMENTRY_0(jint, bootstrapArgumentIndexAt, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint cpi, jint index))
906 constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
1279
1280 HandleMark hm(THREAD);
1281
1282 JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
1283 methodHandle mh;
1284 {
1285 // Reduce the scope of JVMCINMethodHandle so that it isn't alive across the Java call. Once the
1286 // nmethod has been validated and the method is fetched from the nmethod it's fine for the
1287 // nmethod to be reclaimed if necessary.
1288 JVMCINMethodHandle nmethod_handle(THREAD);
1289 nmethod* nm = JVMCIENV->get_nmethod(nmethod_mirror, nmethod_handle);
1290 if (nm == nullptr || !nm->is_in_use()) {
1291 JVMCI_THROW_NULL(InvalidInstalledCodeException);
1292 }
1293 methodHandle nmh(THREAD, nm->method());
1294 mh = nmh;
1295 }
1296 Symbol* signature = mh->signature();
1297 JavaCallArguments jca(mh->size_of_parameters());
1298
1299 arrayOop args_array = (arrayOop) JNIHandles::resolve(args);
1300 if (args_array->is_flatArray()) {
1301 JVMCI_THROW_MSG_NULL(IllegalStateException, "executeHotSpotNmethod cannot handle flat args arrays");
1302 }
1303
1304 JavaArgumentUnboxer jap(signature, &jca, args_array, mh->is_static());
1305 JavaValue result(jap.return_type());
1306 jca.set_alternative_target(Handle(THREAD, JNIHandles::resolve(nmethod_mirror.as_jobject())));
1307 JavaCalls::call(&result, mh, &jca, CHECK_NULL);
1308
1309 if (jap.return_type() == T_VOID) {
1310 return nullptr;
1311 } else if (is_reference_type(jap.return_type())) {
1312 return JNIHandles::make_local(THREAD, result.get_oop());
1313 } else {
1314 jvalue *value = (jvalue *) result.get_value_addr();
1315 // Narrow the value down if required (Important on big endian machines)
1316 switch (jap.return_type()) {
1317 case T_BOOLEAN:
1318 value->z = (jboolean) value->i;
1319 break;
1320 case T_BYTE:
1321 value->b = (jbyte) value->i;
1322 break;
1323 case T_CHAR:
1324 value->c = (jchar) value->i;
1459 C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, ARGUMENT_PAIR(method), int entry_bci, int comp_level))
1460 Method* method = UNPACK_PAIR(Method, method);
1461 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != nullptr;
1462 C2V_END
1463
1464 C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
1465 JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
1466 return JVMCIENV->get_jobject(sym);
1467 C2V_END
1468
1469 C2V_VMENTRY_NULL(jobject, getSignatureName, (JNIEnv* env, jobject, jlong klass_pointer))
1470 Klass* klass = UNPACK_PAIR(Klass, klass);
1471 JVMCIObject signature = JVMCIENV->create_string(klass->signature_name(), JVMCI_CHECK_NULL);
1472 return JVMCIENV->get_jobject(signature);
1473 C2V_END
1474
1475 /*
1476 * Used by matches() to convert a ResolvedJavaMethod[] to an array of Method*.
1477 */
1478 static GrowableArray<Method*>* init_resolved_methods(jobjectArray methods, JVMCIEnv* JVMCIENV) {
1479 refArrayOop methods_oop = (refArrayOop) JNIHandles::resolve(methods);
1480 GrowableArray<Method*>* resolved_methods = new GrowableArray<Method*>(methods_oop->length());
1481 for (int i = 0; i < methods_oop->length(); i++) {
1482 oop resolved = methods_oop->obj_at(i);
1483 Method* resolved_method = nullptr;
1484 if (resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) {
1485 resolved_method = HotSpotJVMCI::asMethod(JVMCIENV, resolved);
1486 }
1487 resolved_methods->append(resolved_method);
1488 }
1489 return resolved_methods;
1490 }
1491
1492 /*
1493 * Used by c2v_iterateFrames to check if `method` matches one of the ResolvedJavaMethods in the `methods` array.
1494 * The ResolvedJavaMethod[] array is converted to a Method* array that is then cached in the resolved_methods_ref in/out parameter.
1495 * In case of a match, the matching ResolvedJavaMethod is returned in matched_jvmci_method_ref.
1496 */
1497 static bool matches(jobjectArray methods, Method* method, GrowableArray<Method*>** resolved_methods_ref, Handle* matched_jvmci_method_ref, Thread* THREAD, JVMCIEnv* JVMCIENV) {
1498 GrowableArray<Method*>* resolved_methods = *resolved_methods_ref;
1499 if (resolved_methods == nullptr) {
1500 resolved_methods = init_resolved_methods(methods, JVMCIENV);
1501 *resolved_methods_ref = resolved_methods;
1502 }
1503 assert(method != nullptr, "method should not be null");
1504 assert(resolved_methods->length() == ((objArrayOop) JNIHandles::resolve(methods))->length(), "arrays must have the same length");
1505 for (int i = 0; i < resolved_methods->length(); i++) {
1506 Method* m = resolved_methods->at(i);
1507 if (m == method) {
1508 *matched_jvmci_method_ref = Handle(THREAD, refArrayOop(JNIHandles::resolve(methods))->obj_at(i));
1509 return true;
1510 }
1511 }
1512 return false;
1513 }
1514
1515 /*
1516 * Resolves an interface call to a concrete method handle.
1517 */
1518 static methodHandle resolve_interface_call(Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
1519 CallInfo callinfo;
1520 Handle receiver = args->receiver();
1521 Klass* recvrKlass = receiver.is_null() ? (Klass*)nullptr : receiver->klass();
1522 LinkInfo link_info(spec_klass, name, signature);
1523 LinkResolver::resolve_interface_call(
1524 callinfo, receiver, recvrKlass, link_info, true, CHECK_(methodHandle()));
1525 methodHandle method(THREAD, callinfo.selected_method());
1526 assert(method.not_null(), "should have thrown exception");
1527 return method;
1528 }
1615 if (vf->is_compiled_frame()) {
1616 // compiled method frame
1617 compiledVFrame* cvf = compiledVFrame::cast(vf);
1618
1619 ScopeDesc* scope = cvf->scope();
1620 // native wrappers do not have a scope
1621 if (scope != nullptr && scope->objects() != nullptr) {
1622 prev_cvf = cvf;
1623
1624 GrowableArray<ScopeValue*>* objects = nullptr;
1625 if (!realloc_called) {
1626 objects = scope->objects();
1627 } else {
1628 // some object might already have been re-allocated, only reallocate the non-allocated ones
1629 objects = get_unallocated_objects_or_null(scope->objects());
1630 }
1631
1632 if (objects != nullptr) {
1633 RegisterMap reg_map(vf->register_map());
1634 bool realloc_failures = Deoptimization::realloc_objects(thread, vf->frame_pointer(), ®_map, objects, CHECK_NULL);
1635 Deoptimization::reassign_fields(vf->frame_pointer(), ®_map, objects, realloc_failures, false, CHECK_NULL);
1636 realloc_called = true;
1637 }
1638
1639 GrowableArray<ScopeValue*>* local_values = scope->locals();
1640 for (int i = 0; i < local_values->length(); i++) {
1641 ScopeValue* value = local_values->at(i);
1642 assert(!value->is_object_merge(), "Should not be.");
1643 if (value->is_object()) {
1644 if (localIsVirtual_h.is_null()) {
1645 typeArrayOop array_oop = oopFactory::new_boolArray(local_values->length(), CHECK_NULL);
1646 localIsVirtual_h = typeArrayHandle(THREAD, array_oop);
1647 }
1648 localIsVirtual_h->bool_at_put(i, true);
1649 }
1650 }
1651 }
1652
1653 locals = cvf->locals();
1654 frame_number = cvf->vframe_id();
1655 } else {
1659 locals = ivf->locals();
1660 }
1661 assert(bci == vf->bci(), "wrong bci");
1662 assert(method == vf->method(), "wrong method");
1663
1664 Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
1665 HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), bci);
1666 if (matched_jvmci_method.is_null()) {
1667 methodHandle mh(THREAD, method);
1668 JVMCIObject jvmci_method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);
1669 matched_jvmci_method = Handle(THREAD, JNIHandles::resolve(jvmci_method.as_jobject()));
1670 }
1671 HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), matched_jvmci_method());
1672 HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), localIsVirtual_h());
1673
1674 HotSpotJVMCI::HotSpotStackFrameReference::set_compilerToVM(JVMCIENV, frame_reference(), JNIHandles::resolve(compilerToVM));
1675 HotSpotJVMCI::HotSpotStackFrameReference::set_stackPointer(JVMCIENV, frame_reference(), (jlong) frame_id);
1676 HotSpotJVMCI::HotSpotStackFrameReference::set_frameNumber(JVMCIENV, frame_reference(), frame_number);
1677
1678 // initialize the locals array
1679 refArrayOop array_oop = oopFactory::new_objectArray(locals->size(), CHECK_NULL);
1680 refArrayHandle array(THREAD, array_oop);
1681 for (int i = 0; i < locals->size(); i++) {
1682 StackValue* var = locals->at(i);
1683 if (var->type() == T_OBJECT) {
1684 array->obj_at_put(i, locals->at(i)->get_obj()());
1685 }
1686 }
1687 HotSpotJVMCI::HotSpotStackFrameReference::set_locals(JVMCIENV, frame_reference(), array());
1688 HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, frame_reference(), JNI_FALSE);
1689
1690 JavaValue result(T_OBJECT);
1691 JavaCallArguments args(visitor);
1692 if (visitor_method.is_null()) {
1693 visitor_method = resolve_interface_call(HotSpotJVMCI::InspectedFrameVisitor::klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);
1694 }
1695
1696 args.push_oop(frame_reference);
1697 JavaCalls::call(&result, visitor_method, &args, CHECK_NULL);
1698 if (result.get_oop() != nullptr) {
1699 return JNIHandles::make_local(thread, result.get_oop());
1700 }
1866 break;
1867 }
1868 vf = vf->sender();
1869 }
1870
1871 int last_frame_number = JVMCIENV->get_HotSpotStackFrameReference_frameNumber(hs_frame);
1872 if (last_frame_number >= virtualFrames->length()) {
1873 JVMCI_THROW_MSG(IllegalStateException, "invalid frame number");
1874 }
1875
1876 // Reallocate the non-escaping objects and restore their fields.
1877 assert (virtualFrames->at(last_frame_number)->scope() != nullptr,"invalid scope");
1878 GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects();
1879
1880 if (objects == nullptr) {
1881 // no objects to materialize
1882 return;
1883 }
1884
1885 bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, CHECK);
1886 Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false, THREAD);
1887
1888 for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) {
1889 compiledVFrame* cvf = virtualFrames->at(frame_index);
1890
1891 GrowableArray<ScopeValue*>* scopedValues = cvf->scope()->locals();
1892 StackValueCollection* locals = cvf->locals();
1893 if (locals != nullptr) {
1894 for (int i2 = 0; i2 < locals->size(); i2++) {
1895 StackValue* var = locals->at(i2);
1896 assert(!scopedValues->at(i2)->is_object_merge(), "Should not be.");
1897 if (var->type() == T_OBJECT && scopedValues->at(i2)->is_object()) {
1898 jvalue val;
1899 val.l = cast_from_oop<jobject>(locals->at(i2)->get_obj()());
1900 cvf->update_local(T_OBJECT, i2, val);
1901 }
1902 }
1903 }
1904
1905 GrowableArray<ScopeValue*>* scopeExpressions = cvf->scope()->expressions();
1906 StackValueCollection* expressions = cvf->expressions();
2031 JVMCI_THROW_NULL(NullPointerException);
2032 }
2033
2034 if (!klass->is_array_klass()) {
2035 return nullptr;
2036 }
2037 oop mirror = klass->java_mirror();
2038 oop component_mirror = java_lang_Class::component_mirror(mirror);
2039 if (component_mirror == nullptr) {
2040 JVMCI_THROW_MSG_NULL(NullPointerException,
2041 err_msg("Component mirror for array class %s is null", klass->external_name()))
2042 }
2043
2044 Klass* component_klass = java_lang_Class::as_Klass(component_mirror);
2045 if (component_klass != nullptr) {
2046 JVMCIKlassHandle klass_handle(THREAD, component_klass);
2047 JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
2048 return JVMCIENV->get_jobject(result);
2049 }
2050 BasicType type = java_lang_Class::primitive_type(component_mirror);
2051 JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type, JVMCI_CHECK_NULL);
2052 return JVMCIENV->get_jobject(result);
2053 C2V_END
2054
2055 C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2056 Klass* klass = UNPACK_PAIR(Klass, klass);
2057 if (klass == nullptr) {
2058 JVMCI_THROW(NullPointerException);
2059 }
2060 if (klass->should_be_initialized()) {
2061 InstanceKlass* k = InstanceKlass::cast(klass);
2062 k->initialize(CHECK);
2063 }
2064 C2V_END
2065
2066 C2V_VMENTRY(void, ensureLinked, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2067 CompilerThreadCanCallJava canCallJava(thread, true); // Linking requires Java calls
2068 Klass* klass = UNPACK_PAIR(Klass, klass);
2069 if (klass == nullptr) {
2070 JVMCI_THROW(NullPointerException);
2071 }
2194 box_signature, &jargs, CHECK_NULL);
2195 oop hotspot_box = box_result.get_oop();
2196 JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
2197 return JVMCIENV->get_jobject(result);
2198 C2V_END
2199
2200 C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2201 Klass* klass = UNPACK_PAIR(Klass, klass);
2202 if (klass == nullptr) {
2203 JVMCI_THROW_NULL(NullPointerException);
2204 }
2205 if (!klass->is_instance_klass()) {
2206 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2207 return JVMCIENV->get_jobjectArray(methods);
2208 }
2209
2210 InstanceKlass* iklass = InstanceKlass::cast(klass);
2211 GrowableArray<Method*> constructors_array;
2212 for (int i = 0; i < iklass->methods()->length(); i++) {
2213 Method* m = iklass->methods()->at(i);
2214 if (m->is_object_constructor()) {
2215 constructors_array.append(m);
2216 }
2217 }
2218 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);
2219 for (int i = 0; i < constructors_array.length(); i++) {
2220 methodHandle ctor(THREAD, constructors_array.at(i));
2221 JVMCIObject method = JVMCIENV->get_jvmci_method(ctor, JVMCI_CHECK_NULL);
2222 JVMCIENV->put_object_at(methods, i, method);
2223 }
2224 return JVMCIENV->get_jobjectArray(methods);
2225 C2V_END
2226
2227 C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2228 Klass* klass = UNPACK_PAIR(Klass, klass);
2229 if (klass == nullptr) {
2230 JVMCI_THROW_NULL(NullPointerException);
2231 }
2232 if (!klass->is_instance_klass()) {
2233 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2234 return JVMCIENV->get_jobjectArray(methods);
2235 }
2236
2237 InstanceKlass* iklass = InstanceKlass::cast(klass);
2238 GrowableArray<Method*> methods_array;
2239 for (int i = 0; i < iklass->methods()->length(); i++) {
2240 Method* m = iklass->methods()->at(i);
2241 if (!(m->is_object_constructor() || m->is_class_initializer()) && !m->is_overpass()) {
2242 methods_array.append(m);
2243 }
2244 }
2245 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);
2246 for (int i = 0; i < methods_array.length(); i++) {
2247 methodHandle mh(THREAD, methods_array.at(i));
2248 JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);
2249 JVMCIENV->put_object_at(methods, i, method);
2250 }
2251 return JVMCIENV->get_jobjectArray(methods);
2252 C2V_END
2253
2254 C2V_VMENTRY_NULL(jobjectArray, getAllMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2255 Klass* klass = UNPACK_PAIR(Klass, klass);
2256 if (klass == nullptr) {
2257 JVMCI_THROW_NULL(NullPointerException);
2258 }
2259 if (!klass->is_instance_klass()) {
2260 JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2261 return JVMCIENV->get_jobjectArray(methods);
2446
2447 C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2448 Klass* klass = UNPACK_PAIR(Klass, klass);
2449 if (klass == nullptr) {
2450 JVMCI_THROW_0(NullPointerException);
2451 }
2452 InstanceKlass* ik = InstanceKlass::cast(klass);
2453 if (ik->class_loader_data()->is_boot_class_loader_data() || ik->class_loader_data()->is_platform_class_loader_data()) {
2454 return true;
2455 }
2456 return false;
2457 C2V_END
2458
2459 C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
2460 if (object == nullptr) {
2461 JVMCI_THROW_NULL(NullPointerException);
2462 }
2463 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2464 if (java_lang_Class::is_instance(obj())) {
2465 if (java_lang_Class::is_primitive(obj())) {
2466 JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()), JVMCI_CHECK_NULL);
2467 return JVMCIENV->get_jobject(type);
2468 }
2469 Klass* klass = java_lang_Class::as_Klass(obj());
2470 JVMCIKlassHandle klass_handle(THREAD);
2471 klass_handle = klass;
2472 JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
2473 return JVMCIENV->get_jobject(type);
2474 }
2475 return nullptr;
2476 C2V_END
2477
2478
2479 C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))
2480 if (object == nullptr) {
2481 JVMCI_THROW_NULL(NullPointerException);
2482 }
2483 Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
2484 const char* str = java_lang_String::as_utf8_string(obj());
2485 JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
2486 return JVMCIENV->get_jobject(result);
2514 return arrayOop(xobj())->length();
2515 }
2516 return -1;
2517 C2V_END
2518
2519
2520 C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
2521 if (x == nullptr) {
2522 JVMCI_THROW_NULL(NullPointerException);
2523 }
2524 Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
2525 if (xobj->klass()->is_array_klass()) {
2526 arrayOop array = arrayOop(xobj());
2527 BasicType element_type = ArrayKlass::cast(array->klass())->element_type();
2528 if (index < 0 || index >= array->length()) {
2529 return nullptr;
2530 }
2531 JVMCIObject result;
2532
2533 if (element_type == T_OBJECT) {
2534 oop element = objArrayOop(xobj())->obj_at(index, CHECK_NULL);
2535 result = JVMCIENV->get_object_constant(element);
2536 if (result.is_null()) {
2537 result = JVMCIENV->get_JavaConstant_NULL_POINTER();
2538 }
2539 } else {
2540 jvalue value;
2541 switch (element_type) {
2542 case T_DOUBLE: value.d = typeArrayOop(xobj())->double_at(index); break;
2543 case T_FLOAT: value.f = typeArrayOop(xobj())->float_at(index); break;
2544 case T_LONG: value.j = typeArrayOop(xobj())->long_at(index); break;
2545 case T_INT: value.i = typeArrayOop(xobj())->int_at(index); break;
2546 case T_SHORT: value.s = typeArrayOop(xobj())->short_at(index); break;
2547 case T_CHAR: value.c = typeArrayOop(xobj())->char_at(index); break;
2548 case T_BYTE: value.b = typeArrayOop(xobj())->byte_at(index); break;
2549 case T_BOOLEAN: value.z = typeArrayOop(xobj())->byte_at(index) & 1; break;
2550 default: ShouldNotReachHere();
2551 }
2552 result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);
2553 }
2554 assert(!result.is_null(), "must have a value");
2555 return JVMCIENV->get_jobject(result);
2853 if (obj_handle == nullptr) {
2854 return 0L;
2855 }
2856 PEER_JVMCIENV_FROM_THREAD(THREAD, !JVMCIENV->is_hotspot());
2857 CompilerThreadCanCallJava canCallJava(thread, PEER_JVMCIENV->is_hotspot());
2858 PEER_JVMCIENV->check_init(JVMCI_CHECK_0);
2859
2860 JVMCIEnv* thisEnv = JVMCIENV;
2861 JVMCIObject obj = thisEnv->wrap(obj_handle);
2862 JVMCIObject result;
2863 if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
2864 methodHandle method(THREAD, thisEnv->asMethod(obj));
2865 result = PEER_JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_0);
2866 } else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
2867 Klass* klass = thisEnv->asKlass(obj);
2868 JVMCIKlassHandle klass_handle(THREAD);
2869 klass_handle = klass;
2870 result = PEER_JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
2871 } else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
2872 BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
2873 result = PEER_JVMCIENV->get_jvmci_primitive_type(type, JVMCI_CHECK_0);
2874 } else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
2875 thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
2876 Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
2877 result = PEER_JVMCIENV->get_object_constant(constant());
2878 } else if (thisEnv->isa_HotSpotNmethod(obj)) {
2879 if (PEER_JVMCIENV->is_hotspot()) {
2880 JVMCINMethodHandle nmethod_handle(THREAD);
2881 nmethod* nm = JVMCIENV->get_nmethod(obj, nmethod_handle);
2882 if (nm != nullptr) {
2883 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2884 if (data != nullptr) {
2885 // Only the mirror in the HotSpot heap is accessible
2886 // through JVMCINMethodData
2887 oop nmethod_mirror = data->get_nmethod_mirror(nm);
2888 if (nmethod_mirror != nullptr) {
2889 result = HotSpotJVMCI::wrap(nmethod_mirror);
2890 }
2891 }
2892 }
2893 }
2962 C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
2963 JVMCIObject code = JVMCIENV->wrap(code_handle);
2964 CodeBlob* cb = JVMCIENV->get_code_blob(code);
2965 if (cb == nullptr) {
2966 return nullptr;
2967 }
2968 // Make a resource copy of code before the allocation causes a safepoint
2969 int code_size = cb->code_size();
2970 jbyte* code_bytes = NEW_RESOURCE_ARRAY(jbyte, code_size);
2971 memcpy(code_bytes, (jbyte*) cb->code_begin(), code_size);
2972
2973 JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
2974 JVMCIENV->copy_bytes_from(code_bytes, result, 0, code_size);
2975 return JVMCIENV->get_jbyteArray(result);
2976 C2V_END
2977
2978 C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
2979 requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
2980 methodHandle m(THREAD, UNPACK_PAIR(Method, method));
2981 oop executable;
2982 if (m->is_class_initializer()) {
2983 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2984 "Cannot create java.lang.reflect.Method for class initializer");
2985 }
2986 else if (m->is_object_constructor()) {
2987 executable = Reflection::new_constructor(m, CHECK_NULL);
2988 } else {
2989 executable = Reflection::new_method(m, false, CHECK_NULL);
2990 }
2991 return JNIHandles::make_local(THREAD, executable);
2992 C2V_END
2993
2994 // Checks that `index` denotes a non-injected field in `klass`
2995 static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) {
2996 if (!klass->is_instance_klass()) {
2997 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2998 err_msg("Expected non-primitive type, got %s", klass->external_name()));
2999 }
3000 InstanceKlass* iklass = InstanceKlass::cast(klass);
3001 if (index < 0 || index >= iklass->java_fields_count()) {
3002 if (index >= 0 && index < iklass->total_fields_count()) {
3003 fieldDescriptor fd(iklass, index);
3004 if (fd.is_injected()) {
3005 JVMCI_THROW_MSG_NULL(IllegalArgumentException,
3006 err_msg("Cannot get Field for injected %s.%s", klass->external_name(), fd.name()->as_C_string()));
3007 }
3111 int result_length = 0;
3112 for (FailedSpeculation* fs = head; fs != nullptr; fs = fs->next()) {
3113 result_length++;
3114 }
3115 int current_length = 0;
3116 JVMCIObjectArray current_array = nullptr;
3117 if (current != nullptr) {
3118 current_array = JVMCIENV->wrap(current);
3119 current_length = JVMCIENV->get_length(current_array);
3120 if (current_length == result_length) {
3121 // No new failures
3122 return current;
3123 }
3124 }
3125 JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);
3126 int result_index = 0;
3127 for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {
3128 assert(fs != nullptr, "npe");
3129 JVMCIPrimitiveArray entry;
3130 if (result_index < current_length) {
3131 entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index, JVMCI_CHECK_NULL);
3132 } else {
3133 entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);
3134 JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());
3135 }
3136 JVMCIENV->put_object_at(result, result_index++, entry);
3137 }
3138 return JVMCIENV->get_jobjectArray(result);
3139 C2V_END
3140
3141 C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
3142 methodHandle method(THREAD, UNPACK_PAIR(Method, method));
3143 MethodData* method_data = get_profiling_method_data(method, CHECK_0);
3144 return (jlong) method_data->get_failed_speculations_address();
3145 C2V_END
3146
3147 C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
3148 FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
3149 C2V_END
3150
3151 C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
|