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