duke@435: /* xdono@631: * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // The following class hierarchy represents duke@435: // a set of operations (VM_Operation) related to GC. duke@435: // duke@435: // VM_Operation duke@435: // VM_GC_Operation duke@435: // VM_GC_HeapInspection duke@435: // VM_GenCollectForAllocation duke@435: // VM_GenCollectFull duke@435: // VM_GenCollectFullConcurrent duke@435: // VM_ParallelGCFailedAllocation duke@435: // VM_ParallelGCFailedPermanentAllocation duke@435: // VM_ParallelGCSystemGC duke@435: // VM_GC_Operation duke@435: // - implements methods common to all classes in the hierarchy: duke@435: // prevents multiple gc requests and manages lock on heap; duke@435: // duke@435: // VM_GC_HeapInspection duke@435: // - prints class histogram on SIGBREAK if PrintClassHistogram duke@435: // is specified; and also the attach "inspectheap" operation duke@435: // duke@435: // VM_GenCollectForAllocation apetrusenko@574: // VM_GenCollectForPermanentAllocation duke@435: // VM_ParallelGCFailedAllocation duke@435: // VM_ParallelGCFailedPermanentAllocation duke@435: // - this operation is invoked when allocation is failed; duke@435: // operation performs garbage collection and tries to duke@435: // allocate afterwards; duke@435: // duke@435: // VM_GenCollectFull duke@435: // VM_GenCollectFullConcurrent duke@435: // VM_ParallelGCSystemGC duke@435: // - these operations preform full collection of heaps of duke@435: // different kind duke@435: // duke@435: duke@435: class VM_GC_Operation: public VM_Operation { duke@435: protected: duke@435: BasicLock _pending_list_basic_lock; // for refs pending list notification (PLL) duke@435: unsigned int _gc_count_before; // gc count before acquiring PLL duke@435: unsigned int _full_gc_count_before; // full gc count before acquiring PLL duke@435: bool _full; // whether a "full" collection duke@435: bool _prologue_succeeded; // whether doit_prologue succeeded duke@435: GCCause::Cause _gc_cause; // the putative cause for this gc op duke@435: bool _gc_locked; // will be set if gc was locked duke@435: duke@435: virtual bool skip_operation() const; duke@435: duke@435: // java.lang.ref.Reference support duke@435: void acquire_pending_list_lock(); duke@435: void release_and_notify_pending_list_lock(); duke@435: duke@435: public: duke@435: VM_GC_Operation(unsigned int gc_count_before, duke@435: unsigned int full_gc_count_before = 0, duke@435: bool full = false) { duke@435: _full = full; duke@435: _prologue_succeeded = false; duke@435: _gc_count_before = gc_count_before; duke@435: duke@435: // A subclass constructor will likely overwrite the following duke@435: _gc_cause = GCCause::_no_cause_specified; duke@435: duke@435: _gc_locked = false; duke@435: duke@435: if (full) { duke@435: _full_gc_count_before = full_gc_count_before; duke@435: } duke@435: } duke@435: ~VM_GC_Operation() {} duke@435: duke@435: // Acquire the reference synchronization lock duke@435: virtual bool doit_prologue(); duke@435: // Do notifyAll (if needed) and release held lock duke@435: virtual void doit_epilogue(); duke@435: duke@435: virtual bool allow_nested_vm_operations() const { return true; } duke@435: bool prologue_succeeded() const { return _prologue_succeeded; } duke@435: duke@435: void set_gc_locked() { _gc_locked = true; } duke@435: bool gc_locked() const { return _gc_locked; } duke@435: duke@435: static void notify_gc_begin(bool full = false); duke@435: static void notify_gc_end(); duke@435: }; duke@435: duke@435: duke@435: class VM_GC_HeapInspection: public VM_GC_Operation { duke@435: private: duke@435: outputStream* _out; duke@435: bool _full_gc; ysr@1050: bool _need_prologue; duke@435: public: ysr@1050: VM_GC_HeapInspection(outputStream* out, bool request_full_gc, ysr@1050: bool need_prologue) : duke@435: VM_GC_Operation(0 /* total collections, dummy, ignored */, duke@435: 0 /* total full collections, dummy, ignored */, duke@435: request_full_gc) { duke@435: _out = out; duke@435: _full_gc = request_full_gc; ysr@1050: _need_prologue = need_prologue; duke@435: } duke@435: duke@435: ~VM_GC_HeapInspection() {} duke@435: virtual VMOp_Type type() const { return VMOp_GC_HeapInspection; } duke@435: virtual bool skip_operation() const; duke@435: virtual bool doit_prologue(); duke@435: virtual void doit(); duke@435: }; duke@435: duke@435: duke@435: class VM_GenCollectForAllocation: public VM_GC_Operation { duke@435: private: duke@435: HeapWord* _res; duke@435: size_t _size; // size of object to be allocated. duke@435: bool _tlab; // alloc is of a tlab. duke@435: public: duke@435: VM_GenCollectForAllocation(size_t size, duke@435: bool tlab, duke@435: unsigned int gc_count_before) duke@435: : VM_GC_Operation(gc_count_before), duke@435: _size(size), duke@435: _tlab(tlab) { duke@435: _res = NULL; duke@435: } duke@435: ~VM_GenCollectForAllocation() {} duke@435: virtual VMOp_Type type() const { return VMOp_GenCollectForAllocation; } duke@435: virtual void doit(); duke@435: HeapWord* result() const { return _res; } duke@435: }; duke@435: duke@435: duke@435: // VM operation to invoke a collection of the heap as a duke@435: // GenCollectedHeap heap. duke@435: class VM_GenCollectFull: public VM_GC_Operation { duke@435: private: duke@435: int _max_level; duke@435: public: duke@435: VM_GenCollectFull(unsigned int gc_count_before, duke@435: unsigned int full_gc_count_before, duke@435: GCCause::Cause gc_cause, duke@435: int max_level) duke@435: : VM_GC_Operation(gc_count_before, full_gc_count_before, true /* full */), duke@435: _max_level(max_level) duke@435: { _gc_cause = gc_cause; } duke@435: ~VM_GenCollectFull() {} duke@435: virtual VMOp_Type type() const { return VMOp_GenCollectFull; } duke@435: virtual void doit(); duke@435: }; apetrusenko@574: apetrusenko@574: class VM_GenCollectForPermanentAllocation: public VM_GC_Operation { apetrusenko@574: private: apetrusenko@574: HeapWord* _res; apetrusenko@574: size_t _size; // size of object to be allocated apetrusenko@574: public: apetrusenko@574: VM_GenCollectForPermanentAllocation(size_t size, apetrusenko@574: unsigned int gc_count_before, apetrusenko@574: unsigned int full_gc_count_before, apetrusenko@574: GCCause::Cause gc_cause) apetrusenko@574: : VM_GC_Operation(gc_count_before, full_gc_count_before, true), apetrusenko@574: _size(size) { apetrusenko@574: _res = NULL; apetrusenko@574: _gc_cause = gc_cause; apetrusenko@574: } apetrusenko@574: ~VM_GenCollectForPermanentAllocation() {} apetrusenko@574: virtual VMOp_Type type() const { return VMOp_GenCollectForPermanentAllocation; } apetrusenko@574: virtual void doit(); apetrusenko@574: HeapWord* result() const { return _res; } apetrusenko@574: };