objArrayKlass.cpp 28.4 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25
#include "precompiled.hpp"
26
#include "classfile/symbolTable.hpp"
27 28 29 30 31
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genOopClosures.inline.hpp"
32
#include "memory/metadataFactory.hpp"
33 34 35
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
36
#include "oops/klass.inline.hpp"
37 38 39 40 41
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayKlass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
42
#include "oops/symbol.hpp"
43 44 45
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/copy.hpp"
46 47
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
48
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
49 50 51 52 53 54 55 56 57
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
58
#endif // INCLUDE_ALL_GCS
D
duke 已提交
59

60 61
ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) {
  assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
62 63
      "array klasses must be same size as InstanceKlass");

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 71 72 73 74 75 76 77 78 79 80 81 82 83 84
                                                int n, KlassHandle element_klass, TRAPS) {

  // Eagerly allocate the direct array supertype.
  KlassHandle super_klass = KlassHandle();
  if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
    KlassHandle element_super (THREAD, element_klass->super());
    if (element_super.not_null()) {
      // The element type has a direct super.  E.g., String[] has direct super of Object[].
      super_klass = KlassHandle(THREAD, element_super->array_klass_or_null());
      bool supers_exist = super_klass.not_null();
      // Also, see if the element has secondary supertypes.
      // We need an array type for each.
      Array<Klass*>* element_supers = element_klass->secondary_supers();
      for( int i = element_supers->length()-1; i >= 0; i-- ) {
        Klass* elem_super = element_supers->at(i);
H
hseigel 已提交
85
        if (elem_super->array_klass_or_null() == NULL) {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
          supers_exist = false;
          break;
        }
      }
      if (!supers_exist) {
        // Oops.  Not allocated yet.  Back out, allocate it, and retry.
        KlassHandle ek;
        {
          MutexUnlocker mu(MultiArray_lock);
          MutexUnlocker mc(Compile_lock);   // for vtables
          Klass* sk = element_super->array_klass(CHECK_0);
          super_klass = KlassHandle(THREAD, sk);
          for( int i = element_supers->length()-1; i >= 0; i-- ) {
            KlassHandle elem_super (THREAD, element_supers->at(i));
            elem_super->array_klass(CHECK_0);
          }
          // Now retry from the beginning
          Klass* klass_oop = element_klass->array_klass(n, CHECK_0);
          // Create a handle because the enclosing brace, when locking
          // can cause a gc.  Better to have this function return a Handle.
          ek = KlassHandle(THREAD, klass_oop);
        }  // re-lock
        return ek();
      }
    } else {
      // The element type is already Object.  Object[] has direct super of Object.
      super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass());
    }
  }

  // Create type name for klass.
  Symbol* name = NULL;
  if (!element_klass->oop_is_instance() ||
      (name = InstanceKlass::cast(element_klass())->array_name()) == NULL) {

    ResourceMark rm(THREAD);
    char *name_str = element_klass->name()->as_C_string();
    int len = element_klass->name()->utf8_length();
    char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
    int idx = 0;
    new_str[idx++] = '[';
    if (element_klass->oop_is_instance()) { // it could be an array or simple type
      new_str[idx++] = 'L';
    }
    memcpy(&new_str[idx], name_str, len * sizeof(char));
    idx += len;
    if (element_klass->oop_is_instance()) {
      new_str[idx++] = ';';
    }
    new_str[idx++] = '\0';
    name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
    if (element_klass->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(element_klass());
      ik->set_array_name(name);
    }
  }

  // Initialize instance variables
144
  ObjArrayKlass* oak = ObjArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_0);
145 146 147 148 149 150 151

  // Add all classes to our internal class loader list here,
  // including classes in the bootstrap (NULL) class loader.
  // GC walks these as strong roots.
  loader_data->add_class(oak);

  // Call complete_create_array_klass after all instance variables has been initialized.
152
  ArrayKlass::complete_create_array_klass(oak, super_klass, CHECK_0);
153 154 155 156

  return oak;
}

157
ObjArrayKlass::ObjArrayKlass(int n, KlassHandle element_klass, Symbol* name) : ArrayKlass(name) {
158 159 160 161 162 163 164 165 166
  this->set_dimension(n);
  this->set_element_klass(element_klass());
  // decrement refcount because object arrays are not explicitly freed.  The
  // InstanceKlass array_name() keeps the name counted while the klass is
  // loaded.
  name->decrement_refcount();

  Klass* bk;
  if (element_klass->oop_is_objArray()) {
167
    bk = ObjArrayKlass::cast(element_klass())->bottom_klass();
168 169 170
  } else {
    bk = element_klass();
  }
H
hseigel 已提交
171
  assert(bk != NULL && (bk->oop_is_instance() || bk->oop_is_typeArray()), "invalid bottom klass");
172 173 174 175 176 177 178 179
  this->set_bottom_klass(bk);
  this->set_class_loader_data(bk->class_loader_data());

  this->set_layout_helper(array_layout_helper(T_OBJECT));
  assert(this->oop_is_array(), "sanity");
  assert(this->oop_is_objArray(), "sanity");
}

180
int ObjArrayKlass::oop_size(oop obj) const {
D
duke 已提交
181 182 183 184
  assert(obj->is_objArray(), "must be object array");
  return objArrayOop(obj)->object_size();
}

185
objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
D
duke 已提交
186 187 188
  if (length >= 0) {
    if (length <= arrayOopDesc::max_array_length(T_OBJECT)) {
      int size = objArrayOopDesc::object_size(length);
189 190
      KlassHandle h_k(THREAD, this);
      return (objArrayOop)CollectedHeap::array_allocate(h_k, size, length, CHECK_NULL);
D
duke 已提交
191
    } else {
192
      report_java_out_of_memory("Requested array size exceeds VM limit");
193
      JvmtiExport::post_array_size_exhausted();
D
duke 已提交
194 195 196 197 198 199 200 201 202
      THROW_OOP_0(Universe::out_of_memory_error_array_size());
    }
  } else {
    THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
  }
}

static int multi_alloc_counter = 0;

203
oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
D
duke 已提交
204 205 206 207 208 209 210 211 212 213
  int length = *sizes;
  // Call to lower_dimension uses this pointer, so most be called before a
  // possible GC
  KlassHandle h_lower_dimension(THREAD, lower_dimension());
  // If length < 0 allocate will throw an exception.
  objArrayOop array = allocate(length, CHECK_NULL);
  objArrayHandle h_array (THREAD, array);
  if (rank > 1) {
    if (length != 0) {
      for (int index = 0; index < length; index++) {
214
        ArrayKlass* ak = ArrayKlass::cast(h_lower_dimension());
D
duke 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
        oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
        h_array->obj_at_put(index, sub_array);
      }
    } else {
      // Since this array dimension has zero length, nothing will be
      // allocated, however the lower dimension values must be checked
      // for illegal values.
      for (int i = 0; i < rank - 1; ++i) {
        sizes += 1;
        if (*sizes < 0) {
          THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
        }
      }
    }
  }
  return h_array();
}

233
// Either oop or narrowOop depending on UseCompressedOops.
234
template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
235
                               arrayOop d, T* dst, int length, TRAPS) {
D
duke 已提交
236 237

  BarrierSet* bs = Universe::heap()->barrier_set();
238 239 240
  // For performance reasons, we assume we are that the write barrier we
  // are using has optimized modes for arrays of references.  At least one
  // of the asserts below will fail if this is not the case.
D
duke 已提交
241
  assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
242
  assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
D
duke 已提交
243 244 245 246

  if (s == d) {
    // since source and destination are equal we do not need conversion checks.
    assert(length > 0, "sanity check");
247
    bs->write_ref_array_pre(dst, length);
D
duke 已提交
248 249 250
    Copy::conjoint_oops_atomic(src, dst, length);
  } else {
    // We have to make sure all elements conform to the destination array
251 252
    Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
    Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
H
hseigel 已提交
253
    if (stype == bound || stype->is_subtype_of(bound)) {
D
duke 已提交
254
      // elements are guaranteed to be subtypes, so no check necessary
255
      bs->write_ref_array_pre(dst, length);
D
duke 已提交
256 257 258 259
      Copy::conjoint_oops_atomic(src, dst, length);
    } else {
      // slow case: need individual subtype checks
      // note: don't use obj_at_put below because it includes a redundant store check
260 261 262 263 264
      T* from = src;
      T* end = from + length;
      for (T* p = dst; from < end; from++, p++) {
        // XXX this is going to be slow.
        T element = *from;
265 266 267 268 269
        // even slower now
        bool element_is_null = oopDesc::is_null(element);
        oop new_val = element_is_null ? oop(NULL)
                                      : oopDesc::decode_heap_oop_not_null(element);
        if (element_is_null ||
H
hseigel 已提交
270
            (new_val->klass())->is_subtype_of(bound)) {
271
          bs->write_ref_field_pre(p, new_val);
272
          *p = *from;
D
duke 已提交
273 274
        } else {
          // We must do a barrier to cover the partial copy.
275 276 277 278
          const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize);
          // pointer delta is scaled to number of elements (length field in
          // objArrayOop) which we assume is 32 bit.
          assert(pd == (size_t)(int)pd, "length field overflow");
279
          bs->write_ref_array((HeapWord*)dst, pd);
D
duke 已提交
280 281 282 283 284 285
          THROW(vmSymbols::java_lang_ArrayStoreException());
          return;
        }
      }
    }
  }
286
  bs->write_ref_array((HeapWord*)dst, length);
D
duke 已提交
287 288
}

289
void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
                               int dst_pos, int length, TRAPS) {
  assert(s->is_objArray(), "must be obj array");

  if (!d->is_objArray()) {
    THROW(vmSymbols::java_lang_ArrayStoreException());
  }

  // Check is all offsets and lengths are non negative
  if (src_pos < 0 || dst_pos < 0 || length < 0) {
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
  }
  // Check if the ranges are valid
  if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
     || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
  }

  // Special case. Boundary cases must be checked first
  // This allows the following call: copy_array(s, s.length(), d.length(), 0).
  // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
  // points to the right of the last element.
  if (length==0) {
    return;
  }
  if (UseCompressedOops) {
    narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos);
    narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos);
    do_copy<narrowOop>(s, src, d, dst, length, CHECK);
  } else {
    oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos);
    oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos);
    do_copy<oop> (s, src, d, dst, length, CHECK);
  }
}

D
duke 已提交
325

326
Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
D
duke 已提交
327

328 329 330
  assert(dimension() <= n, "check order of chain");
  int dim = dimension();
  if (dim == n) return this;
D
duke 已提交
331

332
  if (higher_dimension() == NULL) {
D
duke 已提交
333 334 335 336 337 338 339 340 341 342
    if (or_null)  return NULL;

    ResourceMark rm;
    JavaThread *jt = (JavaThread *)THREAD;
    {
      MutexLocker mc(Compile_lock, THREAD);   // for vtables
      // Ensure atomic creation of higher dimensions
      MutexLocker mu(MultiArray_lock, THREAD);

      // Check if another thread beat us
343
      if (higher_dimension() == NULL) {
D
duke 已提交
344 345

        // Create multi-dim klass object and link them together
346
        Klass* k =
347 348
          ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL);
        ObjArrayKlass* ak = ObjArrayKlass::cast(k);
349
        ak->set_lower_dimension(this);
350
        OrderAccess::storestore();
351
        set_higher_dimension(ak);
352
        assert(ak->oop_is_objArray(), "incorrect initialization of ObjArrayKlass");
D
duke 已提交
353 354 355 356 357 358
      }
    }
  } else {
    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  }

359
  ObjArrayKlass *ak = ObjArrayKlass::cast(higher_dimension());
D
duke 已提交
360 361 362 363 364 365
  if (or_null) {
    return ak->array_klass_or_null(n);
  }
  return ak->array_klass(n, CHECK_NULL);
}

366
Klass* ObjArrayKlass::array_klass_impl(bool or_null, TRAPS) {
D
duke 已提交
367 368 369
  return array_klass_impl(or_null, dimension() +  1, CHECK_NULL);
}

370
bool ObjArrayKlass::can_be_primary_super_slow() const {
371
  if (!bottom_klass()->can_be_primary_super())
D
duke 已提交
372 373 374 375 376 377
    // array of interfaces
    return false;
  else
    return Klass::can_be_primary_super_slow();
}

378
GrowableArray<Klass*>* ObjArrayKlass::compute_secondary_supers(int num_extra_slots) {
D
duke 已提交
379
  // interfaces = { cloneable_klass, serializable_klass, elemSuper[], ... };
H
hseigel 已提交
380
  Array<Klass*>* elem_supers = element_klass()->secondary_supers();
381
  int num_elem_supers = elem_supers == NULL ? 0 : elem_supers->length();
D
duke 已提交
382 383 384
  int num_secondaries = num_extra_slots + 2 + num_elem_supers;
  if (num_secondaries == 2) {
    // Must share this for correct bootstrapping!
385 386
    set_secondary_supers(Universe::the_array_interfaces_array());
    return NULL;
D
duke 已提交
387
  } else {
388 389 390
    GrowableArray<Klass*>* secondaries = new GrowableArray<Klass*>(num_elem_supers+2);
    secondaries->push(SystemDictionary::Cloneable_klass());
    secondaries->push(SystemDictionary::Serializable_klass());
D
duke 已提交
391
    for (int i = 0; i < num_elem_supers; i++) {
392 393
      Klass* elem_super = (Klass*) elem_supers->at(i);
      Klass* array_super = elem_super->array_klass_or_null();
D
duke 已提交
394
      assert(array_super != NULL, "must already have been created");
395
      secondaries->push(array_super);
D
duke 已提交
396
    }
397
    return secondaries;
D
duke 已提交
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);
D
duke 已提交
404

405
  ObjArrayKlass* oak = ObjArrayKlass::cast(k);
406
  return element_klass()->is_subtype_of(oak->element_klass());
D
duke 已提交
407 408
}

409
void ObjArrayKlass::initialize(TRAPS) {
H
hseigel 已提交
410
  bottom_klass()->initialize(THREAD);  // dispatches to either InstanceKlass or TypeArrayKlass
D
duke 已提交
411 412
}

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
#define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \
{                                   \
  T* p         = (T*)(a)->base();   \
  T* const end = p + (a)->length(); \
  while (p < end) {                 \
    do_oop;                         \
    p++;                            \
  }                                 \
}

#define ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(T, a, p, low, high, do_oop) \
{                                   \
  T* const l = (T*)(low);           \
  T* const h = (T*)(high);          \
  T* p       = (T*)(a)->base();     \
  T* end     = p + (a)->length();   \
  if (p < l) p = l;                 \
  if (end > h) end = h;             \
  while (p < end) {                 \
    do_oop;                         \
    ++p;                            \
  }                                 \
}

#define ObjArrayKlass_OOP_ITERATE(a, p, do_oop)      \
  if (UseCompressedOops) {                           \
    ObjArrayKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
      a, p, do_oop)                                  \
  } else {                                           \
    ObjArrayKlass_SPECIALIZED_OOP_ITERATE(oop,       \
      a, p, do_oop)                                  \
  }

#define ObjArrayKlass_BOUNDED_OOP_ITERATE(a, p, low, high, do_oop) \
  if (UseCompressedOops) {                                   \
    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
      a, p, low, high, do_oop)                               \
  } else {                                                   \
    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,       \
      a, p, low, high, do_oop)                               \
  }
D
duke 已提交
454

455
void ObjArrayKlass::oop_follow_contents(oop obj) {
D
duke 已提交
456
  assert (obj->is_array(), "obj must be array");
457
  MarkSweep::follow_klass(obj->klass());
458 459 460 461 462
  if (UseCompressedOops) {
    objarray_follow_contents<narrowOop>(obj, 0);
  } else {
    objarray_follow_contents<oop>(obj, 0);
  }
D
duke 已提交
463 464
}

465
#if INCLUDE_ALL_GCS
466
void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm,
D
duke 已提交
467
                                        oop obj) {
468
  assert(obj->is_array(), "obj must be array");
469
  PSParallelCompact::follow_klass(cm, obj->klass());
470 471 472 473 474
  if (UseCompressedOops) {
    objarray_follow_contents<narrowOop>(cm, obj, 0);
  } else {
    objarray_follow_contents<oop>(cm, obj, 0);
  }
D
duke 已提交
475
}
476
#endif // INCLUDE_ALL_GCS
D
duke 已提交
477

478 479 480 481 482 483
#define if_do_metadata_checked(closure, nv_suffix)                    \
  /* Make sure the non-virtual and the virtual versions match. */     \
  assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
      "Inconsistency in do_metadata");                                \
  if (closure->do_metadata##nv_suffix())

D
duke 已提交
484 485
#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
                                                                                \
486
int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj,                          \
D
duke 已提交
487 488 489 490 491 492 493
                                              OopClosureType* closure) {        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \
  assert (obj->is_array(), "obj must be array");                                \
  objArrayOop a = objArrayOop(obj);                                             \
  /* Get size before changing pointers. */                                      \
  /* Don't call size() or oop_size() since that is a virtual call. */           \
  int size = a->object_size();                                                  \
494 495
  if_do_metadata_checked(closure, nv_suffix) {                                  \
    closure->do_klass##nv_suffix(obj->klass());                                 \
D
duke 已提交
496
  }                                                                             \
497
  ObjArrayKlass_OOP_ITERATE(a, p, (closure)->do_oop##nv_suffix(p))              \
D
duke 已提交
498 499 500 501 502
  return size;                                                                  \
}

#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
                                                                                \
503
int ObjArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj,                      \
D
duke 已提交
504 505 506 507 508 509 510 511
                                                  OopClosureType* closure,      \
                                                  MemRegion mr) {               \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \
  assert(obj->is_array(), "obj must be array");                                 \
  objArrayOop a  = objArrayOop(obj);                                            \
  /* Get size before changing pointers. */                                      \
  /* Don't call size() or oop_size() since that is a virtual call */            \
  int size = a->object_size();                                                  \
512 513 514
  if_do_metadata_checked(closure, nv_suffix) {                                  \
    /* SSS: Do we need to pass down mr here? */                                 \
    closure->do_klass##nv_suffix(a->klass());                                   \
D
duke 已提交
515
  }                                                                             \
516 517 518 519 520 521 522 523 524
  ObjArrayKlass_BOUNDED_OOP_ITERATE(                                            \
    a, p, mr.start(), mr.end(), (closure)->do_oop##nv_suffix(p))                \
  return size;                                                                  \
}

// Like oop_oop_iterate but only iterates over a specified range and only used
// for objArrayOops.
#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix)         \
                                                                                \
525
int ObjArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj,                    \
526 527 528 529 530 531 532 533 534 535 536 537 538
                                                  OopClosureType* closure,      \
                                                  int start, int end) {         \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \
  assert(obj->is_array(), "obj must be array");                                 \
  objArrayOop a  = objArrayOop(obj);                                            \
  /* Get size before changing pointers. */                                      \
  /* Don't call size() or oop_size() since that is a virtual call */            \
  int size = a->object_size();                                                  \
  if (UseCompressedOops) {                                                      \
    HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<narrowOop>(start);\
    /* this might be wierd if end needs to be aligned on HeapWord boundary */   \
    HeapWord* high = (HeapWord*)((narrowOop*)a->base() + end);                  \
    MemRegion mr(low, high);                                                    \
539 540 541
    if_do_metadata_checked(closure, nv_suffix) {                                \
      /* SSS: Do we need to pass down mr here? */                               \
      closure->do_klass##nv_suffix(a->klass());                                 \
D
duke 已提交
542
    }                                                                           \
543 544
    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,                    \
      a, p, low, high, (closure)->do_oop##nv_suffix(p))                         \
D
duke 已提交
545
  } else {                                                                      \
546 547 548
    HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<oop>(start);  \
    HeapWord* high = (HeapWord*)((oop*)a->base() + end);                        \
    MemRegion mr(low, high);                                                    \
549 550 551
    if_do_metadata_checked(closure, nv_suffix) {                                \
      /* SSS: Do we need to pass down mr here? */                               \
      closure->do_klass##nv_suffix(a->klass());                                 \
D
duke 已提交
552
    }                                                                           \
553 554
    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,                          \
      a, p, low, high, (closure)->do_oop##nv_suffix(p))                         \
D
duke 已提交
555 556 557 558 559
  }                                                                             \
  return size;                                                                  \
}

ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN)
560
ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN)
D
duke 已提交
561
ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m)
562
ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m)
563
ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r)
564
ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r)
D
duke 已提交
565

566
int ObjArrayKlass::oop_adjust_pointers(oop obj) {
D
duke 已提交
567 568 569 570 571
  assert(obj->is_objArray(), "obj must be obj array");
  objArrayOop a = objArrayOop(obj);
  // Get size before changing pointers.
  // Don't call size() or oop_size() since that is a virtual call.
  int size = a->object_size();
572
  MarkSweep::adjust_klass(a->klass());
573
  ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p))
D
duke 已提交
574 575 576
  return size;
}

577
#if INCLUDE_ALL_GCS
578
void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
D
duke 已提交
579
  assert(obj->is_objArray(), "obj must be obj array");
580 581 582 583 584
  ObjArrayKlass_OOP_ITERATE( \
    objArrayOop(obj), p, \
    if (PSScavenge::should_scavenge(p)) { \
      pm->claim_or_forward_depth(p); \
    })
D
duke 已提交
585 586
}

587
int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
D
duke 已提交
588 589
  assert (obj->is_objArray(), "obj must be obj array");
  objArrayOop a = objArrayOop(obj);
590 591
  int size = a->object_size();
  a->update_header(cm);
592
  ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p))
593
  return size;
D
duke 已提交
594
}
595
#endif // INCLUDE_ALL_GCS
D
duke 已提交
596 597 598

// JVM support

599
jint ObjArrayKlass::compute_modifier_flags(TRAPS) const {
D
duke 已提交
600 601 602 603 604
  // The modifier for an objectArray is the same as its element
  if (element_klass() == NULL) {
    assert(Universe::is_bootstrapping(), "partial objArray only at startup");
    return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
  }
605
  // Return the flags of the bottom element type.
H
hseigel 已提交
606
  jint element_flags = bottom_klass()->compute_modifier_flags(CHECK_0);
D
duke 已提交
607 608 609 610 611 612 613 614

  return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED))
                        | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL);
}


// Printing

615
void ObjArrayKlass::print_on(outputStream* st) const {
616 617 618 619 620 621 622 623
#ifndef PRODUCT
  Klass::print_on(st);
  st->print(" - instance klass: ");
  element_klass()->print_value_on(st);
  st->cr();
#endif //PRODUCT
}

624
void ObjArrayKlass::print_value_on(outputStream* st) const {
625 626 627 628 629 630 631 632
  assert(is_klass(), "must be klass");

  element_klass()->print_value_on(st);
  st->print("[]");
}

#ifndef PRODUCT

633 634
void ObjArrayKlass::oop_print_on(oop obj, outputStream* st) {
  ArrayKlass::oop_print_on(obj, st);
D
duke 已提交
635 636 637 638 639 640 641 642 643 644
  assert(obj->is_objArray(), "must be objArray");
  objArrayOop oa = objArrayOop(obj);
  int print_len = MIN2((intx) oa->length(), MaxElementPrintSize);
  for(int index = 0; index < print_len; index++) {
    st->print(" - %3d : ", index);
    oa->obj_at(index)->print_value_on(st);
    st->cr();
  }
  int remaining = oa->length() - print_len;
  if (remaining > 0) {
645
    st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
D
duke 已提交
646 647 648
  }
}

649 650
#endif //PRODUCT

651
static int max_objArray_print_length = 4;
D
duke 已提交
652

653
void ObjArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
D
duke 已提交
654
  assert(obj->is_objArray(), "must be objArray");
655
  st->print("a ");
D
duke 已提交
656
  element_klass()->print_value_on(st);
657 658 659
  int len = objArrayOop(obj)->length();
  st->print("[%d] ", len);
  obj->print_address_on(st);
660
  if (NOT_PRODUCT(PrintOopAddress ||) PrintMiscellaneous && (WizardMode || Verbose)) {
661 662 663 664 665 666 667 668 669
    st->print("{");
    for (int i = 0; i < len; i++) {
      if (i > max_objArray_print_length) {
        st->print("..."); break;
      }
      st->print(" "INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
    }
    st->print(" }");
  }
D
duke 已提交
670 671
}

672
const char* ObjArrayKlass::internal_name() const {
D
duke 已提交
673 674 675
  return external_name();
}

676

D
duke 已提交
677 678
// Verification

679 680
void ObjArrayKlass::verify_on(outputStream* st, bool check_dictionary) {
  ArrayKlass::verify_on(st, check_dictionary);
681 682
  guarantee(element_klass()->is_klass(), "should be klass");
  guarantee(bottom_klass()->is_klass(), "should be klass");
H
hseigel 已提交
683
  Klass* bk = bottom_klass();
684 685 686
  guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(),  "invalid bottom klass");
}

687 688
void ObjArrayKlass::oop_verify_on(oop obj, outputStream* st) {
  ArrayKlass::oop_verify_on(obj, st);
D
duke 已提交
689 690 691 692 693 694
  guarantee(obj->is_objArray(), "must be objArray");
  objArrayOop oa = objArrayOop(obj);
  for(int index = 0; index < oa->length(); index++) {
    guarantee(oa->obj_at(index)->is_oop_or_null(), "should be oop");
  }
}