0N/A/*
2099N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#include "precompiled.hpp"
1879N/A#include "classfile/javaClasses.hpp"
1879N/A#include "gc_implementation/shared/markSweep.inline.hpp"
1879N/A#include "oops/arrayKlassKlass.hpp"
1879N/A#include "oops/oop.inline.hpp"
1879N/A#include "runtime/handles.inline.hpp"
2223N/A#ifndef SERIALGC
2223N/A#include "gc_implementation/parNew/parOopClosures.inline.hpp"
2223N/A#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
2223N/A#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
2223N/A#include "memory/cardTableRS.hpp"
2223N/A#include "oops/oop.pcgc.inline.hpp"
2223N/A#endif
0N/A
0N/A
0N/AklassOop arrayKlassKlass::create_klass(TRAPS) {
0N/A arrayKlassKlass o;
0N/A KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
0N/A KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
0N/A // Make sure size calculation is right
0N/A assert(k()->size() == align_object_size(header_size()), "wrong size for object");
0N/A java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror, make links
0N/A return k();
0N/A}
0N/A
0N/Abool arrayKlassKlass::oop_is_parsable(oop obj) const {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A return (!ak->null_vtbl()) && ak->object_is_parsable();
0N/A}
0N/A
0N/Avoid arrayKlassKlass::oop_follow_contents(oop obj) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A MarkSweep::mark_and_push(ak->adr_component_mirror());
0N/A MarkSweep::mark_and_push(ak->adr_lower_dimension());
0N/A MarkSweep::mark_and_push(ak->adr_higher_dimension());
0N/A {
0N/A HandleMark hm;
0N/A ak->vtable()->oop_follow_contents();
0N/A }
0N/A klassKlass::oop_follow_contents(obj);
0N/A}
0N/A
0N/A#ifndef SERIALGC
0N/Avoid arrayKlassKlass::oop_follow_contents(ParCompactionManager* cm,
0N/A oop obj) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A PSParallelCompact::mark_and_push(cm, ak->adr_component_mirror());
0N/A PSParallelCompact::mark_and_push(cm, ak->adr_lower_dimension());
0N/A PSParallelCompact::mark_and_push(cm, ak->adr_higher_dimension());
0N/A {
0N/A HandleMark hm;
0N/A ak->vtable()->oop_follow_contents(cm);
0N/A }
0N/A klassKlass::oop_follow_contents(cm, obj);
0N/A}
0N/A#endif // SERIALGC
0N/A
0N/A
0N/Aint arrayKlassKlass::oop_adjust_pointers(oop obj) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A MarkSweep::adjust_pointer(ak->adr_component_mirror());
0N/A MarkSweep::adjust_pointer(ak->adr_lower_dimension());
0N/A MarkSweep::adjust_pointer(ak->adr_higher_dimension());
0N/A {
0N/A HandleMark hm;
0N/A ak->vtable()->oop_adjust_pointers();
0N/A }
0N/A return klassKlass::oop_adjust_pointers(obj);
0N/A}
0N/A
0N/A
0N/Aint arrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A blk->do_oop(ak->adr_component_mirror());
0N/A blk->do_oop(ak->adr_lower_dimension());
0N/A blk->do_oop(ak->adr_higher_dimension());
0N/A ak->vtable()->oop_oop_iterate(blk);
0N/A return klassKlass::oop_oop_iterate(obj, blk);
0N/A}
0N/A
0N/A
0N/Aint arrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
2223N/A oop* addr = ak->adr_component_mirror();
2223N/A if (mr.contains(addr)) blk->do_oop(addr);
2223N/A addr = ak->adr_lower_dimension();
2223N/A if (mr.contains(addr)) blk->do_oop(addr);
2223N/A addr = ak->adr_higher_dimension();
2223N/A if (mr.contains(addr)) blk->do_oop(addr);
0N/A ak->vtable()->oop_oop_iterate_m(blk, mr);
0N/A return klassKlass::oop_oop_iterate_m(obj, blk, mr);
0N/A}
0N/A
0N/A#ifndef SERIALGC
0N/Avoid arrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
0N/A assert(obj->blueprint()->oop_is_arrayKlass(),"must be an array klass");
2223N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
2223N/A oop* p = ak->adr_component_mirror();
2223N/A if (PSScavenge::should_scavenge(p)) {
2223N/A pm->claim_or_forward_depth(p);
2223N/A }
2223N/A klassKlass::oop_push_contents(pm, obj);
0N/A}
0N/A
0N/Aint arrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A PSParallelCompact::adjust_pointer(ak->adr_component_mirror());
0N/A PSParallelCompact::adjust_pointer(ak->adr_lower_dimension());
0N/A PSParallelCompact::adjust_pointer(ak->adr_higher_dimension());
0N/A {
0N/A HandleMark hm;
0N/A ak->vtable()->oop_update_pointers(cm);
0N/A }
0N/A return klassKlass::oop_update_pointers(cm, obj);
0N/A}
0N/A#endif // SERIALGC
0N/A
0N/A// Printing
0N/A
0N/Avoid arrayKlassKlass::oop_print_on(oop obj, outputStream* st) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A klassKlass::oop_print_on(obj, st);
0N/A}
0N/A
0N/Avoid arrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) {
0N/A assert(obj->is_klass(), "must be klass");
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A for(int index = 0; index < ak->dimension(); index++) {
0N/A st->print("[]");
0N/A }
0N/A}
0N/A
0N/A
0N/Aconst char* arrayKlassKlass::internal_name() const {
0N/A return "{array class}";
0N/A}
0N/A
0N/Avoid arrayKlassKlass::oop_verify_on(oop obj, outputStream* st) {
0N/A klassKlass::oop_verify_on(obj, st);
0N/A
0N/A arrayKlass* ak = arrayKlass::cast(klassOop(obj));
0N/A if (!obj->partially_loaded()) {
0N/A if (ak->component_mirror() != NULL)
0N/A guarantee(ak->component_mirror()->klass(), "should have a class");
0N/A if (ak->lower_dimension() != NULL)
0N/A guarantee(ak->lower_dimension()->klass(), "should have a class");
0N/A if (ak->higher_dimension() != NULL)
0N/A guarantee(ak->higher_dimension()->klass(), "should have a class");
0N/A }
0N/A}