stubGenerator_zero.cpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 2003, 2012, 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 "asm/assembler.hpp"
28#include "assembler_zero.inline.hpp"
29#include "interpreter/interpreter.hpp"
30#include "nativeInst_zero.hpp"
31#include "oops/instanceOop.hpp"
32#include "oops/method.hpp"
33#include "oops/objArrayKlass.hpp"
34#include "oops/oop.inline.hpp"
35#include "prims/methodHandles.hpp"
36#include "runtime/frame.inline.hpp"
37#include "runtime/handles.inline.hpp"
38#include "runtime/sharedRuntime.hpp"
39#include "runtime/stubCodeGenerator.hpp"
40#include "runtime/stubRoutines.hpp"
41#include "stack_zero.inline.hpp"
42#include "utilities/top.hpp"
43#ifdef TARGET_OS_FAMILY_linux
44# include "thread_linux.inline.hpp"
45#endif
46#ifdef TARGET_OS_FAMILY_bsd
47# include "thread_bsd.inline.hpp"
48#endif
49#ifdef COMPILER2
50#include "opto/runtime.hpp"
51#endif
52
53// Declaration and definition of StubGenerator (no .hpp file).
54// For a more detailed description of the stub routine structure
55// see the comment in stubRoutines.hpp
56
57class StubGenerator: public StubCodeGenerator {
58 private:
59  // The call stub is used to call Java from C
60  static void call_stub(
61    JavaCallWrapper *call_wrapper,
62    intptr_t*        result,
63    BasicType        result_type,
64    Method*          method,
65    address          entry_point,
66    intptr_t*        parameters,
67    int              parameter_words,
68    TRAPS) {
69    JavaThread *thread = (JavaThread *) THREAD;
70    ZeroStack *stack = thread->zero_stack();
71
72    // Make sure we have no pending exceptions
73    assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception");
74
75    // Set up the stack if necessary
76    bool stack_needs_teardown = false;
77    if (stack->needs_setup()) {
78      size_t zero_stack_size = stack->suggest_size(thread);
79      stack->setup(alloca(zero_stack_size), zero_stack_size);
80      stack_needs_teardown = true;
81    }
82
83    // Allocate and initialize our frame
84    EntryFrame *frame =
85      EntryFrame::build(parameters, parameter_words, call_wrapper, THREAD);
86
87    if (!HAS_PENDING_EXCEPTION) {
88      // Push the frame
89      thread->push_zero_frame(frame);
90
91      // Make the call
92      Interpreter::invoke_method(method, entry_point, THREAD);
93
94      // Store the result
95      if (!HAS_PENDING_EXCEPTION) {
96        switch (result_type) {
97        case T_INT:
98          *(jint *) result = *(jint *) stack->sp();
99          break;
100        case T_LONG:
101          *(jlong *) result = *(jlong *) stack->sp();
102          break;
103        case T_FLOAT:
104          *(jfloat *) result = *(jfloat *) stack->sp();
105          break;
106        case T_DOUBLE:
107          *(jdouble *) result = *(jdouble *) stack->sp();
108          break;
109        case T_OBJECT:
110          *(oop *) result = *(oop *) stack->sp();
111          break;
112        default:
113          ShouldNotReachHere();
114        }
115      }
116
117      // Unwind the frame
118      thread->pop_zero_frame();
119    }
120
121    // Tear down the stack if necessary
122    if (stack_needs_teardown)
123      stack->teardown();
124  }
125
126  // These stubs get called from some dumb test routine.
127  // I'll write them properly when they're called from
128  // something that's actually doing something.
129  static void fake_arraycopy_stub(address src, address dst, int count) {
130    assert(count == 0, "huh?");
131  }
132
133  void generate_arraycopy_stubs() {
134    // Call the conjoint generation methods immediately after
135    // the disjoint ones so that short branches from the former
136    // to the latter can be generated.
137    StubRoutines::_jbyte_disjoint_arraycopy  = (address) fake_arraycopy_stub;
138    StubRoutines::_jbyte_arraycopy           = (address) fake_arraycopy_stub;
139
140    StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub;
141    StubRoutines::_jshort_arraycopy          = (address) fake_arraycopy_stub;
142
143    StubRoutines::_jint_disjoint_arraycopy   = (address) fake_arraycopy_stub;
144    StubRoutines::_jint_arraycopy            = (address) fake_arraycopy_stub;
145
146    StubRoutines::_jlong_disjoint_arraycopy  = (address) fake_arraycopy_stub;
147    StubRoutines::_jlong_arraycopy           = (address) fake_arraycopy_stub;
148
149    StubRoutines::_oop_disjoint_arraycopy    = ShouldNotCallThisStub();
150    StubRoutines::_oop_arraycopy             = ShouldNotCallThisStub();
151
152    StubRoutines::_checkcast_arraycopy       = ShouldNotCallThisStub();
153    StubRoutines::_unsafe_arraycopy          = ShouldNotCallThisStub();
154    StubRoutines::_generic_arraycopy         = ShouldNotCallThisStub();
155
156    // We don't generate specialized code for HeapWord-aligned source
157    // arrays, so just use the code we've already generated
158    StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
159      StubRoutines::_jbyte_disjoint_arraycopy;
160    StubRoutines::_arrayof_jbyte_arraycopy =
161      StubRoutines::_jbyte_arraycopy;
162
163    StubRoutines::_arrayof_jshort_disjoint_arraycopy =
164      StubRoutines::_jshort_disjoint_arraycopy;
165    StubRoutines::_arrayof_jshort_arraycopy =
166      StubRoutines::_jshort_arraycopy;
167
168    StubRoutines::_arrayof_jint_disjoint_arraycopy =
169      StubRoutines::_jint_disjoint_arraycopy;
170    StubRoutines::_arrayof_jint_arraycopy =
171      StubRoutines::_jint_arraycopy;
172
173    StubRoutines::_arrayof_jlong_disjoint_arraycopy =
174      StubRoutines::_jlong_disjoint_arraycopy;
175    StubRoutines::_arrayof_jlong_arraycopy =
176      StubRoutines::_jlong_arraycopy;
177
178    StubRoutines::_arrayof_oop_disjoint_arraycopy =
179      StubRoutines::_oop_disjoint_arraycopy;
180    StubRoutines::_arrayof_oop_arraycopy =
181      StubRoutines::_oop_arraycopy;
182  }
183
184  void generate_initial() {
185    // Generates all stubs and initializes the entry points
186
187    // entry points that exist in all platforms Note: This is code
188    // that could be shared among different platforms - however the
189    // benefit seems to be smaller than the disadvantage of having a
190    // much more complicated generator structure. See also comment in
191    // stubRoutines.hpp.
192
193    StubRoutines::_forward_exception_entry   = ShouldNotCallThisStub();
194    StubRoutines::_call_stub_entry           = (address) call_stub;
195    StubRoutines::_catch_exception_entry     = ShouldNotCallThisStub();
196
197    // atomic calls
198    StubRoutines::_atomic_xchg_entry         = ShouldNotCallThisStub();
199    StubRoutines::_atomic_xchg_ptr_entry     = ShouldNotCallThisStub();
200    StubRoutines::_atomic_cmpxchg_entry      = ShouldNotCallThisStub();
201    StubRoutines::_atomic_cmpxchg_ptr_entry  = ShouldNotCallThisStub();
202    StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub();
203    StubRoutines::_atomic_add_entry          = ShouldNotCallThisStub();
204    StubRoutines::_atomic_add_ptr_entry      = ShouldNotCallThisStub();
205    StubRoutines::_fence_entry               = ShouldNotCallThisStub();
206
207    // amd64 does this here, sparc does it in generate_all()
208    StubRoutines::_handler_for_unsafe_access_entry =
209      ShouldNotCallThisStub();
210  }
211
212  void generate_all() {
213    // Generates all stubs and initializes the entry points
214
215    // These entry points require SharedInfo::stack0 to be set up in
216    // non-core builds and need to be relocatable, so they each
217    // fabricate a RuntimeStub internally.
218    StubRoutines::_throw_AbstractMethodError_entry =
219      ShouldNotCallThisStub();
220
221    StubRoutines::_throw_NullPointerException_at_call_entry =
222      ShouldNotCallThisStub();
223
224    StubRoutines::_throw_StackOverflowError_entry =
225      ShouldNotCallThisStub();
226
227    // support for verify_oop (must happen after universe_init)
228    StubRoutines::_verify_oop_subroutine_entry =
229      ShouldNotCallThisStub();
230
231    // arraycopy stubs used by compilers
232    generate_arraycopy_stubs();
233  }
234
235 public:
236  StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
237    if (all) {
238      generate_all();
239    } else {
240      generate_initial();
241    }
242  }
243};
244
245void StubGenerator_generate(CodeBuffer* code, bool all) {
246  StubGenerator g(code, all);
247}
248
249EntryFrame *EntryFrame::build(const intptr_t*  parameters,
250                              int              parameter_words,
251                              JavaCallWrapper* call_wrapper,
252                              TRAPS) {
253
254  ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
255  stack->overflow_check(header_words + parameter_words, CHECK_NULL);
256
257  stack->push(0); // next_frame, filled in later
258  intptr_t *fp = stack->sp();
259  assert(fp - stack->sp() == next_frame_off, "should be");
260
261  stack->push(ENTRY_FRAME);
262  assert(fp - stack->sp() == frame_type_off, "should be");
263
264  stack->push((intptr_t) call_wrapper);
265  assert(fp - stack->sp() == call_wrapper_off, "should be");
266
267  for (int i = 0; i < parameter_words; i++)
268    stack->push(parameters[i]);
269
270  return (EntryFrame *) fp;
271}
272