Mercurial > hg > truffle
comparison src/share/vm/opto/runtime.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | a5dd6e3ef9f3 |
children | 8a02ca5e5576 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
226 new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj); | 226 new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj); |
227 thread->set_vm_result(new_obj); | 227 thread->set_vm_result(new_obj); |
228 } | 228 } |
229 | 229 |
230 // object allocation | 230 // object allocation |
231 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThread* thread)) | 231 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thread)) |
232 JRT_BLOCK; | 232 JRT_BLOCK; |
233 #ifndef PRODUCT | 233 #ifndef PRODUCT |
234 SharedRuntime::_new_instance_ctr++; // new instance requires GC | 234 SharedRuntime::_new_instance_ctr++; // new instance requires GC |
235 #endif | 235 #endif |
236 assert(check_compiled_frame(thread), "incorrect caller"); | 236 assert(check_compiled_frame(thread), "incorrect caller"); |
237 | 237 |
238 // These checks are cheap to make and support reflective allocation. | 238 // These checks are cheap to make and support reflective allocation. |
239 int lh = Klass::cast(klass)->layout_helper(); | 239 int lh = Klass::cast(klass)->layout_helper(); |
240 if (Klass::layout_helper_needs_slow_path(lh) | 240 if (Klass::layout_helper_needs_slow_path(lh) |
241 || !instanceKlass::cast(klass)->is_initialized()) { | 241 || !InstanceKlass::cast(klass)->is_initialized()) { |
242 KlassHandle kh(THREAD, klass); | 242 KlassHandle kh(THREAD, klass); |
243 kh->check_valid_for_instantiation(false, THREAD); | 243 kh->check_valid_for_instantiation(false, THREAD); |
244 if (!HAS_PENDING_EXCEPTION) { | 244 if (!HAS_PENDING_EXCEPTION) { |
245 instanceKlass::cast(kh())->initialize(THREAD); | 245 InstanceKlass::cast(kh())->initialize(THREAD); |
246 } | 246 } |
247 if (!HAS_PENDING_EXCEPTION) { | 247 if (!HAS_PENDING_EXCEPTION) { |
248 klass = kh(); | 248 klass = kh(); |
249 } else { | 249 } else { |
250 klass = NULL; | 250 klass = NULL; |
251 } | 251 } |
252 } | 252 } |
253 | 253 |
254 if (klass != NULL) { | 254 if (klass != NULL) { |
255 // Scavenge and allocate an instance. | 255 // Scavenge and allocate an instance. |
256 oop result = instanceKlass::cast(klass)->allocate_instance(THREAD); | 256 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD); |
257 thread->set_vm_result(result); | 257 thread->set_vm_result(result); |
258 | 258 |
259 // Pass oops back through thread local storage. Our apparent type to Java | 259 // Pass oops back through thread local storage. Our apparent type to Java |
260 // is that we return an oop, but we can block on exit from this routine and | 260 // is that we return an oop, but we can block on exit from this routine and |
261 // a GC can trash the oop in C's return register. The generated stub will | 261 // a GC can trash the oop in C's return register. The generated stub will |
271 } | 271 } |
272 JRT_END | 272 JRT_END |
273 | 273 |
274 | 274 |
275 // array allocation | 275 // array allocation |
276 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len, JavaThread *thread)) | 276 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread *thread)) |
277 JRT_BLOCK; | 277 JRT_BLOCK; |
278 #ifndef PRODUCT | 278 #ifndef PRODUCT |
279 SharedRuntime::_new_array_ctr++; // new array requires GC | 279 SharedRuntime::_new_array_ctr++; // new array requires GC |
280 #endif | 280 #endif |
281 assert(check_compiled_frame(thread), "incorrect caller"); | 281 assert(check_compiled_frame(thread), "incorrect caller"); |
290 result = oopFactory::new_typeArray(elem_type, len, THREAD); | 290 result = oopFactory::new_typeArray(elem_type, len, THREAD); |
291 } else { | 291 } else { |
292 // Although the oopFactory likes to work with the elem_type, | 292 // Although the oopFactory likes to work with the elem_type, |
293 // the compiler prefers the array_type, since it must already have | 293 // the compiler prefers the array_type, since it must already have |
294 // that latter value in hand for the fast path. | 294 // that latter value in hand for the fast path. |
295 klassOopDesc* elem_type = objArrayKlass::cast(array_type)->element_klass(); | 295 Klass* elem_type = objArrayKlass::cast(array_type)->element_klass(); |
296 result = oopFactory::new_objArray(elem_type, len, THREAD); | 296 result = oopFactory::new_objArray(elem_type, len, THREAD); |
297 } | 297 } |
298 | 298 |
299 // Pass oops back through thread local storage. Our apparent type to Java | 299 // Pass oops back through thread local storage. Our apparent type to Java |
300 // is that we return an oop, but we can block on exit from this routine and | 300 // is that we return an oop, but we can block on exit from this routine and |
309 new_store_pre_barrier(thread); | 309 new_store_pre_barrier(thread); |
310 } | 310 } |
311 JRT_END | 311 JRT_END |
312 | 312 |
313 // array allocation without zeroing | 313 // array allocation without zeroing |
314 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(klassOopDesc* array_type, int len, JavaThread *thread)) | 314 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread *thread)) |
315 JRT_BLOCK; | 315 JRT_BLOCK; |
316 #ifndef PRODUCT | 316 #ifndef PRODUCT |
317 SharedRuntime::_new_array_ctr++; // new array requires GC | 317 SharedRuntime::_new_array_ctr++; // new array requires GC |
318 #endif | 318 #endif |
319 assert(check_compiled_frame(thread), "incorrect caller"); | 319 assert(check_compiled_frame(thread), "incorrect caller"); |
359 JRT_END | 359 JRT_END |
360 | 360 |
361 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array. | 361 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array. |
362 | 362 |
363 // multianewarray for 2 dimensions | 363 // multianewarray for 2 dimensions |
364 JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1, int len2, JavaThread *thread)) | 364 JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int len2, JavaThread *thread)) |
365 #ifndef PRODUCT | 365 #ifndef PRODUCT |
366 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension | 366 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension |
367 #endif | 367 #endif |
368 assert(check_compiled_frame(thread), "incorrect caller"); | 368 assert(check_compiled_frame(thread), "incorrect caller"); |
369 assert(oop(elem_type)->is_klass(), "not a class"); | 369 assert(elem_type->is_klass(), "not a class"); |
370 jint dims[2]; | 370 jint dims[2]; |
371 dims[0] = len1; | 371 dims[0] = len1; |
372 dims[1] = len2; | 372 dims[1] = len2; |
373 oop obj = arrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); | 373 oop obj = arrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); |
374 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | 374 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
375 thread->set_vm_result(obj); | 375 thread->set_vm_result(obj); |
376 JRT_END | 376 JRT_END |
377 | 377 |
378 // multianewarray for 3 dimensions | 378 // multianewarray for 3 dimensions |
379 JRT_ENTRY(void, OptoRuntime::multianewarray3_C(klassOopDesc* elem_type, int len1, int len2, int len3, JavaThread *thread)) | 379 JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int len2, int len3, JavaThread *thread)) |
380 #ifndef PRODUCT | 380 #ifndef PRODUCT |
381 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension | 381 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension |
382 #endif | 382 #endif |
383 assert(check_compiled_frame(thread), "incorrect caller"); | 383 assert(check_compiled_frame(thread), "incorrect caller"); |
384 assert(oop(elem_type)->is_klass(), "not a class"); | 384 assert(elem_type->is_klass(), "not a class"); |
385 jint dims[3]; | 385 jint dims[3]; |
386 dims[0] = len1; | 386 dims[0] = len1; |
387 dims[1] = len2; | 387 dims[1] = len2; |
388 dims[2] = len3; | 388 dims[2] = len3; |
389 oop obj = arrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); | 389 oop obj = arrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); |
390 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | 390 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
391 thread->set_vm_result(obj); | 391 thread->set_vm_result(obj); |
392 JRT_END | 392 JRT_END |
393 | 393 |
394 // multianewarray for 4 dimensions | 394 // multianewarray for 4 dimensions |
395 JRT_ENTRY(void, OptoRuntime::multianewarray4_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread)) | 395 JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread)) |
396 #ifndef PRODUCT | 396 #ifndef PRODUCT |
397 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension | 397 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension |
398 #endif | 398 #endif |
399 assert(check_compiled_frame(thread), "incorrect caller"); | 399 assert(check_compiled_frame(thread), "incorrect caller"); |
400 assert(oop(elem_type)->is_klass(), "not a class"); | 400 assert(elem_type->is_klass(), "not a class"); |
401 jint dims[4]; | 401 jint dims[4]; |
402 dims[0] = len1; | 402 dims[0] = len1; |
403 dims[1] = len2; | 403 dims[1] = len2; |
404 dims[2] = len3; | 404 dims[2] = len3; |
405 dims[3] = len4; | 405 dims[3] = len4; |
407 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | 407 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
408 thread->set_vm_result(obj); | 408 thread->set_vm_result(obj); |
409 JRT_END | 409 JRT_END |
410 | 410 |
411 // multianewarray for 5 dimensions | 411 // multianewarray for 5 dimensions |
412 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread)) | 412 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread)) |
413 #ifndef PRODUCT | 413 #ifndef PRODUCT |
414 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension | 414 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension |
415 #endif | 415 #endif |
416 assert(check_compiled_frame(thread), "incorrect caller"); | 416 assert(check_compiled_frame(thread), "incorrect caller"); |
417 assert(oop(elem_type)->is_klass(), "not a class"); | 417 assert(elem_type->is_klass(), "not a class"); |
418 jint dims[5]; | 418 jint dims[5]; |
419 dims[0] = len1; | 419 dims[0] = len1; |
420 dims[1] = len2; | 420 dims[1] = len2; |
421 dims[2] = len3; | 421 dims[2] = len3; |
422 dims[3] = len4; | 422 dims[3] = len4; |
424 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); | 424 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); |
425 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | 425 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
426 thread->set_vm_result(obj); | 426 thread->set_vm_result(obj); |
427 JRT_END | 427 JRT_END |
428 | 428 |
429 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(klassOopDesc* elem_type, arrayOopDesc* dims, JavaThread *thread)) | 429 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread *thread)) |
430 assert(check_compiled_frame(thread), "incorrect caller"); | 430 assert(check_compiled_frame(thread), "incorrect caller"); |
431 assert(oop(elem_type)->is_klass(), "not a class"); | 431 assert(elem_type->is_klass(), "not a class"); |
432 assert(oop(dims)->is_typeArray(), "not an array"); | 432 assert(oop(dims)->is_typeArray(), "not an array"); |
433 | 433 |
434 ResourceMark rm; | 434 ResourceMark rm; |
435 jint len = dims->length(); | 435 jint len = dims->length(); |
436 assert(len > 0, "Dimensions array should contain data"); | 436 assert(len > 0, "Dimensions array should contain data"); |
842 return TypeFunc::make(domain,range); | 842 return TypeFunc::make(domain,range); |
843 } | 843 } |
844 | 844 |
845 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) | 845 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) |
846 if (receiver == NULL) return; | 846 if (receiver == NULL) return; |
847 klassOop receiver_klass = receiver->klass(); | 847 Klass* receiver_klass = receiver->klass(); |
848 | 848 |
849 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells(); | 849 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells(); |
850 int empty_row = -1; // free row, if any is encountered | 850 int empty_row = -1; // free row, if any is encountered |
851 | 851 |
852 // ReceiverTypeData* vc = new ReceiverTypeData(mdp); | 852 // ReceiverTypeData* vc = new ReceiverTypeData(mdp); |
1146 // Dtrace support. entry and exit probes have the same signature | 1146 // Dtrace support. entry and exit probes have the same signature |
1147 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { | 1147 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { |
1148 // create input type (domain) | 1148 // create input type (domain) |
1149 const Type **fields = TypeTuple::fields(2); | 1149 const Type **fields = TypeTuple::fields(2); |
1150 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage | 1150 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage |
1151 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // methodOop; Method we are entering | 1151 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // Method*; Method we are entering |
1152 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); | 1152 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); |
1153 | 1153 |
1154 // create result type (range) | 1154 // create result type (range) |
1155 fields = TypeTuple::fields(0); | 1155 fields = TypeTuple::fields(0); |
1156 | 1156 |
1176 } | 1176 } |
1177 | 1177 |
1178 | 1178 |
1179 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread)) | 1179 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread)) |
1180 assert(obj->is_oop(), "must be a valid oop"); | 1180 assert(obj->is_oop(), "must be a valid oop"); |
1181 assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise"); | 1181 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); |
1182 instanceKlass::register_finalizer(instanceOop(obj), CHECK); | 1182 InstanceKlass::register_finalizer(instanceOop(obj), CHECK); |
1183 JRT_END | 1183 JRT_END |
1184 | 1184 |
1185 //----------------------------------------------------------------------------- | 1185 //----------------------------------------------------------------------------- |
1186 | 1186 |
1187 NamedCounter * volatile OptoRuntime::_named_counters = NULL; | 1187 NamedCounter * volatile OptoRuntime::_named_counters = NULL; |