1 /* 2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "jfr/leakprofiler/sampling/objectSample.hpp" 27 #include "jfr/leakprofiler/sampling/sampleList.hpp" 28 #include "oops/oop.inline.hpp" 29 30 SampleList::SampleList(size_t limit, size_t cache_size) : 31 _free_list(), 32 _in_use_list(), 33 _last_resolved(NULL), 34 _limit(limit), 35 _cache_size(cache_size), 36 _allocated(0) { 37 } 38 39 SampleList::~SampleList() { 40 deallocate_samples(_free_list); 41 deallocate_samples(_in_use_list); 42 } 43 44 ObjectSample* SampleList::last() const { 45 return _in_use_list.head(); 46 } 47 48 const ObjectSample* SampleList::last_resolved() const { 49 return _last_resolved; 50 } 51 52 void SampleList::set_last_resolved(const ObjectSample* sample) { 53 assert(last() == sample, "invariant"); 54 _last_resolved = sample; 55 } 56 57 void SampleList::link(ObjectSample* sample) { 58 assert(sample != NULL, "invariant"); 59 _in_use_list.prepend(sample); 60 } 61 62 void SampleList::unlink(ObjectSample* sample) { 63 assert(sample != NULL, "invariant"); 64 if (_last_resolved == sample) { 65 _last_resolved = sample->next(); 66 } 67 reset(_in_use_list.remove(sample)); 68 } 69 70 ObjectSample* SampleList::reuse(ObjectSample* sample) { 71 assert(sample != NULL, "invariant"); 72 unlink(sample); 73 link(sample); 74 return sample; 75 } 76 77 void SampleList::populate_cache() { 78 if (_free_list.count() < _cache_size) { 79 const size_t cache_delta = _cache_size - _free_list.count(); 80 for (size_t i = 0; i < cache_delta; ++i) { 81 ObjectSample* sample = newSample(); 82 if (sample != NULL) { 83 _free_list.append(sample); 84 } 85 } 86 } 87 } 88 89 ObjectSample* SampleList::newSample() const { 90 if (_limit == _allocated) { 91 return NULL; 92 } 93 ++_allocated; 94 return new ObjectSample(); 95 } 96 97 ObjectSample* SampleList::get() { 98 ObjectSample* sample = _free_list.head(); 99 if (sample != NULL) { 100 link(_free_list.remove(sample)); 101 } else { 102 sample = newSample(); 103 if (sample != NULL) { 104 _in_use_list.prepend(sample); 105 } 106 } 107 if (_cache_size > 0 && sample != NULL) { 108 populate_cache(); 109 } 110 return sample; 111 } 112 113 void SampleList::release(ObjectSample* sample) { 114 assert(sample != NULL, "invariant"); 115 unlink(sample); 116 _free_list.append(sample); 117 } 118 119 void SampleList::deallocate_samples(List& list) { 120 if (list.count() > 0) { 121 ObjectSample* sample = list.head(); 122 while (sample != NULL) { 123 list.remove(sample); 124 delete sample; 125 sample = list.head(); 126 } 127 } 128 assert(list.count() == 0, "invariant"); 129 } 130 131 void SampleList::reset(ObjectSample* sample) { 132 assert(sample != NULL, "invariant"); 133 sample->reset(); 134 } 135 136 bool SampleList::is_full() const { 137 return _in_use_list.count() == _limit; 138 } 139 140 size_t SampleList::count() const { 141 return _in_use_list.count(); 142 }