mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
110 lines
4.7 KiB
C++
110 lines
4.7 KiB
C++
/*
|
|
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
#include "precompiled.hpp"
|
|
#include "runtime/interfaceSupport.inline.hpp"
|
|
#include "classfile/javaClasses.inline.hpp"
|
|
#include "code/vmreg.hpp"
|
|
#include "logging/logStream.hpp"
|
|
#include "memory/resourceArea.hpp"
|
|
#include "oops/typeArrayOop.inline.hpp"
|
|
#include "oops/oopCast.inline.hpp"
|
|
#include "prims/foreignGlobals.inline.hpp"
|
|
#include "prims/downcallLinker.hpp"
|
|
#include "runtime/jniHandles.inline.hpp"
|
|
|
|
JNI_ENTRY(jlong, NEP_makeDowncallStub(JNIEnv* env, jclass _unused, jobject method_type, jobject jabi,
|
|
jobjectArray arg_moves, jobjectArray ret_moves, jboolean needs_return_buffer))
|
|
ResourceMark rm;
|
|
const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi);
|
|
|
|
oop type = JNIHandles::resolve(method_type);
|
|
objArrayOop arg_moves_oop = oop_cast<objArrayOop>(JNIHandles::resolve(arg_moves));
|
|
objArrayOop ret_moves_oop = oop_cast<objArrayOop>(JNIHandles::resolve(ret_moves));
|
|
int pcount = java_lang_invoke_MethodType::ptype_count(type);
|
|
int pslots = java_lang_invoke_MethodType::ptype_slot_count(type);
|
|
BasicType* basic_type = NEW_RESOURCE_ARRAY(BasicType, pslots);
|
|
|
|
GrowableArray<VMReg> input_regs(pcount);
|
|
for (int i = 0, bt_idx = 0; i < pcount; i++) {
|
|
oop type_oop = java_lang_invoke_MethodType::ptype(type, i);
|
|
assert(java_lang_Class::is_primitive(type_oop), "Only primitives expected");
|
|
BasicType bt = java_lang_Class::primitive_type(type_oop);
|
|
basic_type[bt_idx++] = bt;
|
|
input_regs.push(ForeignGlobals::parse_vmstorage(arg_moves_oop->obj_at(i)));
|
|
|
|
if (bt == BasicType::T_DOUBLE || bt == BasicType::T_LONG) {
|
|
basic_type[bt_idx++] = T_VOID;
|
|
// we only need these in the basic type
|
|
// NativeCallingConvention ignores them, but they are needed
|
|
// for JavaCallingConvention
|
|
}
|
|
}
|
|
|
|
|
|
jint outs = ret_moves_oop->length();
|
|
GrowableArray<VMReg> output_regs(outs);
|
|
oop type_oop = java_lang_invoke_MethodType::rtype(type);
|
|
BasicType ret_bt = java_lang_Class::primitive_type(type_oop);
|
|
for (int i = 0; i < outs; i++) {
|
|
// note that we don't care about long/double upper halfs here:
|
|
// we are NOT moving Java values, we are moving register-sized values
|
|
output_regs.push(ForeignGlobals::parse_vmstorage(ret_moves_oop->obj_at(i)));
|
|
}
|
|
|
|
return (jlong) DowncallLinker::make_downcall_stub(
|
|
basic_type, pslots, ret_bt, abi, input_regs, output_regs, needs_return_buffer)->code_begin();
|
|
JNI_END
|
|
|
|
JNI_ENTRY(jboolean, NEP_freeDowncallStub(JNIEnv* env, jclass _unused, jlong invoker))
|
|
// safe to call without code cache lock, because stub is always alive
|
|
CodeBlob* cb = CodeCache::find_blob((char*) invoker);
|
|
if (cb == nullptr) {
|
|
return false;
|
|
}
|
|
RuntimeStub::free(cb->as_runtime_stub());
|
|
return true;
|
|
JNI_END
|
|
|
|
#define CC (char*) /*cast a literal from (const char*)*/
|
|
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
|
|
#define METHOD_TYPE "Ljava/lang/invoke/MethodType;"
|
|
#define ABI_DESC "Ljdk/internal/foreign/abi/ABIDescriptor;"
|
|
#define VM_STORAGE_ARR "[Ljdk/internal/foreign/abi/VMStorage;"
|
|
|
|
static JNINativeMethod NEP_methods[] = {
|
|
{CC "makeDowncallStub", CC "(" METHOD_TYPE ABI_DESC VM_STORAGE_ARR VM_STORAGE_ARR "Z)J", FN_PTR(NEP_makeDowncallStub)},
|
|
{CC "freeDowncallStub0", CC "(J)Z", FN_PTR(NEP_freeDowncallStub)},
|
|
};
|
|
|
|
#undef METHOD_TYPE
|
|
#undef ABI_DESC
|
|
#undef VM_STORAGE_ARR
|
|
|
|
JNI_ENTRY(void, JVM_RegisterNativeEntryPointMethods(JNIEnv *env, jclass NEP_class))
|
|
ThreadToNativeFromVM ttnfv(thread);
|
|
int status = env->RegisterNatives(NEP_class, NEP_methods, sizeof(NEP_methods)/sizeof(JNINativeMethod));
|
|
guarantee(status == JNI_OK && !env->ExceptionOccurred(),
|
|
"register jdk.internal.foreign.abi.NativeEntryPoint natives");
|
|
JNI_END
|