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