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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/codeBuffer.hpp"
27 #include "code/codeCacheExtensions.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "runtime/interfaceSupport.hpp"
31 #include "runtime/sharedRuntime.hpp"
32 #include "runtime/stubRoutines.hpp"
33 #include "runtime/timer.hpp"
34 #include "utilities/copy.hpp"
35 #ifdef COMPILER2
36 #include "opto/runtime.hpp"
37 #endif
38
39
40 // Implementation of StubRoutines - for a description
41 // of how to extend it, see the header file.
42
43 // Class Variables
44
45 BufferBlob* StubRoutines::_code1 = NULL;
46 BufferBlob* StubRoutines::_code2 = NULL;
47
166 double (* StubRoutines::_intrinsic_tan )(double) = NULL;
167
168 address StubRoutines::_safefetch32_entry = NULL;
169 address StubRoutines::_safefetch32_fault_pc = NULL;
170 address StubRoutines::_safefetch32_continuation_pc = NULL;
171 address StubRoutines::_safefetchN_entry = NULL;
172 address StubRoutines::_safefetchN_fault_pc = NULL;
173 address StubRoutines::_safefetchN_continuation_pc = NULL;
174
175 // Initialization
176 //
177 // Note: to break cycle with universe initialization, stubs are generated in two phases.
178 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
179 // The second phase includes all other stubs (which may depend on universe being initialized.)
180
181 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
182
183 void StubRoutines::initialize1() {
184 if (_code1 == NULL) {
185 ResourceMark rm;
186 TraceTime timer("StubRoutines generation 1", TraceStartupTime);
187 _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
188 if (_code1 == NULL) {
189 vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
190 }
191 CodeBuffer buffer(_code1);
192 StubGenerator_generate(&buffer, false);
193 // When new stubs added we need to make sure there is some space left
194 // to catch situation when we should increase size again.
195 assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1");
196 }
197 }
198
199
200 #ifdef ASSERT
201 typedef void (*arraycopy_fn)(address src, address dst, int count);
202
203 // simple tests of generated arraycopy functions
204 static void test_arraycopy_func(address func, int alignment) {
205 if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
206 // Exit safely if stubs were generated but cannot be used.
259 const intptr_t v1 = UCONST64(0xABCD00000000ABCD);
260 const intptr_t v2 = UCONST64(0xDEFD00000000DEFD);
261 #else
262 const intptr_t v1 = 0xABCDABCD;
263 const intptr_t v2 = 0xDEFDDEFD;
264 #endif
265 intptr_t dummy = v1;
266 intptr_t* const p_invalid = (intptr_t*) get_segfault_address();
267 intptr_t* const p_valid = &dummy;
268 intptr_t result_invalid = SafeFetchN(p_invalid, v2);
269 assert(result_invalid == v2, "SafeFetchN error");
270 intptr_t result_valid = SafeFetchN(p_valid, v2);
271 assert(result_valid == v1, "SafeFetchN error");
272 }
273 }
274 #endif
275
276 void StubRoutines::initialize2() {
277 if (_code2 == NULL) {
278 ResourceMark rm;
279 TraceTime timer("StubRoutines generation 2", TraceStartupTime);
280 _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
281 if (_code2 == NULL) {
282 vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");
283 }
284 CodeBuffer buffer(_code2);
285 StubGenerator_generate(&buffer, true);
286 // When new stubs added we need to make sure there is some space left
287 // to catch situation when we should increase size again.
288 assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2");
289 }
290
291 #ifdef ASSERT
292
293 #define TEST_ARRAYCOPY(type) \
294 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \
295 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \
296 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \
297 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
298
299 // Make sure all the arraycopy stubs properly handle zero count
|
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/codeBuffer.hpp"
27 #include "code/codeCacheExtensions.hpp"
28 #include "logging/log.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/interfaceSupport.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "runtime/stubRoutines.hpp"
34 #include "runtime/timer.hpp"
35 #include "utilities/copy.hpp"
36 #ifdef COMPILER2
37 #include "opto/runtime.hpp"
38 #endif
39
40
41 // Implementation of StubRoutines - for a description
42 // of how to extend it, see the header file.
43
44 // Class Variables
45
46 BufferBlob* StubRoutines::_code1 = NULL;
47 BufferBlob* StubRoutines::_code2 = NULL;
48
167 double (* StubRoutines::_intrinsic_tan )(double) = NULL;
168
169 address StubRoutines::_safefetch32_entry = NULL;
170 address StubRoutines::_safefetch32_fault_pc = NULL;
171 address StubRoutines::_safefetch32_continuation_pc = NULL;
172 address StubRoutines::_safefetchN_entry = NULL;
173 address StubRoutines::_safefetchN_fault_pc = NULL;
174 address StubRoutines::_safefetchN_continuation_pc = NULL;
175
176 // Initialization
177 //
178 // Note: to break cycle with universe initialization, stubs are generated in two phases.
179 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
180 // The second phase includes all other stubs (which may depend on universe being initialized.)
181
182 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
183
184 void StubRoutines::initialize1() {
185 if (_code1 == NULL) {
186 ResourceMark rm;
187 TraceTime timer("StubRoutines generation 1",
188 log_is_enabled(Info, startuptime),
189 LogTag::_startuptime);
190 _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
191 if (_code1 == NULL) {
192 vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
193 }
194 CodeBuffer buffer(_code1);
195 StubGenerator_generate(&buffer, false);
196 // When new stubs added we need to make sure there is some space left
197 // to catch situation when we should increase size again.
198 assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1");
199 }
200 }
201
202
203 #ifdef ASSERT
204 typedef void (*arraycopy_fn)(address src, address dst, int count);
205
206 // simple tests of generated arraycopy functions
207 static void test_arraycopy_func(address func, int alignment) {
208 if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
209 // Exit safely if stubs were generated but cannot be used.
262 const intptr_t v1 = UCONST64(0xABCD00000000ABCD);
263 const intptr_t v2 = UCONST64(0xDEFD00000000DEFD);
264 #else
265 const intptr_t v1 = 0xABCDABCD;
266 const intptr_t v2 = 0xDEFDDEFD;
267 #endif
268 intptr_t dummy = v1;
269 intptr_t* const p_invalid = (intptr_t*) get_segfault_address();
270 intptr_t* const p_valid = &dummy;
271 intptr_t result_invalid = SafeFetchN(p_invalid, v2);
272 assert(result_invalid == v2, "SafeFetchN error");
273 intptr_t result_valid = SafeFetchN(p_valid, v2);
274 assert(result_valid == v1, "SafeFetchN error");
275 }
276 }
277 #endif
278
279 void StubRoutines::initialize2() {
280 if (_code2 == NULL) {
281 ResourceMark rm;
282 TraceTime timer("StubRoutines generation 2",
283 log_is_enabled(Info, startuptime),
284 LogTag::_startuptime);
285 _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
286 if (_code2 == NULL) {
287 vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");
288 }
289 CodeBuffer buffer(_code2);
290 StubGenerator_generate(&buffer, true);
291 // When new stubs added we need to make sure there is some space left
292 // to catch situation when we should increase size again.
293 assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2");
294 }
295
296 #ifdef ASSERT
297
298 #define TEST_ARRAYCOPY(type) \
299 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \
300 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \
301 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \
302 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
303
304 // Make sure all the arraycopy stubs properly handle zero count
|