2
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26
#include "precompiled.hpp"
27
#include "asm/assembler.inline.hpp"
28
#include "interpreter/interpreter.hpp"
29
#include "nativeInst_zero.hpp"
30
#include "oops/instanceOop.hpp"
31
#include "oops/method.hpp"
32
#include "oops/objArrayKlass.hpp"
33
#include "oops/oop.inline.hpp"
34
#include "prims/methodHandles.hpp"
35
#include "runtime/frame.inline.hpp"
36
#include "runtime/handles.inline.hpp"
37
#include "runtime/javaThread.hpp"
38
#include "runtime/sharedRuntime.hpp"
39
#include "runtime/stubCodeGenerator.hpp"
40
#include "runtime/stubRoutines.hpp"
41
#include "stack_zero.inline.hpp"
43
#include "opto/runtime.hpp"
46
// Declaration and definition of StubGenerator (no .hpp file).
47
// For a more detailed description of the stub routine structure
48
// see the comment in stubRoutines.hpp
50
class StubGenerator: public StubCodeGenerator {
52
// The call stub is used to call Java from C
53
static void call_stub(
54
JavaCallWrapper *call_wrapper,
56
BasicType result_type,
62
JavaThread *thread = THREAD;
63
ZeroStack *stack = thread->zero_stack();
65
// Make sure we have no pending exceptions
66
assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception");
68
// Set up the stack if necessary
69
bool stack_needs_teardown = false;
70
if (stack->needs_setup()) {
71
size_t zero_stack_size = stack->suggest_size(thread);
72
stack->setup(alloca(zero_stack_size), zero_stack_size);
73
stack_needs_teardown = true;
76
// Allocate and initialize our frame
78
EntryFrame::build(parameters, parameter_words, call_wrapper, THREAD);
80
if (!HAS_PENDING_EXCEPTION) {
82
thread->push_zero_frame(frame);
85
Interpreter::invoke_method(method, entry_point, THREAD);
88
if (!HAS_PENDING_EXCEPTION) {
89
switch (result_type) {
91
*(jint *) result = *(jint *) stack->sp();
94
*(jlong *) result = *(jlong *) stack->sp();
97
*(jfloat *) result = *(jfloat *) stack->sp();
100
*(jdouble *) result = *(jdouble *) stack->sp();
103
*(oop *) result = *(oop *) stack->sp();
106
ShouldNotReachHere();
111
thread->pop_zero_frame();
114
// Tear down the stack if necessary
115
if (stack_needs_teardown)
119
// These stubs get called from some dumb test routine.
120
// I'll write them properly when they're called from
121
// something that's actually doing something.
122
static void fake_arraycopy_stub(address src, address dst, int count) {
123
assert(count == 0, "huh?");
126
void generate_arraycopy_stubs() {
127
// Call the conjoint generation methods immediately after
128
// the disjoint ones so that short branches from the former
129
// to the latter can be generated.
130
StubRoutines::_jbyte_disjoint_arraycopy = (address) fake_arraycopy_stub;
131
StubRoutines::_jbyte_arraycopy = (address) fake_arraycopy_stub;
133
StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub;
134
StubRoutines::_jshort_arraycopy = (address) fake_arraycopy_stub;
136
StubRoutines::_jint_disjoint_arraycopy = (address) fake_arraycopy_stub;
137
StubRoutines::_jint_arraycopy = (address) fake_arraycopy_stub;
139
StubRoutines::_jlong_disjoint_arraycopy = (address) fake_arraycopy_stub;
140
StubRoutines::_jlong_arraycopy = (address) fake_arraycopy_stub;
142
StubRoutines::_oop_disjoint_arraycopy = ShouldNotCallThisStub();
143
StubRoutines::_oop_arraycopy = ShouldNotCallThisStub();
145
StubRoutines::_checkcast_arraycopy = ShouldNotCallThisStub();
146
StubRoutines::_generic_arraycopy = ShouldNotCallThisStub();
148
// Shared code tests for "null" to discover the stub is not generated.
149
StubRoutines::_unsafe_arraycopy = nullptr;
151
// Shared code tests for "null" to discover the stub is not generated.
152
StubRoutines::_unsafe_setmemory = nullptr;
154
// We don't generate specialized code for HeapWord-aligned source
155
// arrays, so just use the code we've already generated
156
StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
157
StubRoutines::_jbyte_disjoint_arraycopy;
158
StubRoutines::_arrayof_jbyte_arraycopy =
159
StubRoutines::_jbyte_arraycopy;
161
StubRoutines::_arrayof_jshort_disjoint_arraycopy =
162
StubRoutines::_jshort_disjoint_arraycopy;
163
StubRoutines::_arrayof_jshort_arraycopy =
164
StubRoutines::_jshort_arraycopy;
166
StubRoutines::_arrayof_jint_disjoint_arraycopy =
167
StubRoutines::_jint_disjoint_arraycopy;
168
StubRoutines::_arrayof_jint_arraycopy =
169
StubRoutines::_jint_arraycopy;
171
StubRoutines::_arrayof_jlong_disjoint_arraycopy =
172
StubRoutines::_jlong_disjoint_arraycopy;
173
StubRoutines::_arrayof_jlong_arraycopy =
174
StubRoutines::_jlong_arraycopy;
176
StubRoutines::_arrayof_oop_disjoint_arraycopy =
177
StubRoutines::_oop_disjoint_arraycopy;
178
StubRoutines::_arrayof_oop_arraycopy =
179
StubRoutines::_oop_arraycopy;
182
void generate_initial_stubs() {
183
// Generates all stubs and initializes the entry points
185
// entry points that exist in all platforms Note: This is code
186
// that could be shared among different platforms - however the
187
// benefit seems to be smaller than the disadvantage of having a
188
// much more complicated generator structure. See also comment in
191
StubRoutines::_forward_exception_entry = ShouldNotCallThisStub();
192
StubRoutines::_call_stub_entry = (address) call_stub;
193
StubRoutines::_catch_exception_entry = ShouldNotCallThisStub();
196
StubRoutines::_atomic_xchg_entry = ShouldNotCallThisStub();
197
StubRoutines::_atomic_cmpxchg_entry = ShouldNotCallThisStub();
198
StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub();
199
StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
200
StubRoutines::_fence_entry = ShouldNotCallThisStub();
203
void generate_final_stubs() {
204
// Generates all stubs and initializes the entry points
206
// These entry points require SharedInfo::stack0 to be set up in
207
// non-core builds and need to be relocatable, so they each
208
// fabricate a RuntimeStub internally.
209
StubRoutines::_throw_AbstractMethodError_entry =
210
ShouldNotCallThisStub();
212
StubRoutines::_throw_NullPointerException_at_call_entry =
213
ShouldNotCallThisStub();
215
StubRoutines::_throw_StackOverflowError_entry =
216
ShouldNotCallThisStub();
218
// support for verify_oop (must happen after universe_init)
219
StubRoutines::_verify_oop_subroutine_entry =
220
ShouldNotCallThisStub();
222
// arraycopy stubs used by compilers
223
generate_arraycopy_stubs();
228
StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) {
229
if (kind == Initial_stubs) {
230
generate_initial_stubs();
231
} else if (kind == Final_stubs) {
232
generate_final_stubs();
237
void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) {
238
StubGenerator g(code, kind);
241
EntryFrame *EntryFrame::build(const intptr_t* parameters,
243
JavaCallWrapper* call_wrapper,
246
ZeroStack *stack = THREAD->zero_stack();
247
stack->overflow_check(header_words + parameter_words, CHECK_NULL);
249
stack->push(0); // next_frame, filled in later
250
intptr_t *fp = stack->sp();
251
assert(fp - stack->sp() == next_frame_off, "should be");
253
stack->push(ENTRY_FRAME);
254
assert(fp - stack->sp() == frame_type_off, "should be");
256
stack->push((intptr_t) call_wrapper);
257
assert(fp - stack->sp() == call_wrapper_off, "should be");
259
for (int i = 0; i < parameter_words; i++)
260
stack->push(parameters[i]);
262
return (EntryFrame *) fp;