Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp
38920 views
/*1* Copyright (c) 2001, 2014, 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#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP25#define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP2627#include "memory/iterator.hpp"28#include "oops/oopsHierarchy.hpp"29#include "runtime/os.hpp"30#include "utilities/debug.hpp"3132// A BufferingOops closure tries to separate out the cost of finding roots33// from the cost of applying closures to them. It maintains an array of34// ref-containing locations. Until the array is full, applying the closure35// to an oop* merely records that location in the array. Since this36// closure app cost is small, an elapsed timer can approximately attribute37// all of this cost to the cost of finding the roots. When the array fills38// up, the wrapped closure is applied to all elements, keeping track of39// this elapsed time of this process, and leaving the array empty.40// The caller must be sure to call "done" to process any unprocessed41// buffered entriess.4243class BufferingOopClosure: public OopClosure {44friend class TestBufferingOopClosure;45protected:46static const size_t BufferLength = 1024;4748// We need to know if the buffered addresses contain oops or narrowOops.49// We can't tag the addresses the way StarTask does, because we need to50// be able to handle unaligned addresses coming from oops embedded in code.51//52// The addresses for the full-sized oops are filled in from the bottom,53// while the addresses for the narrowOops are filled in from the top.54OopOrNarrowOopStar _buffer[BufferLength];55OopOrNarrowOopStar* _oop_top;56OopOrNarrowOopStar* _narrowOop_bottom;5758OopClosure* _oc;59double _closure_app_seconds;606162bool is_buffer_empty() {63return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);64}6566bool is_buffer_full() {67return _narrowOop_bottom < _oop_top;68}6970// Process addresses containing full-sized oops.71void process_oops() {72for (OopOrNarrowOopStar* curr = _buffer; curr < _oop_top; ++curr) {73_oc->do_oop((oop*)(*curr));74}75_oop_top = _buffer;76}7778// Process addresses containing narrow oops.79void process_narrowOops() {80for (OopOrNarrowOopStar* curr = _buffer + BufferLength - 1; curr > _narrowOop_bottom; --curr) {81_oc->do_oop((narrowOop*)(*curr));82}83_narrowOop_bottom = _buffer + BufferLength - 1;84}8586// Apply the closure to all oops and clear the buffer.87// Accumulate the time it took.88void process_buffer() {89double start = os::elapsedTime();9091process_oops();92process_narrowOops();9394_closure_app_seconds += (os::elapsedTime() - start);95}9697void process_buffer_if_full() {98if (is_buffer_full()) {99process_buffer();100}101}102103void add_narrowOop(narrowOop* p) {104assert(!is_buffer_full(), "Buffer should not be full");105*_narrowOop_bottom = (OopOrNarrowOopStar)p;106_narrowOop_bottom--;107}108109void add_oop(oop* p) {110assert(!is_buffer_full(), "Buffer should not be full");111*_oop_top = (OopOrNarrowOopStar)p;112_oop_top++;113}114115public:116virtual void do_oop(narrowOop* p) {117process_buffer_if_full();118add_narrowOop(p);119}120121virtual void do_oop(oop* p) {122process_buffer_if_full();123add_oop(p);124}125126void done() {127if (!is_buffer_empty()) {128process_buffer();129}130}131132double closure_app_seconds() {133return _closure_app_seconds;134}135136BufferingOopClosure(OopClosure *oc) :137_oc(oc),138_oop_top(_buffer),139_narrowOop_bottom(_buffer + BufferLength - 1),140_closure_app_seconds(0.0) { }141};142143#endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP144145146