diff -r c8aa7a0bf7d0 -r 100a882dcffa hotspot/src/share/vm/services/memRecorder.hpp --- a/hotspot/src/share/vm/services/memRecorder.hpp Fri Aug 08 16:24:16 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_SERVICES_MEM_RECORDER_HPP -#define SHARE_VM_SERVICES_MEM_RECORDER_HPP - -#include "memory/allocation.hpp" -#include "runtime/os.hpp" -#include "services/memPtrArray.hpp" - -class MemSnapshot; -class MemTracker; -class MemTrackWorker; - -// Fixed size memory pointer array implementation -template class FixedSizeMemPointerArray : - public MemPointerArray { - // This implementation is for memory recorder only - friend class MemRecorder; - - private: - E _data[SIZE]; - int _size; - - protected: - FixedSizeMemPointerArray(bool init_elements = false): - _size(0){ - if (init_elements) { - for (int index = 0; index < SIZE; index ++) { - ::new ((void*)&_data[index]) E(); - } - } - } - - void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { - // the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder' - // to avoid recursion - return os::malloc(size, (mtNMT | otNMTRecorder)); - } - - void* operator new(size_t size) throw() { - assert(false, "use nothrow version"); - return NULL; - } - - void operator delete(void* p) { - os::free(p, (mtNMT | otNMTRecorder)); - } - - // instance size - inline size_t instance_size() const { - return sizeof(FixedSizeMemPointerArray); - } - - NOT_PRODUCT(int capacity() const { return SIZE; }) - - public: - // implementation of public interface - bool out_of_memory() const { return false; } - bool is_empty() const { return _size == 0; } - bool is_full() { return length() >= SIZE; } - int length() const { return _size; } - - void clear() { - _size = 0; - } - - bool append(MemPointer* ptr) { - if (is_full()) return false; - _data[_size ++] = *(E*)ptr; - return true; - } - - virtual bool insert_at(MemPointer* p, int pos) { - assert(false, "append only"); - return false; - } - - virtual bool remove_at(int pos) { - assert(false, "not supported"); - return false; - } - - MemPointer* at(int index) const { - assert(index >= 0 && index < length(), - "parameter check"); - return ((E*)&_data[index]); - } - - void sort(FN_SORT fn) { - qsort((void*)_data, _size, sizeof(E), fn); - } - - bool shrink() { - return false; - } -}; - - -// This iterator requires pre-sorted MemPointerArray, which is sorted by: -// 1. address -// 2. allocation type -// 3. sequence number -// During the array walking, iterator collapses pointers with the same -// address and allocation type, and only returns the one with highest -// sequence number. -// -// This is read-only iterator, update methods are asserted. -class SequencedRecordIterator : public MemPointerArrayIterator { - private: - MemPointerArrayIteratorImpl _itr; - MemPointer* _cur; - - public: - SequencedRecordIterator(const MemPointerArray* arr): - _itr(const_cast(arr)) { - _cur = next_record(); - } - - SequencedRecordIterator(const SequencedRecordIterator& itr): - _itr(itr._itr) { - _cur = next_record(); - } - - // return the pointer at current position - virtual MemPointer* current() const { - return _cur; - }; - - // return the next pointer and advance current position - virtual MemPointer* next() { - _cur = next_record(); - return _cur; - } - - // return the next pointer without advancing current position - virtual MemPointer* peek_next() const { - assert(false, "not implemented"); - return NULL; - - } - // return the previous pointer without changing current position - virtual MemPointer* peek_prev() const { - assert(false, "not implemented"); - return NULL; - } - - // remove the pointer at current position - virtual void remove() { - assert(false, "read-only iterator"); - }; - // insert the pointer at current position - virtual bool insert(MemPointer* ptr) { - assert(false, "read-only iterator"); - return false; - } - - virtual bool insert_after(MemPointer* ptr) { - assert(false, "read-only iterator"); - return false; - } - private: - // collapse the 'same kind' of records, and return this 'kind' of - // record with highest sequence number - MemPointer* next_record(); - - // Test if the two records are the same kind: the same memory block and allocation - // type. - inline bool same_kind(const MemPointerRecord* p1, const MemPointerRecord* p2) const { - assert(!p1->is_vm_pointer() && !p2->is_vm_pointer(), "malloc pointer only"); - return (p1->addr() == p2->addr() && - (p1->flags() &MemPointerRecord::tag_masks) == - (p2->flags() & MemPointerRecord::tag_masks)); - } -}; - - - -#define DEFAULT_RECORDER_PTR_ARRAY_SIZE 512 - -class MemRecorder : public CHeapObj { - friend class MemSnapshot; - friend class MemTracker; - friend class MemTrackWorker; - friend class GenerationData; - - protected: - // the array that holds memory records - MemPointerArray* _pointer_records; - - private: - // used for linked list - MemRecorder* _next; - // active recorder can only record a certain generation data - unsigned long _generation; - - protected: - _NOINLINE_ MemRecorder(); - ~MemRecorder(); - - // record a memory operation - bool record(address addr, MEMFLAGS flags, size_t size, jint seq, address caller_pc = 0); - - // linked list support - inline void set_next(MemRecorder* rec) { - _next = rec; - } - - inline MemRecorder* next() const { - return _next; - } - - // if the recorder is full - inline bool is_full() const { - assert(_pointer_records != NULL, "just check"); - return _pointer_records->is_full(); - } - - // if running out of memory when initializing recorder's internal - // data - inline bool out_of_memory() const { - return (_pointer_records == NULL || - _pointer_records->out_of_memory()); - } - - inline void clear() { - assert(_pointer_records != NULL, "Just check"); - _pointer_records->clear(); - } - - SequencedRecordIterator pointer_itr(); - - // return the generation of this recorder which it belongs to - unsigned long get_generation() const { return _generation; } - protected: - // number of MemRecorder instance - static volatile jint _instance_count; - - private: - // sorting function, sort records into following order - // 1. memory address - // 2. allocation type - // 3. sequence number - static int sort_record_fn(const void* e1, const void* e2); - - debug_only(void check_dup_seq(jint seq) const;) - void set_generation(); -}; - -#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP