1 /*
2  * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3  * Copyright 2007, 2008, 2010 Red Hat, Inc.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  *
24  */
25 
26 #include "precompiled.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "interpreter/interpreterRuntime.hpp"
29 #include "memory/allocation.inline.hpp"
30 #include "oops/method.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/icache.hpp"
34 #include "runtime/interfaceSupport.inline.hpp"
35 #include "runtime/signature.hpp"
36 #include "stack_zero.inline.hpp"
37 #include "utilities/align.hpp"
38 
pass_int()39 void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() {
40   push(T_INT);
41   _cif->nargs++;
42 }
43 
pass_long()44 void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() {
45   push(T_LONG);
46   _cif->nargs++;
47 }
48 
pass_float()49 void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() {
50   push(T_FLOAT);
51   _cif->nargs++;
52 }
53 
pass_double()54 void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() {
55   push(T_DOUBLE);
56   _cif->nargs++;
57 }
58 
pass_object()59 void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() {
60   push(T_OBJECT);
61   _cif->nargs++;
62 }
63 
push(BasicType type)64 void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) {
65   ffi_type *ftype = NULL;
66   switch (type) {
67   case T_VOID:
68     ftype = &ffi_type_void;
69     break;
70 
71   case T_BOOLEAN:
72     ftype = &ffi_type_uint8;
73     break;
74 
75   case T_CHAR:
76     ftype = &ffi_type_uint16;
77     break;
78 
79   case T_BYTE:
80     ftype = &ffi_type_sint8;
81     break;
82 
83   case T_SHORT:
84     ftype = &ffi_type_sint16;
85     break;
86 
87   case T_INT:
88     ftype = &ffi_type_sint32;
89     break;
90 
91   case T_LONG:
92     ftype = &ffi_type_sint64;
93     break;
94 
95   case T_FLOAT:
96     ftype = &ffi_type_float;
97     break;
98 
99   case T_DOUBLE:
100     ftype = &ffi_type_double;
101     break;
102 
103   case T_OBJECT:
104   case T_ARRAY:
105     ftype = &ffi_type_pointer;
106     break;
107 
108   default:
109     ShouldNotReachHere();
110   }
111   push((intptr_t) ftype);
112 }
113 
114 // For fast signature handlers the "signature handler" is generated
115 // into a temporary buffer.  It is then copied to its final location,
116 // and pd_set_handler is called on it.  We have this two stage thing
117 // to accomodate this.
118 
generate(uint64_t fingerprint)119 void InterpreterRuntime::SignatureHandlerGeneratorBase::generate(
120   uint64_t fingerprint) {
121 
122   // Build the argument types list
123   pass_object();
124   if (method()->is_static())
125     pass_object();
126   iterate(fingerprint);
127 
128   // Tack on the result type
129   push(method()->result_type());
130 }
131 
SignatureHandlerGenerator(const methodHandle & method,CodeBuffer * buffer)132 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer)
133   : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->insts_end()),
134     _cb(buffer) {
135   _cb->set_insts_end((address) (cif() + 1));
136 }
137 
push(intptr_t value)138 void InterpreterRuntime::SignatureHandlerGenerator::push(intptr_t value) {
139   intptr_t *dst = (intptr_t *) _cb->insts_end();
140   _cb->set_insts_end((address) (dst + 1));
141   *dst = value;
142 }
143 
finalize()144 void InterpreterRuntime::SignatureHandler::finalize() {
145   ffi_status status =
146     ffi_prep_cif(cif(),
147                  FFI_DEFAULT_ABI,
148                  argument_count(),
149                  result_type(),
150                  argument_types());
151 
152   assert(status == FFI_OK, "should be");
153 }
154 
155 JRT_ENTRY(address,
156           InterpreterRuntime::slow_signature_handler(JavaThread* current,
157                                                      Method*     method,
158                                                      intptr_t*   unused1,
159                                                      intptr_t*   unused2))
160   ZeroStack *stack = current->zero_stack();
161 
162   int required_words =
163     (align_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) +
164     (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1;
165 
166   stack->overflow_check(required_words, CHECK_NULL);
167 
168   intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
169   SlowSignatureHandlerGenerator sshg(methodHandle(current, method), buf);
170   sshg.generate((uint64_t)CONST64(-1));
171 
172   SignatureHandler *handler = sshg.handler();
173   handler->finalize();
174 
175   return (address) handler;
176 JRT_END
177 
pd_set_handler(address handlerAddr)178 void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) {
179   InterpreterRuntime::SignatureHandler *handler =
180     InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
181 
182   handler->finalize();
183 }
184