aoqi@0: /* aoqi@0: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1HRPRINTER_HPP aoqi@0: #define SHARE_VM_GC_IMPLEMENTATION_G1_G1HRPRINTER_HPP aoqi@0: aoqi@0: #include "memory/allocation.hpp" aoqi@0: #include "gc_implementation/g1/heapRegion.hpp" aoqi@0: aoqi@0: #define SKIP_RETIRED_FULL_REGIONS 1 aoqi@0: aoqi@0: class G1HRPrinter VALUE_OBJ_CLASS_SPEC { aoqi@0: public: aoqi@0: typedef enum { aoqi@0: Alloc, aoqi@0: AllocForce, aoqi@0: Retire, aoqi@0: Reuse, aoqi@0: CSet, aoqi@0: EvacFailure, aoqi@0: Cleanup, aoqi@0: PostCompaction, aoqi@0: Commit, aoqi@0: Uncommit aoqi@0: } ActionType; aoqi@0: aoqi@0: typedef enum { aoqi@0: Unset, aoqi@0: Eden, aoqi@0: Survivor, aoqi@0: Old, aoqi@0: SingleHumongous, aoqi@0: StartsHumongous, aoqi@0: ContinuesHumongous aoqi@0: } RegionType; aoqi@0: aoqi@0: typedef enum { aoqi@0: StartGC, aoqi@0: EndGC, aoqi@0: StartFullGC, aoqi@0: EndFullGC aoqi@0: } PhaseType; aoqi@0: aoqi@0: private: aoqi@0: bool _active; aoqi@0: aoqi@0: static const char* action_name(ActionType action); aoqi@0: static const char* region_type_name(RegionType type); aoqi@0: static const char* phase_name(PhaseType phase); aoqi@0: aoqi@0: // Print an action event. This version is used in most scenarios and aoqi@0: // only prints the region's bottom. The parameters type and top are aoqi@0: // optional (the "not set" values are Unset and NULL). aoqi@0: static void print(ActionType action, RegionType type, aoqi@0: HeapRegion* hr, HeapWord* top); aoqi@0: aoqi@0: // Print an action event. This version prints both the region's aoqi@0: // bottom and end. Used for Commit / Uncommit events. aoqi@0: static void print(ActionType action, HeapWord* bottom, HeapWord* end); aoqi@0: aoqi@0: // Print a phase event. aoqi@0: static void print(PhaseType phase, size_t phase_num); aoqi@0: aoqi@0: public: aoqi@0: // In some places we iterate over a list in order to generate output aoqi@0: // for the list's elements. By exposing this we can avoid this aoqi@0: // iteration if the printer is not active. aoqi@0: const bool is_active() { return _active; } aoqi@0: aoqi@0: // Have to set this explicitly as we have to do this during the aoqi@0: // heap's initialize() method, not in the constructor. aoqi@0: void set_active(bool active) { _active = active; } aoqi@0: aoqi@0: // The methods below are convenient wrappers for the print() methods. aoqi@0: aoqi@0: void alloc(HeapRegion* hr, RegionType type, bool force = false) { aoqi@0: if (is_active()) { aoqi@0: print((!force) ? Alloc : AllocForce, type, hr, NULL); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void alloc(RegionType type, HeapRegion* hr, HeapWord* top) { aoqi@0: if (is_active()) { aoqi@0: print(Alloc, type, hr, top); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void retire(HeapRegion* hr) { aoqi@0: if (is_active()) { aoqi@0: if (!SKIP_RETIRED_FULL_REGIONS || hr->top() < hr->end()) { aoqi@0: print(Retire, Unset, hr, hr->top()); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void reuse(HeapRegion* hr) { aoqi@0: if (is_active()) { aoqi@0: print(Reuse, Unset, hr, NULL); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void cset(HeapRegion* hr) { aoqi@0: if (is_active()) { aoqi@0: print(CSet, Unset, hr, NULL); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void evac_failure(HeapRegion* hr) { aoqi@0: if (is_active()) { aoqi@0: print(EvacFailure, Unset, hr, NULL); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void cleanup(HeapRegion* hr) { aoqi@0: if (is_active()) { aoqi@0: print(Cleanup, Unset, hr, NULL); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void post_compaction(HeapRegion* hr, RegionType type) { aoqi@0: if (is_active()) { aoqi@0: print(PostCompaction, type, hr, hr->top()); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void commit(HeapWord* bottom, HeapWord* end) { aoqi@0: if (is_active()) { aoqi@0: print(Commit, bottom, end); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void uncommit(HeapWord* bottom, HeapWord* end) { aoqi@0: if (is_active()) { aoqi@0: print(Uncommit, bottom, end); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void start_gc(bool full, size_t gc_num) { aoqi@0: if (is_active()) { aoqi@0: if (!full) { aoqi@0: print(StartGC, gc_num); aoqi@0: } else { aoqi@0: print(StartFullGC, gc_num); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void end_gc(bool full, size_t gc_num) { aoqi@0: if (is_active()) { aoqi@0: if (!full) { aoqi@0: print(EndGC, gc_num); aoqi@0: } else { aoqi@0: print(EndFullGC, gc_num); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: G1HRPrinter() : _active(false) { } aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1HRPRINTER_HPP