Path: blob/master/src/hotspot/share/gc/serial/markSweep.cpp
41152 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "compiler/compileBroker.hpp"26#include "gc/serial/markSweep.inline.hpp"27#include "gc/shared/collectedHeap.inline.hpp"28#include "gc/shared/gcTimer.hpp"29#include "gc/shared/gcTrace.hpp"30#include "gc/shared/gc_globals.hpp"31#include "memory/iterator.inline.hpp"32#include "memory/universe.hpp"33#include "oops/access.inline.hpp"34#include "oops/compressedOops.inline.hpp"35#include "oops/instanceClassLoaderKlass.inline.hpp"36#include "oops/instanceKlass.inline.hpp"37#include "oops/instanceMirrorKlass.inline.hpp"38#include "oops/instanceRefKlass.inline.hpp"39#include "oops/methodData.hpp"40#include "oops/objArrayKlass.inline.hpp"41#include "oops/oop.inline.hpp"42#include "oops/typeArrayOop.inline.hpp"43#include "utilities/macros.hpp"44#include "utilities/stack.inline.hpp"4546uint MarkSweep::_total_invocations = 0;4748Stack<oop, mtGC> MarkSweep::_marking_stack;49Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack;5051Stack<oop, mtGC> MarkSweep::_preserved_oop_stack;52Stack<markWord, mtGC> MarkSweep::_preserved_mark_stack;53size_t MarkSweep::_preserved_count = 0;54size_t MarkSweep::_preserved_count_max = 0;55PreservedMark* MarkSweep::_preserved_marks = NULL;56ReferenceProcessor* MarkSweep::_ref_processor = NULL;57STWGCTimer* MarkSweep::_gc_timer = NULL;58SerialOldTracer* MarkSweep::_gc_tracer = NULL;5960MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;6162MarkAndPushClosure MarkSweep::mark_and_push_closure;63CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong);64CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure, ClassLoaderData::_claim_strong);6566template <class T> inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) {67mark_and_push(p);68}6970void MarkSweep::push_objarray(oop obj, size_t index) {71ObjArrayTask task(obj, index);72assert(task.is_valid(), "bad ObjArrayTask");73_objarray_stack.push(task);74}7576inline void MarkSweep::follow_array(objArrayOop array) {77MarkSweep::follow_klass(array->klass());78// Don't push empty arrays to avoid unnecessary work.79if (array->length() > 0) {80MarkSweep::push_objarray(array, 0);81}82}8384inline void MarkSweep::follow_object(oop obj) {85assert(obj->is_gc_marked(), "should be marked");86if (obj->is_objArray()) {87// Handle object arrays explicitly to allow them to88// be split into chunks if needed.89MarkSweep::follow_array((objArrayOop)obj);90} else {91obj->oop_iterate(&mark_and_push_closure);92}93}9495void MarkSweep::follow_array_chunk(objArrayOop array, int index) {96const int len = array->length();97const int beg_index = index;98assert(beg_index < len || len == 0, "index too large");99100const int stride = MIN2(len - beg_index, (int) ObjArrayMarkingStride);101const int end_index = beg_index + stride;102103array->oop_iterate_range(&mark_and_push_closure, beg_index, end_index);104105if (end_index < len) {106MarkSweep::push_objarray(array, end_index); // Push the continuation.107}108}109110void MarkSweep::follow_stack() {111do {112while (!_marking_stack.is_empty()) {113oop obj = _marking_stack.pop();114assert (obj->is_gc_marked(), "p must be marked");115follow_object(obj);116}117// Process ObjArrays one at a time to avoid marking stack bloat.118if (!_objarray_stack.is_empty()) {119ObjArrayTask task = _objarray_stack.pop();120follow_array_chunk(objArrayOop(task.obj()), task.index());121}122} while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());123}124125MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;126127void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }128129template <class T> inline void MarkSweep::follow_root(T* p) {130assert(!Universe::heap()->is_in(p),131"roots shouldn't be things within the heap");132T heap_oop = RawAccess<>::oop_load(p);133if (!CompressedOops::is_null(heap_oop)) {134oop obj = CompressedOops::decode_not_null(heap_oop);135if (!obj->mark().is_marked()) {136mark_object(obj);137follow_object(obj);138}139}140follow_stack();141}142143void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }144void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }145146void PreservedMark::adjust_pointer() {147MarkSweep::adjust_pointer(&_obj);148}149150void PreservedMark::restore() {151_obj->set_mark(_mark);152}153154// We preserve the mark which should be replaced at the end and the location155// that it will go. Note that the object that this markWord belongs to isn't156// currently at that address but it will be after phase4157void MarkSweep::preserve_mark(oop obj, markWord mark) {158// We try to store preserved marks in the to space of the new generation since159// this is storage which should be available. Most of the time this should be160// sufficient space for the marks we need to preserve but if it isn't we fall161// back to using Stacks to keep track of the overflow.162if (_preserved_count < _preserved_count_max) {163_preserved_marks[_preserved_count++].init(obj, mark);164} else {165_preserved_mark_stack.push(mark);166_preserved_oop_stack.push(obj);167}168}169170void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {171_ref_processor = rp;172mark_and_push_closure.set_ref_discoverer(_ref_processor);173}174175AdjustPointerClosure MarkSweep::adjust_pointer_closure;176177void MarkSweep::adjust_marks() {178assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),179"inconsistent preserved oop stacks");180181// adjust the oops we saved earlier182for (size_t i = 0; i < _preserved_count; i++) {183_preserved_marks[i].adjust_pointer();184}185186// deal with the overflow stack187StackIterator<oop, mtGC> iter(_preserved_oop_stack);188while (!iter.is_empty()) {189oop* p = iter.next_addr();190adjust_pointer(p);191}192}193194void MarkSweep::restore_marks() {195assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),196"inconsistent preserved oop stacks");197log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_oop_stack.size());198199// restore the marks we saved earlier200for (size_t i = 0; i < _preserved_count; i++) {201_preserved_marks[i].restore();202}203204// deal with the overflow205while (!_preserved_oop_stack.is_empty()) {206oop obj = _preserved_oop_stack.pop();207markWord mark = _preserved_mark_stack.pop();208obj->set_mark(mark);209}210}211212MarkSweep::IsAliveClosure MarkSweep::is_alive;213214bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }215216MarkSweep::KeepAliveClosure MarkSweep::keep_alive;217218void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }219void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }220221void MarkSweep::initialize() {222MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();223MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();224}225226227