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 "classfile/symbolTable.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "gc_implementation/shared/markSweep.inline.hpp" 30 #include "gc_interface/collectedHeap.inline.hpp" 31 #include "memory/genOopClosures.inline.hpp" 32 #include "memory/iterator.inline.hpp" 33 #include "memory/metadataFactory.hpp" 34 #include "memory/resourceArea.hpp" 35 #include "memory/specialized_oop_closures.hpp" 36 #include "memory/universe.inline.hpp" 37 #include "oops/instanceKlass.hpp" 38 #include "oops/klass.inline.hpp" 39 #include "oops/objArrayKlass.inline.hpp" 40 #include "oops/objArrayOop.inline.hpp" 41 #include "oops/oop.inline.hpp" 42 #include "oops/symbol.hpp" 43 #include "runtime/handles.inline.hpp" 44 #include "runtime/mutexLocker.hpp" 45 #include "runtime/orderAccess.inline.hpp" 46 #include "utilities/copy.hpp" 47 #include "utilities/macros.hpp" 48 #if INCLUDE_ALL_GCS 49 #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp" 50 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 51 #include "gc_implementation/g1/g1OopClosures.inline.hpp" 52 #include "gc_implementation/g1/g1RemSet.inline.hpp" 53 #include "gc_implementation/g1/heapRegionManager.inline.hpp" 54 #include "gc_implementation/parNew/parOopClosures.inline.hpp" 55 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp" 56 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 57 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 58 #endif // INCLUDE_ALL_GCS 59 60 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) { 61 assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), 62 "array klasses must be same size as InstanceKlass"); 63 64 int size = ArrayKlass::static_size(ObjArrayKlass::header_size()); 65 66 return new (loader_data, size, THREAD) ObjArrayKlass(n, klass_handle, name); 67 } 68 69 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data, 70 int n, KlassHandle element_klass, TRAPS) { 71 72 // Eagerly allocate the direct array supertype. 73 KlassHandle super_klass = KlassHandle(); 74 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) { 75 KlassHandle element_super (THREAD, element_klass->super()); 76 if (element_super.not_null()) { 77 // The element type has a direct super. E.g., String[] has direct super of Object[]. 78 super_klass = KlassHandle(THREAD, element_super->array_klass_or_null()); 392 Klass* elem_super = (Klass*) elem_supers->at(i); 393 Klass* array_super = elem_super->array_klass_or_null(); 394 assert(array_super != NULL, "must already have been created"); 395 secondaries->push(array_super); 396 } 397 return secondaries; 398 } 399 } 400 401 bool ObjArrayKlass::compute_is_subtype_of(Klass* k) { 402 if (!k->oop_is_objArray()) 403 return ArrayKlass::compute_is_subtype_of(k); 404 405 ObjArrayKlass* oak = ObjArrayKlass::cast(k); 406 return element_klass()->is_subtype_of(oak->element_klass()); 407 } 408 409 void ObjArrayKlass::initialize(TRAPS) { 410 bottom_klass()->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass 411 } 412 413 #define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \ 414 { \ 415 T* p = (T*)(a)->base(); \ 416 T* const end = p + (a)->length(); \ 417 while (p < end) { \ 418 do_oop; \ 419 p++; \ 420 } \ 421 } 422 423 #define ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(T, a, p, low, high, do_oop) \ 424 { \ 425 T* const l = (T*)(low); \ 426 T* const h = (T*)(high); \ 427 T* p = (T*)(a)->base(); \ 428 T* end = p + (a)->length(); \ 429 if (p < l) p = l; \ 430 if (end > h) end = h; \ 431 while (p < end) { \ 432 do_oop; \ 433 ++p; \ 434 } \ 435 } 436 437 #define ObjArrayKlass_OOP_ITERATE(a, p, do_oop) \ 438 if (UseCompressedOops) { \ 439 ObjArrayKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \ 440 a, p, do_oop) \ 441 } else { \ 442 ObjArrayKlass_SPECIALIZED_OOP_ITERATE(oop, \ 443 a, p, do_oop) \ 444 } 445 446 #define ObjArrayKlass_BOUNDED_OOP_ITERATE(a, p, low, high, do_oop) \ 447 if (UseCompressedOops) { \ 448 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \ 449 a, p, low, high, do_oop) \ 450 } else { \ 451 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ 452 a, p, low, high, do_oop) \ 453 } 454 455 void ObjArrayKlass::oop_follow_contents(oop obj) { 456 assert (obj->is_array(), "obj must be array"); 457 MarkSweep::follow_klass(obj->klass()); 458 if (UseCompressedOops) { 459 objarray_follow_contents<narrowOop>(obj, 0); 460 } else { 461 objarray_follow_contents<oop>(obj, 0); 462 } 463 } 464 465 #if INCLUDE_ALL_GCS 466 void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, 467 oop obj) { 468 assert(obj->is_array(), "obj must be array"); 469 PSParallelCompact::follow_klass(cm, obj->klass()); 470 if (UseCompressedOops) { 471 objarray_follow_contents<narrowOop>(cm, obj, 0); 472 } else { 473 objarray_follow_contents<oop>(cm, obj, 0); 474 } 475 } 476 #endif // INCLUDE_ALL_GCS 477 478 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ 479 \ 480 int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj, \ 481 OopClosureType* closure) { \ 482 assert (obj->is_array(), "obj must be array"); \ 483 objArrayOop a = objArrayOop(obj); \ 484 /* Get size before changing pointers. */ \ 485 /* Don't call size() or oop_size() since that is a virtual call. */ \ 486 int size = a->object_size(); \ 487 if_do_metadata_checked(closure, nv_suffix) { \ 488 closure->do_klass##nv_suffix(obj->klass()); \ 489 } \ 490 ObjArrayKlass_OOP_ITERATE(a, p, (closure)->do_oop##nv_suffix(p)) \ 491 return size; \ 492 } 493 494 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ 495 \ 496 int ObjArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \ 497 OopClosureType* closure, \ 498 MemRegion mr) { \ 499 assert(obj->is_array(), "obj must be array"); \ 500 objArrayOop a = objArrayOop(obj); \ 501 /* Get size before changing pointers. */ \ 502 /* Don't call size() or oop_size() since that is a virtual call */ \ 503 int size = a->object_size(); \ 504 if_do_metadata_checked(closure, nv_suffix) { \ 505 /* SSS: Do we need to pass down mr here? */ \ 506 closure->do_klass##nv_suffix(a->klass()); \ 507 } \ 508 ObjArrayKlass_BOUNDED_OOP_ITERATE( \ 509 a, p, mr.start(), mr.end(), (closure)->do_oop##nv_suffix(p)) \ 510 return size; \ 511 } 512 513 // Like oop_oop_iterate but only iterates over a specified range and only used 514 // for objArrayOops. 515 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix) \ 516 \ 517 int ObjArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj, \ 518 OopClosureType* closure, \ 519 int start, int end) { \ 520 assert(obj->is_array(), "obj must be array"); \ 521 objArrayOop a = objArrayOop(obj); \ 522 /* Get size before changing pointers. */ \ 523 /* Don't call size() or oop_size() since that is a virtual call */ \ 524 int size = a->object_size(); \ 525 if (UseCompressedOops) { \ 526 HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<narrowOop>(start);\ 527 /* this might be wierd if end needs to be aligned on HeapWord boundary */ \ 528 HeapWord* high = (HeapWord*)((narrowOop*)a->base() + end); \ 529 MemRegion mr(low, high); \ 530 if_do_metadata_checked(closure, nv_suffix) { \ 531 /* SSS: Do we need to pass down mr here? */ \ 532 closure->do_klass##nv_suffix(a->klass()); \ 533 } \ 534 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \ 535 a, p, low, high, (closure)->do_oop##nv_suffix(p)) \ 536 } else { \ 537 HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<oop>(start); \ 538 HeapWord* high = (HeapWord*)((oop*)a->base() + end); \ 539 MemRegion mr(low, high); \ 540 if_do_metadata_checked(closure, nv_suffix) { \ 541 /* SSS: Do we need to pass down mr here? */ \ 542 closure->do_klass##nv_suffix(a->klass()); \ 543 } \ 544 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ 545 a, p, low, high, (closure)->do_oop##nv_suffix(p)) \ 546 } \ 547 return size; \ 548 } 549 550 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN) 551 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN) 552 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) 553 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) 554 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) 555 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) 556 557 int ObjArrayKlass::oop_adjust_pointers(oop obj) { 558 assert(obj->is_objArray(), "obj must be obj array"); 559 objArrayOop a = objArrayOop(obj); 560 // Get size before changing pointers. 561 // Don't call size() or oop_size() since that is a virtual call. 562 int size = a->object_size(); 563 ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) 564 return size; 565 } 566 567 #if INCLUDE_ALL_GCS 568 void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 569 assert(obj->is_objArray(), "obj must be obj array"); 570 ObjArrayKlass_OOP_ITERATE( \ 571 objArrayOop(obj), p, \ 572 if (PSScavenge::should_scavenge(p)) { \ 573 pm->claim_or_forward_depth(p); \ 574 }) 575 } 576 577 int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 578 assert (obj->is_objArray(), "obj must be obj array"); 579 objArrayOop a = objArrayOop(obj); 580 int size = a->object_size(); 581 ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) 582 return size; 583 } 584 #endif // INCLUDE_ALL_GCS 585 586 // JVM support 587 588 jint ObjArrayKlass::compute_modifier_flags(TRAPS) const { 589 // The modifier for an objectArray is the same as its element 590 if (element_klass() == NULL) { 591 assert(Universe::is_bootstrapping(), "partial objArray only at startup"); 592 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; 593 } 594 // Return the flags of the bottom element type. 595 jint element_flags = bottom_klass()->compute_modifier_flags(CHECK_0); 596 597 return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) 598 | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); 599 } 600 601 602 // Printing 603 604 void ObjArrayKlass::print_on(outputStream* st) const { | 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 "classfile/symbolTable.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "gc_interface/collectedHeap.inline.hpp" 30 #include "memory/iterator.inline.hpp" 31 #include "memory/metadataFactory.hpp" 32 #include "memory/resourceArea.hpp" 33 #include "memory/specialized_oop_closures.hpp" 34 #include "memory/universe.inline.hpp" 35 #include "oops/instanceKlass.hpp" 36 #include "oops/klass.inline.hpp" 37 #include "oops/objArrayKlass.inline.hpp" 38 #include "oops/objArrayOop.inline.hpp" 39 #include "oops/oop.inline.hpp" 40 #include "oops/symbol.hpp" 41 #include "runtime/handles.inline.hpp" 42 #include "runtime/mutexLocker.hpp" 43 #include "runtime/orderAccess.inline.hpp" 44 #include "utilities/copy.hpp" 45 #include "utilities/macros.hpp" 46 47 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) { 48 assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), 49 "array klasses must be same size as InstanceKlass"); 50 51 int size = ArrayKlass::static_size(ObjArrayKlass::header_size()); 52 53 return new (loader_data, size, THREAD) ObjArrayKlass(n, klass_handle, name); 54 } 55 56 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data, 57 int n, KlassHandle element_klass, TRAPS) { 58 59 // Eagerly allocate the direct array supertype. 60 KlassHandle super_klass = KlassHandle(); 61 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) { 62 KlassHandle element_super (THREAD, element_klass->super()); 63 if (element_super.not_null()) { 64 // The element type has a direct super. E.g., String[] has direct super of Object[]. 65 super_klass = KlassHandle(THREAD, element_super->array_klass_or_null()); 379 Klass* elem_super = (Klass*) elem_supers->at(i); 380 Klass* array_super = elem_super->array_klass_or_null(); 381 assert(array_super != NULL, "must already have been created"); 382 secondaries->push(array_super); 383 } 384 return secondaries; 385 } 386 } 387 388 bool ObjArrayKlass::compute_is_subtype_of(Klass* k) { 389 if (!k->oop_is_objArray()) 390 return ArrayKlass::compute_is_subtype_of(k); 391 392 ObjArrayKlass* oak = ObjArrayKlass::cast(k); 393 return element_klass()->is_subtype_of(oak->element_klass()); 394 } 395 396 void ObjArrayKlass::initialize(TRAPS) { 397 bottom_klass()->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass 398 } 399 400 // JVM support 401 402 jint ObjArrayKlass::compute_modifier_flags(TRAPS) const { 403 // The modifier for an objectArray is the same as its element 404 if (element_klass() == NULL) { 405 assert(Universe::is_bootstrapping(), "partial objArray only at startup"); 406 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; 407 } 408 // Return the flags of the bottom element type. 409 jint element_flags = bottom_klass()->compute_modifier_flags(CHECK_0); 410 411 return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) 412 | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); 413 } 414 415 416 // Printing 417 418 void ObjArrayKlass::print_on(outputStream* st) const { |