1.1 --- a/src/share/vm/services/memTrackWorker.cpp Wed Aug 27 09:36:55 2014 +0200 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,212 +0,0 @@ 1.4 -/* 1.5 - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 - * 1.8 - * This code is free software; you can redistribute it and/or modify it 1.9 - * under the terms of the GNU General Public License version 2 only, as 1.10 - * published by the Free Software Foundation. 1.11 - * 1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 - * version 2 for more details (a copy is included in the LICENSE file that 1.16 - * accompanied this code). 1.17 - * 1.18 - * You should have received a copy of the GNU General Public License version 1.19 - * 2 along with this work; if not, write to the Free Software Foundation, 1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 - * 1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 - * or visit www.oracle.com if you need additional information or have any 1.24 - * questions. 1.25 - * 1.26 - */ 1.27 - 1.28 -#include "precompiled.hpp" 1.29 -#include "runtime/threadCritical.hpp" 1.30 -#include "services/memTracker.hpp" 1.31 -#include "services/memTrackWorker.hpp" 1.32 -#include "utilities/decoder.hpp" 1.33 -#include "utilities/vmError.hpp" 1.34 - 1.35 - 1.36 -void GenerationData::reset() { 1.37 - _number_of_classes = 0; 1.38 - while (_recorder_list != NULL) { 1.39 - MemRecorder* tmp = _recorder_list; 1.40 - _recorder_list = _recorder_list->next(); 1.41 - MemTracker::release_thread_recorder(tmp); 1.42 - } 1.43 -} 1.44 - 1.45 -MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) { 1.46 - // create thread uses cgc thread type for now. We should revisit 1.47 - // the option, or create new thread type. 1.48 - _has_error = !os::create_thread(this, os::cgc_thread); 1.49 - set_name("MemTrackWorker"); 1.50 - 1.51 - // initial generation circuit buffer 1.52 - if (!has_error()) { 1.53 - _head = _tail = 0; 1.54 - for(int index = 0; index < MAX_GENERATIONS; index ++) { 1.55 - ::new ((void*)&_gen[index]) GenerationData(); 1.56 - } 1.57 - } 1.58 - NOT_PRODUCT(_sync_point_count = 0;) 1.59 - NOT_PRODUCT(_merge_count = 0;) 1.60 - NOT_PRODUCT(_last_gen_in_use = 0;) 1.61 -} 1.62 - 1.63 -MemTrackWorker::~MemTrackWorker() { 1.64 - for (int index = 0; index < MAX_GENERATIONS; index ++) { 1.65 - _gen[index].reset(); 1.66 - } 1.67 -} 1.68 - 1.69 -void* MemTrackWorker::operator new(size_t size) throw() { 1.70 - assert(false, "use nothrow version"); 1.71 - return NULL; 1.72 -} 1.73 - 1.74 -void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { 1.75 - return allocate(size, false, mtNMT); 1.76 -} 1.77 - 1.78 -void MemTrackWorker::start() { 1.79 - os::start_thread(this); 1.80 -} 1.81 - 1.82 -/* 1.83 - * Native memory tracking worker thread loop: 1.84 - * 1. merge one generation of memory recorders to staging area 1.85 - * 2. promote staging data to memory snapshot 1.86 - * 1.87 - * This thread can run through safepoint. 1.88 - */ 1.89 - 1.90 -void MemTrackWorker::run() { 1.91 - assert(MemTracker::is_on(), "native memory tracking is off"); 1.92 - this->initialize_thread_local_storage(); 1.93 - this->record_stack_base_and_size(); 1.94 - assert(_snapshot != NULL, "Worker should not be started"); 1.95 - MemRecorder* rec; 1.96 - unsigned long processing_generation = 0; 1.97 - bool worker_idle = false; 1.98 - 1.99 - while (!MemTracker::shutdown_in_progress()) { 1.100 - NOT_PRODUCT(_last_gen_in_use = generations_in_use();) 1.101 - { 1.102 - // take a recorder from earliest generation in buffer 1.103 - ThreadCritical tc; 1.104 - rec = _gen[_head].next_recorder(); 1.105 - } 1.106 - if (rec != NULL) { 1.107 - if (rec->get_generation() != processing_generation || worker_idle) { 1.108 - processing_generation = rec->get_generation(); 1.109 - worker_idle = false; 1.110 - MemTracker::set_current_processing_generation(processing_generation); 1.111 - } 1.112 - 1.113 - // merge the recorder into staging area 1.114 - if (!_snapshot->merge(rec)) { 1.115 - MemTracker::shutdown(MemTracker::NMT_out_of_memory); 1.116 - } else { 1.117 - NOT_PRODUCT(_merge_count ++;) 1.118 - } 1.119 - MemTracker::release_thread_recorder(rec); 1.120 - } else { 1.121 - // no more recorder to merge, promote staging area 1.122 - // to snapshot 1.123 - if (_head != _tail) { 1.124 - long number_of_classes; 1.125 - { 1.126 - ThreadCritical tc; 1.127 - if (_gen[_head].has_more_recorder() || _head == _tail) { 1.128 - continue; 1.129 - } 1.130 - number_of_classes = _gen[_head].number_of_classes(); 1.131 - _gen[_head].reset(); 1.132 - 1.133 - // done with this generation, increment _head pointer 1.134 - _head = (_head + 1) % MAX_GENERATIONS; 1.135 - } 1.136 - // promote this generation data to snapshot 1.137 - if (!_snapshot->promote(number_of_classes)) { 1.138 - // failed to promote, means out of memory 1.139 - MemTracker::shutdown(MemTracker::NMT_out_of_memory); 1.140 - } 1.141 - } else { 1.142 - // worker thread is idle 1.143 - worker_idle = true; 1.144 - MemTracker::report_worker_idle(); 1.145 - _snapshot->wait(1000); 1.146 - ThreadCritical tc; 1.147 - // check if more data arrived 1.148 - if (!_gen[_head].has_more_recorder()) { 1.149 - _gen[_head].add_recorders(MemTracker::get_pending_recorders()); 1.150 - } 1.151 - } 1.152 - } 1.153 - } 1.154 - assert(MemTracker::shutdown_in_progress(), "just check"); 1.155 - 1.156 - // transits to final shutdown 1.157 - MemTracker::final_shutdown(); 1.158 -} 1.159 - 1.160 -// at synchronization point, where 'safepoint visible' Java threads are blocked 1.161 -// at a safepoint, and the rest of threads are blocked on ThreadCritical lock. 1.162 -// The caller MemTracker::sync() already takes ThreadCritical before calling this 1.163 -// method. 1.164 -// 1.165 -// Following tasks are performed: 1.166 -// 1. add all recorders in pending queue to current generation 1.167 -// 2. increase generation 1.168 - 1.169 -void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) { 1.170 - NOT_PRODUCT(_sync_point_count ++;) 1.171 - assert(count_recorder(rec) <= MemRecorder::_instance_count, 1.172 - "pending queue has infinite loop"); 1.173 - 1.174 - bool out_of_generation_buffer = false; 1.175 - // check shutdown state inside ThreadCritical 1.176 - if (MemTracker::shutdown_in_progress()) return; 1.177 - 1.178 - _gen[_tail].set_number_of_classes(number_of_classes); 1.179 - // append the recorders to the end of the generation 1.180 - _gen[_tail].add_recorders(rec); 1.181 - assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count, 1.182 - "after add to current generation has infinite loop"); 1.183 - // we have collected all recorders for this generation. If there is data, 1.184 - // we need to increment _tail to start a new generation. 1.185 - if (_gen[_tail].has_more_recorder() || _head == _tail) { 1.186 - _tail = (_tail + 1) % MAX_GENERATIONS; 1.187 - out_of_generation_buffer = (_tail == _head); 1.188 - } 1.189 - 1.190 - if (out_of_generation_buffer) { 1.191 - MemTracker::shutdown(MemTracker::NMT_out_of_generation); 1.192 - } 1.193 -} 1.194 - 1.195 -#ifndef PRODUCT 1.196 -int MemTrackWorker::count_recorder(const MemRecorder* head) { 1.197 - int count = 0; 1.198 - while(head != NULL) { 1.199 - count ++; 1.200 - head = head->next(); 1.201 - } 1.202 - return count; 1.203 -} 1.204 - 1.205 -int MemTrackWorker::count_pending_recorders() const { 1.206 - int count = 0; 1.207 - for (int index = 0; index < MAX_GENERATIONS; index ++) { 1.208 - MemRecorder* head = _gen[index].peek(); 1.209 - if (head != NULL) { 1.210 - count += count_recorder(head); 1.211 - } 1.212 - } 1.213 - return count; 1.214 -} 1.215 -#endif