< prev index next >

src/share/vm/oops/objArrayKlass.cpp

Print this page




   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 {


< prev index next >