1 | /* |
2 | * Copyright (c) 2001, 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 "jvm.h" |
27 | #include "logging/log.hpp" |
28 | #include "memory/allocation.inline.hpp" |
29 | #include "runtime/arguments.hpp" |
30 | #include "runtime/java.hpp" |
31 | #include "runtime/mutex.hpp" |
32 | #include "runtime/mutexLocker.hpp" |
33 | #include "runtime/orderAccess.hpp" |
34 | #include "runtime/os.hpp" |
35 | #include "runtime/perfData.hpp" |
36 | #include "runtime/perfMemory.hpp" |
37 | #include "runtime/safepoint.hpp" |
38 | #include "runtime/statSampler.hpp" |
39 | #include "utilities/align.hpp" |
40 | #include "utilities/globalDefinitions.hpp" |
41 | |
42 | // Prefix of performance data file. |
43 | const char PERFDATA_NAME[] = "hsperfdata" ; |
44 | |
45 | // Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating |
46 | // character will be included in the sizeof(PERFDATA_NAME) operation. |
47 | static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) + |
48 | UINT_CHARS + 1; |
49 | |
50 | char* PerfMemory::_start = NULL; |
51 | char* PerfMemory::_end = NULL; |
52 | char* PerfMemory::_top = NULL; |
53 | size_t PerfMemory::_capacity = 0; |
54 | int PerfMemory::_initialized = false; |
55 | PerfDataPrologue* PerfMemory::_prologue = NULL; |
56 | bool PerfMemory::_destroyed = false; |
57 | |
58 | void perfMemory_init() { |
59 | |
60 | if (!UsePerfData) return; |
61 | |
62 | PerfMemory::initialize(); |
63 | } |
64 | |
65 | void perfMemory_exit() { |
66 | |
67 | if (!UsePerfData) return; |
68 | if (!PerfMemory::is_usable()) return; |
69 | |
70 | // Only destroy PerfData objects if we're at a safepoint and the |
71 | // StatSampler is not active. Otherwise, we risk removing PerfData |
72 | // objects that are currently being used by running JavaThreads |
73 | // or the StatSampler. This method is invoked while we are not at |
74 | // a safepoint during a VM abort so leaving the PerfData objects |
75 | // around may also help diagnose the failure. In rare cases, |
76 | // PerfData objects are used in parallel with a safepoint. See |
77 | // the work around in PerfDataManager::destroy(). |
78 | // |
79 | if (SafepointSynchronize::is_at_safepoint() && !StatSampler::is_active()) { |
80 | PerfDataManager::destroy(); |
81 | } |
82 | |
83 | // Remove the persistent external resources, if any. This method |
84 | // does not unmap or invalidate any virtual memory allocated during |
85 | // initialization. |
86 | // |
87 | PerfMemory::destroy(); |
88 | } |
89 | |
90 | void PerfMemory::initialize() { |
91 | |
92 | if (is_initialized()) |
93 | // initialization already performed |
94 | return; |
95 | |
96 | size_t capacity = align_up(PerfDataMemorySize, |
97 | os::vm_allocation_granularity()); |
98 | |
99 | log_debug(perf, memops)("PerfDataMemorySize = " SIZE_FORMAT "," |
100 | " os::vm_allocation_granularity = %d," |
101 | " adjusted size = " SIZE_FORMAT, |
102 | PerfDataMemorySize, |
103 | os::vm_allocation_granularity(), |
104 | capacity); |
105 | |
106 | // allocate PerfData memory region |
107 | create_memory_region(capacity); |
108 | |
109 | if (_start == NULL) { |
110 | |
111 | // the PerfMemory region could not be created as desired. Rather |
112 | // than terminating the JVM, we revert to creating the instrumentation |
113 | // on the C heap. When running in this mode, external monitoring |
114 | // clients cannot attach to and monitor this JVM. |
115 | // |
116 | // the warning is issued only in debug mode in order to avoid |
117 | // additional output to the stdout or stderr output streams. |
118 | // |
119 | if (PrintMiscellaneous && Verbose) { |
120 | warning("Could not create PerfData Memory region, reverting to malloc" ); |
121 | } |
122 | |
123 | _prologue = NEW_C_HEAP_OBJ(PerfDataPrologue, mtInternal); |
124 | } |
125 | else { |
126 | |
127 | // the PerfMemory region was created as expected. |
128 | |
129 | log_debug(perf, memops)("PerfMemory created: address = " INTPTR_FORMAT "," |
130 | " size = " SIZE_FORMAT, |
131 | p2i(_start), |
132 | _capacity); |
133 | |
134 | _prologue = (PerfDataPrologue *)_start; |
135 | _end = _start + _capacity; |
136 | _top = _start + sizeof(PerfDataPrologue); |
137 | } |
138 | |
139 | assert(_prologue != NULL, "prologue pointer must be initialized" ); |
140 | |
141 | #ifdef VM_LITTLE_ENDIAN |
142 | _prologue->magic = (jint)0xc0c0feca; |
143 | _prologue->byte_order = PERFDATA_LITTLE_ENDIAN; |
144 | #else |
145 | _prologue->magic = (jint)0xcafec0c0; |
146 | _prologue->byte_order = PERFDATA_BIG_ENDIAN; |
147 | #endif |
148 | |
149 | _prologue->major_version = PERFDATA_MAJOR_VERSION; |
150 | _prologue->minor_version = PERFDATA_MINOR_VERSION; |
151 | _prologue->accessible = 0; |
152 | |
153 | _prologue->entry_offset = sizeof(PerfDataPrologue); |
154 | _prologue->num_entries = 0; |
155 | _prologue->used = 0; |
156 | _prologue->overflow = 0; |
157 | _prologue->mod_time_stamp = 0; |
158 | |
159 | OrderAccess::release_store(&_initialized, 1); |
160 | } |
161 | |
162 | void PerfMemory::destroy() { |
163 | |
164 | if (!is_usable()) return; |
165 | |
166 | if (_start != NULL && _prologue->overflow != 0) { |
167 | |
168 | // This state indicates that the contiguous memory region exists and |
169 | // that it wasn't large enough to hold all the counters. In this case, |
170 | // we output a warning message to the user on exit if the -XX:+Verbose |
171 | // flag is set (a debug only flag). External monitoring tools can detect |
172 | // this condition by monitoring the _prologue->overflow word. |
173 | // |
174 | // There are two tunables that can help resolve this issue: |
175 | // - increase the size of the PerfMemory with -XX:PerfDataMemorySize=<n> |
176 | // - decrease the maximum string constant length with |
177 | // -XX:PerfMaxStringConstLength=<n> |
178 | // |
179 | if (PrintMiscellaneous && Verbose) { |
180 | warning("PerfMemory Overflow Occurred.\n" |
181 | "\tCapacity = " SIZE_FORMAT " bytes" |
182 | " Used = " SIZE_FORMAT " bytes" |
183 | " Overflow = " INT32_FORMAT " bytes" |
184 | "\n\tUse -XX:PerfDataMemorySize=<size> to specify larger size." , |
185 | PerfMemory::capacity(), |
186 | PerfMemory::used(), |
187 | _prologue->overflow); |
188 | } |
189 | } |
190 | |
191 | if (_start != NULL) { |
192 | |
193 | // this state indicates that the contiguous memory region was successfully |
194 | // and that persistent resources may need to be cleaned up. This is |
195 | // expected to be the typical condition. |
196 | // |
197 | delete_memory_region(); |
198 | } |
199 | |
200 | _destroyed = true; |
201 | } |
202 | |
203 | // allocate an aligned block of memory from the PerfData memory |
204 | // region. This method assumes that the PerfData memory region |
205 | // was aligned on a double word boundary when created. |
206 | // |
207 | char* PerfMemory::alloc(size_t size) { |
208 | |
209 | if (!UsePerfData) return NULL; |
210 | |
211 | MutexLocker ml(PerfDataMemAlloc_lock); |
212 | |
213 | assert(is_usable(), "called before init or after destroy" ); |
214 | |
215 | // check that there is enough memory for this request |
216 | if ((_top + size) >= _end) { |
217 | |
218 | _prologue->overflow += (jint)size; |
219 | |
220 | return NULL; |
221 | } |
222 | |
223 | char* result = _top; |
224 | |
225 | _top += size; |
226 | |
227 | assert(contains(result), "PerfData memory pointer out of range" ); |
228 | |
229 | _prologue->used = (jint)used(); |
230 | _prologue->num_entries = _prologue->num_entries + 1; |
231 | |
232 | return result; |
233 | } |
234 | |
235 | void PerfMemory::mark_updated() { |
236 | if (!UsePerfData) return; |
237 | |
238 | assert(is_usable(), "called before init or after destroy" ); |
239 | |
240 | _prologue->mod_time_stamp = os::elapsed_counter(); |
241 | } |
242 | |
243 | // Returns the complete path including the file name of performance data file. |
244 | // Caller is expected to release the allocated memory. |
245 | char* PerfMemory::get_perfdata_file_path() { |
246 | char* dest_file = NULL; |
247 | |
248 | if (PerfDataSaveFile != NULL) { |
249 | // dest_file_name stores the validated file name if file_name |
250 | // contains %p which will be replaced by pid. |
251 | dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN, mtInternal); |
252 | if(!Arguments::copy_expand_pid(PerfDataSaveFile, strlen(PerfDataSaveFile), |
253 | dest_file, JVM_MAXPATHLEN)) { |
254 | FREE_C_HEAP_ARRAY(char, dest_file); |
255 | if (PrintMiscellaneous && Verbose) { |
256 | warning("Invalid performance data file path name specified, " \ |
257 | "fall back to a default name" ); |
258 | } |
259 | } else { |
260 | return dest_file; |
261 | } |
262 | } |
263 | // create the name of the file for retaining the instrumentation memory. |
264 | dest_file = NEW_C_HEAP_ARRAY(char, PERFDATA_FILENAME_LEN, mtInternal); |
265 | jio_snprintf(dest_file, PERFDATA_FILENAME_LEN, |
266 | "%s_%d" , PERFDATA_NAME, os::current_process_id()); |
267 | |
268 | return dest_file; |
269 | } |
270 | |
271 | bool PerfMemory::is_initialized() { |
272 | return OrderAccess::load_acquire(&_initialized) != 0; |
273 | } |
274 | |