zgu@3900: /* zgu@3900: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. zgu@3900: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. zgu@3900: * zgu@3900: * This code is free software; you can redistribute it and/or modify it zgu@3900: * under the terms of the GNU General Public License version 2 only, as zgu@3900: * published by the Free Software Foundation. zgu@3900: * zgu@3900: * This code is distributed in the hope that it will be useful, but WITHOUT zgu@3900: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or zgu@3900: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License zgu@3900: * version 2 for more details (a copy is included in the LICENSE file that zgu@3900: * accompanied this code). zgu@3900: * zgu@3900: * You should have received a copy of the GNU General Public License version zgu@3900: * 2 along with this work; if not, write to the Free Software Foundation, zgu@3900: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. zgu@3900: * zgu@3900: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA zgu@3900: * or visit www.oracle.com if you need additional information or have any zgu@3900: * questions. zgu@3900: * zgu@3900: */ zgu@3900: zgu@3900: #ifndef SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP zgu@3900: #define SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP zgu@3900: zgu@3900: #include "memory/allocation.hpp" zgu@3900: #include "runtime/thread.hpp" zgu@3900: #include "services/memRecorder.hpp" zgu@3900: zgu@3900: // Maximum MAX_GENERATIONS generation data can be tracked. zgu@3900: #define MAX_GENERATIONS 512 zgu@3900: zgu@4959: class GenerationData VALUE_OBJ_CLASS_SPEC { zgu@4400: private: zgu@4400: int _number_of_classes; zgu@4400: MemRecorder* _recorder_list; zgu@4400: zgu@4400: public: zgu@4400: GenerationData(): _number_of_classes(0), _recorder_list(NULL) { } zgu@4400: zgu@4400: inline int number_of_classes() const { return _number_of_classes; } zgu@4400: inline void set_number_of_classes(long num) { _number_of_classes = num; } zgu@4400: zgu@4400: inline MemRecorder* next_recorder() { zgu@4400: if (_recorder_list == NULL) { zgu@4400: return NULL; zgu@4400: } else { zgu@4400: MemRecorder* tmp = _recorder_list; zgu@4400: _recorder_list = _recorder_list->next(); zgu@4400: return tmp; zgu@4400: } zgu@4400: } zgu@4400: zgu@4400: inline bool has_more_recorder() const { zgu@4400: return (_recorder_list != NULL); zgu@4400: } zgu@4400: zgu@4400: // add recorders to this generation zgu@4400: void add_recorders(MemRecorder* head) { zgu@4400: if (head != NULL) { zgu@4400: if (_recorder_list == NULL) { zgu@4400: _recorder_list = head; zgu@4400: } else { zgu@4400: MemRecorder* tmp = _recorder_list; zgu@4400: for (; tmp->next() != NULL; tmp = tmp->next()); zgu@4400: tmp->set_next(head); zgu@4400: } zgu@4400: } zgu@4400: } zgu@4400: zgu@4400: void reset(); zgu@4400: zgu@4400: NOT_PRODUCT(MemRecorder* peek() const { return _recorder_list; }) zgu@4400: }; zgu@3900: zgu@3900: class MemTrackWorker : public NamedThread { zgu@3900: private: zgu@4400: // circular buffer. This buffer contains generation data to be merged into global zgu@3900: // snaphsot. zgu@4400: // Each slot holds a generation zgu@4400: GenerationData _gen[MAX_GENERATIONS]; zgu@4400: int _head, _tail; // head and tail pointers to above circular buffer zgu@3900: zgu@4400: bool _has_error; zgu@3900: zgu@4927: MemSnapshot* _snapshot; zgu@4927: zgu@3900: public: zgu@4927: MemTrackWorker(MemSnapshot* snapshot); zgu@3900: ~MemTrackWorker(); zgu@3900: _NOINLINE_ void* operator new(size_t size); zgu@3900: _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant); zgu@3900: zgu@3900: void start(); zgu@3900: void run(); zgu@3900: zgu@3900: inline bool has_error() const { return _has_error; } zgu@3900: zgu@3900: // task at synchronization point zgu@4400: void at_sync_point(MemRecorder* pending_recorders, int number_of_classes); zgu@3900: zgu@3900: // for debugging purpose, they are not thread safe. zgu@3900: NOT_PRODUCT(static int count_recorder(const MemRecorder* head);) zgu@3900: NOT_PRODUCT(int count_pending_recorders() const;) zgu@3900: zgu@3900: NOT_PRODUCT(int _sync_point_count;) zgu@3900: NOT_PRODUCT(int _merge_count;) zgu@3900: NOT_PRODUCT(int _last_gen_in_use;) zgu@3900: ctornqvi@4512: // how many generations are queued zgu@3900: inline int generations_in_use() const { zgu@3935: return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1)); zgu@3900: } zgu@3900: }; zgu@3900: zgu@3900: #endif // SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP