src/share/vm/services/memRecorder.cpp

Mon, 31 Mar 2014 13:09:35 -0700

author
minqi
date
Mon, 31 Mar 2014 13:09:35 -0700
changeset 6535
f42c10a3d4b1
parent 5272
1f4355cee9a2
child 6876
710a3c8b516e
permissions
-rw-r--r--

7090324: gclog rotation via external tool
Summary: GC log rotation can be set via java command line, but customer sometime need to sync with OS level rotation setting.
Reviewed-by: sla, minqi, ehelin
Contributed-by: suenaga.yasumasa@lab.ntt.co.jp

zgu@3900 1 /*
zgu@5272 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
zgu@3900 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
zgu@3900 4 *
zgu@3900 5 * This code is free software; you can redistribute it and/or modify it
zgu@3900 6 * under the terms of the GNU General Public License version 2 only, as
zgu@3900 7 * published by the Free Software Foundation.
zgu@3900 8 *
zgu@3900 9 * This code is distributed in the hope that it will be useful, but WITHOUT
zgu@3900 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
zgu@3900 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
zgu@3900 12 * version 2 for more details (a copy is included in the LICENSE file that
zgu@3900 13 * accompanied this code).
zgu@3900 14 *
zgu@3900 15 * You should have received a copy of the GNU General Public License version
zgu@3900 16 * 2 along with this work; if not, write to the Free Software Foundation,
zgu@3900 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
zgu@3900 18 *
zgu@3900 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
zgu@3900 20 * or visit www.oracle.com if you need additional information or have any
zgu@3900 21 * questions.
zgu@3900 22 *
zgu@3900 23 */
zgu@3900 24
zgu@3900 25 #include "precompiled.hpp"
zgu@3900 26
zgu@3900 27 #include "runtime/atomic.hpp"
zgu@3900 28 #include "services/memBaseline.hpp"
zgu@3900 29 #include "services/memRecorder.hpp"
zgu@3900 30 #include "services/memPtr.hpp"
zgu@3900 31 #include "services/memTracker.hpp"
zgu@3900 32
zgu@3900 33 MemPointer* SequencedRecordIterator::next_record() {
zgu@4193 34 MemPointerRecord* itr_cur = (MemPointerRecord*)_itr.current();
zgu@4193 35 if (itr_cur == NULL) {
zgu@4193 36 return itr_cur;
zgu@4193 37 }
zgu@3900 38
zgu@4193 39 MemPointerRecord* itr_next = (MemPointerRecord*)_itr.next();
zgu@4193 40
zgu@4193 41 // don't collapse virtual memory records
zgu@4193 42 while (itr_next != NULL && !itr_cur->is_vm_pointer() &&
zgu@4193 43 !itr_next->is_vm_pointer() &&
zgu@4193 44 same_kind(itr_cur, itr_next)) {
zgu@3900 45 itr_cur = itr_next;
zgu@4193 46 itr_next = (MemPointerRecord*)_itr.next();
zgu@3900 47 }
zgu@3900 48
zgu@3900 49 return itr_cur;
zgu@3900 50 }
zgu@3900 51
zgu@3900 52
zgu@3935 53 volatile jint MemRecorder::_instance_count = 0;
zgu@3900 54
zgu@3900 55 MemRecorder::MemRecorder() {
zgu@3900 56 assert(MemTracker::is_on(), "Native memory tracking is off");
zgu@3935 57 Atomic::inc(&_instance_count);
ctornqvi@4512 58 set_generation();
zgu@3900 59
zgu@3900 60 if (MemTracker::track_callsite()) {
zgu@3900 61 _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecordEx,
zgu@3900 62 DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
zgu@3900 63 } else {
zgu@3900 64 _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecord,
zgu@3900 65 DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
zgu@3900 66 }
zgu@3900 67 _next = NULL;
zgu@3900 68
zgu@3900 69
zgu@3900 70 if (_pointer_records != NULL) {
zgu@3900 71 // recode itself
zgu@5272 72 address pc = CURRENT_PC;
zgu@3900 73 record((address)this, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
zgu@5272 74 sizeof(MemRecorder), SequenceGenerator::next(), pc);
zgu@3900 75 record((address)_pointer_records, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
zgu@5272 76 _pointer_records->instance_size(), SequenceGenerator::next(), pc);
zgu@3900 77 }
zgu@3900 78 }
zgu@3900 79
zgu@3900 80 MemRecorder::~MemRecorder() {
zgu@3900 81 if (_pointer_records != NULL) {
zgu@3900 82 if (MemTracker::is_on()) {
zgu@3900 83 MemTracker::record_free((address)_pointer_records, mtNMT);
zgu@3900 84 MemTracker::record_free((address)this, mtNMT);
zgu@3900 85 }
zgu@3900 86 delete _pointer_records;
zgu@3900 87 }
zgu@4400 88 // delete all linked recorders
zgu@4400 89 while (_next != NULL) {
zgu@4400 90 MemRecorder* tmp = _next;
zgu@4400 91 _next = _next->next();
zgu@4400 92 tmp->set_next(NULL);
zgu@4400 93 delete tmp;
zgu@3900 94 }
zgu@3900 95 Atomic::dec(&_instance_count);
zgu@3900 96 }
zgu@3900 97
zgu@3900 98 // Sorting order:
zgu@3900 99 // 1. memory block address
zgu@3900 100 // 2. mem pointer record tags
zgu@3900 101 // 3. sequence number
zgu@3900 102 int MemRecorder::sort_record_fn(const void* e1, const void* e2) {
zgu@3900 103 const MemPointerRecord* p1 = (const MemPointerRecord*)e1;
zgu@3900 104 const MemPointerRecord* p2 = (const MemPointerRecord*)e2;
zgu@3900 105 int delta = UNSIGNED_COMPARE(p1->addr(), p2->addr());
zgu@3900 106 if (delta == 0) {
zgu@3900 107 int df = UNSIGNED_COMPARE((p1->flags() & MemPointerRecord::tag_masks),
zgu@3900 108 (p2->flags() & MemPointerRecord::tag_masks));
zgu@3900 109 if (df == 0) {
zgu@3900 110 assert(p1->seq() != p2->seq(), "dup seq");
zgu@3900 111 return p1->seq() - p2->seq();
zgu@3900 112 } else {
zgu@3900 113 return df;
zgu@3900 114 }
zgu@3900 115 } else {
zgu@3900 116 return delta;
zgu@3900 117 }
zgu@3900 118 }
zgu@3900 119
zgu@5272 120 bool MemRecorder::record(address p, MEMFLAGS flags, size_t size, jint seq, address pc) {
zgu@5272 121 assert(seq > 0, "No sequence number");
zgu@3900 122 #ifdef ASSERT
zgu@3900 123 if (MemPointerRecord::is_virtual_memory_record(flags)) {
zgu@3900 124 assert((flags & MemPointerRecord::tag_masks) != 0, "bad virtual memory record");
zgu@3900 125 } else {
zgu@3900 126 assert((flags & MemPointerRecord::tag_masks) == MemPointerRecord::malloc_tag() ||
zgu@3900 127 (flags & MemPointerRecord::tag_masks) == MemPointerRecord::free_tag() ||
zgu@3900 128 IS_ARENA_OBJ(flags),
zgu@3900 129 "bad malloc record");
zgu@3900 130 }
zgu@3900 131 // a recorder should only hold records within the same generation
zgu@3900 132 unsigned long cur_generation = SequenceGenerator::current_generation();
zgu@3900 133 assert(cur_generation == _generation,
zgu@3900 134 "this thread did not enter sync point");
zgu@3900 135 #endif
zgu@3900 136
zgu@3900 137 if (MemTracker::track_callsite()) {
zgu@5272 138 SeqMemPointerRecordEx ap(p, flags, size, seq, pc);
zgu@3900 139 debug_only(check_dup_seq(ap.seq());)
zgu@3900 140 return _pointer_records->append(&ap);
zgu@3900 141 } else {
zgu@5272 142 SeqMemPointerRecord ap(p, flags, size, seq);
zgu@3900 143 debug_only(check_dup_seq(ap.seq());)
zgu@3900 144 return _pointer_records->append(&ap);
zgu@3900 145 }
zgu@3900 146 }
zgu@3900 147
zgu@3900 148 // iterator for alloc pointers
zgu@3900 149 SequencedRecordIterator MemRecorder::pointer_itr() {
zgu@3900 150 assert(_pointer_records != NULL, "just check");
zgu@3900 151 _pointer_records->sort((FN_SORT)sort_record_fn);
zgu@3900 152 return SequencedRecordIterator(_pointer_records);
zgu@3900 153 }
zgu@3900 154
zgu@3900 155
zgu@3900 156 void MemRecorder::set_generation() {
zgu@3900 157 _generation = SequenceGenerator::current_generation();
zgu@3900 158 }
zgu@3900 159
ctornqvi@4512 160 #ifdef ASSERT
ctornqvi@4512 161
zgu@3900 162 void MemRecorder::check_dup_seq(jint seq) const {
zgu@3900 163 MemPointerArrayIteratorImpl itr(_pointer_records);
zgu@3900 164 MemPointerRecord* rc = (MemPointerRecord*)itr.current();
zgu@3900 165 while (rc != NULL) {
zgu@3900 166 assert(rc->seq() != seq, "dup seq");
zgu@3900 167 rc = (MemPointerRecord*)itr.next();
zgu@3900 168 }
zgu@3900 169 }
zgu@3900 170
zgu@3900 171 #endif

mercurial