Path: blob/master/src/hotspot/share/prims/foreign_globals.cpp
41144 views
/*1* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "foreign_globals.hpp"25#include "classfile/symbolTable.hpp"26#include "classfile/systemDictionary.hpp"27#include "classfile/vmSymbols.hpp"28#include "memory/resourceArea.hpp"29#include "runtime/fieldDescriptor.hpp"30#include "runtime/fieldDescriptor.inline.hpp"3132#define FOREIGN_ABI "jdk/internal/foreign/abi/"3334static int field_offset(InstanceKlass* cls, const char* fieldname, Symbol* sigsym) {35TempNewSymbol fieldnamesym = SymbolTable::new_symbol(fieldname, (int)strlen(fieldname));36fieldDescriptor fd;37bool success = cls->find_field(fieldnamesym, sigsym, false, &fd);38assert(success, "Field not found");39return fd.offset();40}4142static InstanceKlass* find_InstanceKlass(const char* name, TRAPS) {43TempNewSymbol sym = SymbolTable::new_symbol(name, (int)strlen(name));44Klass* k = SystemDictionary::resolve_or_null(sym, Handle(), Handle(), THREAD);45assert(k != nullptr, "Can not find class: %s", name);46return InstanceKlass::cast(k);47}4849const ForeignGlobals& ForeignGlobals::instance() {50static ForeignGlobals globals; // thread-safe lazy init-once (since C++11)51return globals;52}5354const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) {55return instance().parse_abi_descriptor_impl(jabi);56}57const BufferLayout ForeignGlobals::parse_buffer_layout(jobject jlayout) {58return instance().parse_buffer_layout_impl(jlayout);59}6061const CallRegs ForeignGlobals::parse_call_regs(jobject jconv) {62return instance().parse_call_regs_impl(jconv);63}6465ForeignGlobals::ForeignGlobals() {66JavaThread* current_thread = JavaThread::current();67ResourceMark rm(current_thread);6869// ABIDescriptor70InstanceKlass* k_ABI = find_InstanceKlass(FOREIGN_ABI "ABIDescriptor", current_thread);71const char* strVMSArrayArray = "[[L" FOREIGN_ABI "VMStorage;";72Symbol* symVMSArrayArray = SymbolTable::new_symbol(strVMSArrayArray);73ABI.inputStorage_offset = field_offset(k_ABI, "inputStorage", symVMSArrayArray);74ABI.outputStorage_offset = field_offset(k_ABI, "outputStorage", symVMSArrayArray);75ABI.volatileStorage_offset = field_offset(k_ABI, "volatileStorage", symVMSArrayArray);76ABI.stackAlignment_offset = field_offset(k_ABI, "stackAlignment", vmSymbols::int_signature());77ABI.shadowSpace_offset = field_offset(k_ABI, "shadowSpace", vmSymbols::int_signature());7879// VMStorage80InstanceKlass* k_VMS = find_InstanceKlass(FOREIGN_ABI "VMStorage", current_thread);81VMS.index_offset = field_offset(k_VMS, "index", vmSymbols::int_signature());82VMS.type_offset = field_offset(k_VMS, "type", vmSymbols::int_signature());8384// BufferLayout85InstanceKlass* k_BL = find_InstanceKlass(FOREIGN_ABI "BufferLayout", current_thread);86BL.size_offset = field_offset(k_BL, "size", vmSymbols::long_signature());87BL.arguments_next_pc_offset = field_offset(k_BL, "arguments_next_pc", vmSymbols::long_signature());88BL.stack_args_bytes_offset = field_offset(k_BL, "stack_args_bytes", vmSymbols::long_signature());89BL.stack_args_offset = field_offset(k_BL, "stack_args", vmSymbols::long_signature());90BL.input_type_offsets_offset = field_offset(k_BL, "input_type_offsets", vmSymbols::long_array_signature());91BL.output_type_offsets_offset = field_offset(k_BL, "output_type_offsets", vmSymbols::long_array_signature());9293// CallRegs94const char* strVMSArray = "[L" FOREIGN_ABI "VMStorage;";95Symbol* symVMSArray = SymbolTable::new_symbol(strVMSArray);96InstanceKlass* k_CC = find_InstanceKlass(FOREIGN_ABI "ProgrammableUpcallHandler$CallRegs", current_thread);97CallConvOffsets.arg_regs_offset = field_offset(k_CC, "argRegs", symVMSArray);98CallConvOffsets.ret_regs_offset = field_offset(k_CC, "retRegs", symVMSArray);99}100101void CallRegs::calling_convention(BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt) const {102int src_pos = 0;103for (uint i = 0; i < argcnt; i++) {104switch (sig_bt[i]) {105case T_BOOLEAN:106case T_CHAR:107case T_BYTE:108case T_SHORT:109case T_INT:110case T_FLOAT:111assert(src_pos < _args_length, "oob");112parm_regs[i].set1(_arg_regs[src_pos++]);113break;114case T_LONG:115case T_DOUBLE:116assert((i + 1) < argcnt && sig_bt[i + 1] == T_VOID, "expecting half");117assert(src_pos < _args_length, "oob");118parm_regs[i].set2(_arg_regs[src_pos++]);119break;120case T_VOID: // Halves of longs and doubles121assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");122parm_regs[i].set_bad();123break;124default:125ShouldNotReachHere();126break;127}128}129}130131132