164 // Initialization
165 //
166 // Note: to break cycle with universe initialization, stubs are generated in two phases.
167 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
168 // The second phase includes all other stubs (which may depend on universe being initialized.)
169
170 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
171
172 void StubRoutines::initialize1() {
173 if (_code1 == NULL) {
174 ResourceMark rm;
175 TraceTime timer("StubRoutines generation 1", TraceStartupTime);
176 _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
177 if (_code1 == NULL) {
178 vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
179 }
180 CodeBuffer buffer(_code1);
181 StubGenerator_generate(&buffer, false);
182 // When new stubs added we need to make sure there is some space left
183 // to catch situation when we should increase size again.
184 assert(buffer.insts_remaining() > 200, "increase code_size1");
185 }
186 }
187
188
189 #ifdef ASSERT
190 typedef void (*arraycopy_fn)(address src, address dst, int count);
191
192 // simple tests of generated arraycopy functions
193 static void test_arraycopy_func(address func, int alignment) {
194 if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
195 // Exit safely if stubs were generated but cannot be used.
196 // Also excluding pregenerated interpreter since the code may depend on
197 // some registers being properly initialized (for instance Rthread)
198 return;
199 }
200 int v = 0xcc;
201 int v2 = 0x11;
202 jlong lbuffer[8];
203 jlong lbuffer2[8];
204 address fbuffer = (address) lbuffer;
257 intptr_t result_invalid = SafeFetchN(p_invalid, v2);
258 assert(result_invalid == v2, "SafeFetchN error");
259 intptr_t result_valid = SafeFetchN(p_valid, v2);
260 assert(result_valid == v1, "SafeFetchN error");
261 }
262 }
263 #endif
264
265 void StubRoutines::initialize2() {
266 if (_code2 == NULL) {
267 ResourceMark rm;
268 TraceTime timer("StubRoutines generation 2", TraceStartupTime);
269 _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
270 if (_code2 == NULL) {
271 vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");
272 }
273 CodeBuffer buffer(_code2);
274 StubGenerator_generate(&buffer, true);
275 // When new stubs added we need to make sure there is some space left
276 // to catch situation when we should increase size again.
277 assert(buffer.insts_remaining() > 200, "increase code_size2");
278 }
279
280 #ifdef ASSERT
281
282 #define TEST_ARRAYCOPY(type) \
283 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \
284 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \
285 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \
286 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
287
288 // Make sure all the arraycopy stubs properly handle zero count
289 TEST_ARRAYCOPY(jbyte);
290 TEST_ARRAYCOPY(jshort);
291 TEST_ARRAYCOPY(jint);
292 TEST_ARRAYCOPY(jlong);
293
294 #undef TEST_ARRAYCOPY
295
296 #define TEST_FILL(type) \
297 if (_##type##_fill != NULL) { \
|
164 // Initialization
165 //
166 // Note: to break cycle with universe initialization, stubs are generated in two phases.
167 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
168 // The second phase includes all other stubs (which may depend on universe being initialized.)
169
170 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
171
172 void StubRoutines::initialize1() {
173 if (_code1 == NULL) {
174 ResourceMark rm;
175 TraceTime timer("StubRoutines generation 1", TraceStartupTime);
176 _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
177 if (_code1 == NULL) {
178 vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
179 }
180 CodeBuffer buffer(_code1);
181 StubGenerator_generate(&buffer, false);
182 // When new stubs added we need to make sure there is some space left
183 // to catch situation when we should increase size again.
184 assert(code_size1 == 0 || buffer.insts_remaining() > 200, "increase code_size1");
185 }
186 }
187
188
189 #ifdef ASSERT
190 typedef void (*arraycopy_fn)(address src, address dst, int count);
191
192 // simple tests of generated arraycopy functions
193 static void test_arraycopy_func(address func, int alignment) {
194 if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
195 // Exit safely if stubs were generated but cannot be used.
196 // Also excluding pregenerated interpreter since the code may depend on
197 // some registers being properly initialized (for instance Rthread)
198 return;
199 }
200 int v = 0xcc;
201 int v2 = 0x11;
202 jlong lbuffer[8];
203 jlong lbuffer2[8];
204 address fbuffer = (address) lbuffer;
257 intptr_t result_invalid = SafeFetchN(p_invalid, v2);
258 assert(result_invalid == v2, "SafeFetchN error");
259 intptr_t result_valid = SafeFetchN(p_valid, v2);
260 assert(result_valid == v1, "SafeFetchN error");
261 }
262 }
263 #endif
264
265 void StubRoutines::initialize2() {
266 if (_code2 == NULL) {
267 ResourceMark rm;
268 TraceTime timer("StubRoutines generation 2", TraceStartupTime);
269 _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
270 if (_code2 == NULL) {
271 vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");
272 }
273 CodeBuffer buffer(_code2);
274 StubGenerator_generate(&buffer, true);
275 // When new stubs added we need to make sure there is some space left
276 // to catch situation when we should increase size again.
277 assert(code_size2 == 0 || buffer.insts_remaining() > 200, "increase code_size2");
278 }
279
280 #ifdef ASSERT
281
282 #define TEST_ARRAYCOPY(type) \
283 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \
284 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \
285 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \
286 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
287
288 // Make sure all the arraycopy stubs properly handle zero count
289 TEST_ARRAYCOPY(jbyte);
290 TEST_ARRAYCOPY(jshort);
291 TEST_ARRAYCOPY(jint);
292 TEST_ARRAYCOPY(jlong);
293
294 #undef TEST_ARRAYCOPY
295
296 #define TEST_FILL(type) \
297 if (_##type##_fill != NULL) { \
|