stubRoutines.hpp revision 0:a61af66fc99e
1/*
2 * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25// StubRoutines provides entry points to assembly routines used by
26// compiled code and the run-time system. Platform-specific entry
27// points are defined in the platform-specific inner class.
28//
29// Class scheme:
30//
31//    platform-independent               platform-dependent
32//
33//    stubRoutines.hpp  <-- included --  stubRoutines_<arch>.hpp
34//           ^                                  ^
35//           |                                  |
36//       implements                         implements
37//           |                                  |
38//           |                                  |
39//    stubRoutines.cpp                   stubRoutines_<arch>.cpp
40//    stubRoutines_<os_family>.cpp       stubGenerator_<arch>.cpp
41//    stubRoutines_<os_arch>.cpp
42//
43// Note 1: The important thing is a clean decoupling between stub
44//         entry points (interfacing to the whole vm; i.e., 1-to-n
45//         relationship) and stub generators (interfacing only to
46//         the entry points implementation; i.e., 1-to-1 relationship).
47//         This significantly simplifies changes in the generator
48//         structure since the rest of the vm is not affected.
49//
50// Note 2: stubGenerator_<arch>.cpp contains a minimal portion of
51//         machine-independent code; namely the generator calls of
52//         the generator functions that are used platform-independently.
53//         However, it comes with the advantage of having a 1-file
54//         implementation of the generator. It should be fairly easy
55//         to change, should it become a problem later.
56//
57// Scheme for adding a new entry point:
58//
59// 1. determine if it's a platform-dependent or independent entry point
60//    a) if platform independent: make subsequent changes in the independent files
61//    b) if platform   dependent: make subsequent changes in the   dependent files
62// 2. add a private instance variable holding the entry point address
63// 3. add a public accessor function to the instance variable
64// 4. implement the corresponding generator function in the platform-dependent
65//    stubGenerator_<arch>.cpp file and call the function in generate_all() of that file
66
67
68class StubRoutines: AllStatic {
69
70 public:
71  enum platform_independent_constants {
72    max_size_of_parameters = 256                           // max. parameter size supported by megamorphic lookups
73  };
74
75  // Dependencies
76  friend class StubGenerator;
77  #include "incls/_stubRoutines_pd.hpp.incl"               // machine-specific parts
78
79  static jint    _verify_oop_count;
80  static address _verify_oop_subroutine_entry;
81
82  static address _call_stub_return_address;                // the return PC, when returning to a call stub
83  static address _call_stub_entry;
84  static address _forward_exception_entry;
85  static address _catch_exception_entry;
86  static address _throw_AbstractMethodError_entry;
87  static address _throw_ArithmeticException_entry;
88  static address _throw_NullPointerException_entry;
89  static address _throw_NullPointerException_at_call_entry;
90  static address _throw_StackOverflowError_entry;
91  static address _handler_for_unsafe_access_entry;
92
93  static address _atomic_xchg_entry;
94  static address _atomic_xchg_ptr_entry;
95  static address _atomic_store_entry;
96  static address _atomic_store_ptr_entry;
97  static address _atomic_cmpxchg_entry;
98  static address _atomic_cmpxchg_ptr_entry;
99  static address _atomic_cmpxchg_long_entry;
100  static address _atomic_add_entry;
101  static address _atomic_add_ptr_entry;
102  static address _fence_entry;
103  static address _d2i_wrapper;
104  static address _d2l_wrapper;
105
106  static jint    _fpu_cntrl_wrd_std;
107  static jint    _fpu_cntrl_wrd_24;
108  static jint    _fpu_cntrl_wrd_64;
109  static jint    _fpu_cntrl_wrd_trunc;
110  static jint    _mxcsr_std;
111  static jint    _fpu_subnormal_bias1[3];
112  static jint    _fpu_subnormal_bias2[3];
113
114  static BufferBlob* _code1;                               // code buffer for initial routines
115  static BufferBlob* _code2;                               // code buffer for all other routines
116
117  // Leaf routines which implement arraycopy and their addresses
118  // arraycopy operands aligned on element type boundary
119  static address _jbyte_arraycopy;
120  static address _jshort_arraycopy;
121  static address _jint_arraycopy;
122  static address _jlong_arraycopy;
123  static address _oop_arraycopy;
124  static address _jbyte_disjoint_arraycopy;
125  static address _jshort_disjoint_arraycopy;
126  static address _jint_disjoint_arraycopy;
127  static address _jlong_disjoint_arraycopy;
128  static address _oop_disjoint_arraycopy;
129
130  // arraycopy operands aligned on zero'th element boundary
131  // These are identical to the ones aligned aligned on an
132  // element type boundary, except that they assume that both
133  // source and destination are HeapWord aligned.
134  static address _arrayof_jbyte_arraycopy;
135  static address _arrayof_jshort_arraycopy;
136  static address _arrayof_jint_arraycopy;
137  static address _arrayof_jlong_arraycopy;
138  static address _arrayof_oop_arraycopy;
139  static address _arrayof_jbyte_disjoint_arraycopy;
140  static address _arrayof_jshort_disjoint_arraycopy;
141  static address _arrayof_jint_disjoint_arraycopy;
142  static address _arrayof_jlong_disjoint_arraycopy;
143  static address _arrayof_oop_disjoint_arraycopy;
144
145  // these are recommended but optional:
146  static address _checkcast_arraycopy;
147  static address _unsafe_arraycopy;
148  static address _generic_arraycopy;
149
150 public:
151  // Initialization/Testing
152  static void    initialize1();                            // must happen before universe::genesis
153  static void    initialize2();                            // must happen after  universe::genesis
154
155  static bool contains(address addr) {
156    return
157      (_code1 != NULL && _code1->blob_contains(addr)) ||
158      (_code2 != NULL && _code2->blob_contains(addr)) ;
159  }
160
161  // Debugging
162  static jint    verify_oop_count()                        { return _verify_oop_count; }
163  static jint*   verify_oop_count_addr()                   { return &_verify_oop_count; }
164  // a subroutine for debugging the GC
165  static address verify_oop_subroutine_entry_address()    { return (address)&_verify_oop_subroutine_entry; }
166
167  static address catch_exception_entry()                   { return _catch_exception_entry; }
168
169  // Calls to Java
170  typedef void (*CallStub)(
171    address   link,
172    intptr_t* result,
173    BasicType result_type,
174    methodOopDesc* method,
175    address   entry_point,
176    intptr_t* parameters,
177    int       size_of_parameters,
178    TRAPS
179  );
180
181  static CallStub call_stub()                              { return CAST_TO_FN_PTR(CallStub, _call_stub_entry); }
182
183  // Exceptions
184  static address forward_exception_entry()                 { return _forward_exception_entry; }
185  // Implicit exceptions
186  static address throw_AbstractMethodError_entry()         { return _throw_AbstractMethodError_entry; }
187  static address throw_ArithmeticException_entry()         { return _throw_ArithmeticException_entry; }
188  static address throw_NullPointerException_entry()        { return _throw_NullPointerException_entry; }
189  static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
190  static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }
191
192  // Exceptions during unsafe access - should throw Java exception rather
193  // than crash.
194  static address handler_for_unsafe_access()               { return _handler_for_unsafe_access_entry; }
195
196  static address atomic_xchg_entry()                       { return _atomic_xchg_entry; }
197  static address atomic_xchg_ptr_entry()                   { return _atomic_xchg_ptr_entry; }
198  static address atomic_store_entry()                      { return _atomic_store_entry; }
199  static address atomic_store_ptr_entry()                  { return _atomic_store_ptr_entry; }
200  static address atomic_cmpxchg_entry()                    { return _atomic_cmpxchg_entry; }
201  static address atomic_cmpxchg_ptr_entry()                { return _atomic_cmpxchg_ptr_entry; }
202  static address atomic_cmpxchg_long_entry()               { return _atomic_cmpxchg_long_entry; }
203  static address atomic_add_entry()                        { return _atomic_add_entry; }
204  static address atomic_add_ptr_entry()                    { return _atomic_add_ptr_entry; }
205  static address fence_entry()                             { return _fence_entry; }
206
207  static address d2i_wrapper()                             { return _d2i_wrapper; }
208  static address d2l_wrapper()                             { return _d2l_wrapper; }
209  static jint    fpu_cntrl_wrd_std()                       { return _fpu_cntrl_wrd_std;   }
210  static address addr_fpu_cntrl_wrd_std()                  { return (address)&_fpu_cntrl_wrd_std;   }
211  static address addr_fpu_cntrl_wrd_24()                   { return (address)&_fpu_cntrl_wrd_24;   }
212  static address addr_fpu_cntrl_wrd_64()                   { return (address)&_fpu_cntrl_wrd_64;   }
213  static address addr_fpu_cntrl_wrd_trunc()                { return (address)&_fpu_cntrl_wrd_trunc; }
214  static address addr_mxcsr_std()                          { return (address)&_mxcsr_std; }
215  static address addr_fpu_subnormal_bias1()                { return (address)&_fpu_subnormal_bias1; }
216  static address addr_fpu_subnormal_bias2()                { return (address)&_fpu_subnormal_bias2; }
217
218
219  static address jbyte_arraycopy()  { return _jbyte_arraycopy; }
220  static address jshort_arraycopy() { return _jshort_arraycopy; }
221  static address jint_arraycopy()   { return _jint_arraycopy; }
222  static address jlong_arraycopy()  { return _jlong_arraycopy; }
223  static address oop_arraycopy()    { return _oop_arraycopy; }
224  static address jbyte_disjoint_arraycopy()  { return _jbyte_disjoint_arraycopy; }
225  static address jshort_disjoint_arraycopy() { return _jshort_disjoint_arraycopy; }
226  static address jint_disjoint_arraycopy()   { return _jint_disjoint_arraycopy; }
227  static address jlong_disjoint_arraycopy()  { return _jlong_disjoint_arraycopy; }
228  static address oop_disjoint_arraycopy()    { return _oop_disjoint_arraycopy; }
229
230  static address arrayof_jbyte_arraycopy()  { return _arrayof_jbyte_arraycopy; }
231  static address arrayof_jshort_arraycopy() { return _arrayof_jshort_arraycopy; }
232  static address arrayof_jint_arraycopy()   { return _arrayof_jint_arraycopy; }
233  static address arrayof_jlong_arraycopy()  { return _arrayof_jlong_arraycopy; }
234  static address arrayof_oop_arraycopy()    { return _arrayof_oop_arraycopy; }
235
236  static address arrayof_jbyte_disjoint_arraycopy()  { return _arrayof_jbyte_disjoint_arraycopy; }
237  static address arrayof_jshort_disjoint_arraycopy() { return _arrayof_jshort_disjoint_arraycopy; }
238  static address arrayof_jint_disjoint_arraycopy()   { return _arrayof_jint_disjoint_arraycopy; }
239  static address arrayof_jlong_disjoint_arraycopy()  { return _arrayof_jlong_disjoint_arraycopy; }
240  static address arrayof_oop_disjoint_arraycopy()    { return _arrayof_oop_disjoint_arraycopy; }
241
242  static address checkcast_arraycopy()     { return _checkcast_arraycopy; }
243  static address unsafe_arraycopy()        { return _unsafe_arraycopy; }
244  static address generic_arraycopy()       { return _generic_arraycopy; }
245
246  //
247  // Default versions of the above arraycopy functions for platforms which do
248  // not have specialized versions
249  //
250  static void jbyte_copy (jbyte*  src, jbyte*  dest, size_t count);
251  static void jshort_copy(jshort* src, jshort* dest, size_t count);
252  static void jint_copy  (jint*   src, jint*   dest, size_t count);
253  static void jlong_copy (jlong*  src, jlong*  dest, size_t count);
254  static void oop_copy   (oop*    src, oop*    dest, size_t count);
255
256  static void arrayof_jbyte_copy (HeapWord* src, HeapWord* dest, size_t count);
257  static void arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count);
258  static void arrayof_jint_copy  (HeapWord* src, HeapWord* dest, size_t count);
259  static void arrayof_jlong_copy (HeapWord* src, HeapWord* dest, size_t count);
260  static void arrayof_oop_copy   (HeapWord* src, HeapWord* dest, size_t count);
261};
262