jdk

Форк
0
/
statSampler.cpp 
349 строк · 11.6 Кб
1
/*
2
 * Copyright (c) 2001, 2023, 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 "classfile/javaClasses.hpp"
27
#include "classfile/vmClasses.hpp"
28
#include "classfile/vmSymbols.hpp"
29
#include "memory/allocation.inline.hpp"
30
#include "memory/resourceArea.hpp"
31
#include "oops/oop.inline.hpp"
32
#include "runtime/arguments.hpp"
33
#include "runtime/java.hpp"
34
#include "runtime/javaCalls.hpp"
35
#include "runtime/os.hpp"
36
#include "runtime/perfData.inline.hpp"
37
#include "runtime/statSampler.hpp"
38
#include "runtime/vm_version.hpp"
39

40
// --------------------------------------------------------
41
// StatSamplerTask
42

43
class StatSamplerTask : public PeriodicTask {
44
  public:
45
    StatSamplerTask(int interval_time) : PeriodicTask(interval_time) {}
46
    void task() { StatSampler::collect_sample(); }
47
};
48

49

50
//----------------------------------------------------------
51
// Implementation of StatSampler
52

53
StatSamplerTask*              StatSampler::_task   = nullptr;
54
PerfDataList*                 StatSampler::_sampled = nullptr;
55

56
/*
57
 * the initialize method is called from the engage() method
58
 * and is responsible for initializing various global variables.
59
 */
60
void StatSampler::initialize() {
61

62
  if (!UsePerfData) return;
63

64
  // create performance data that could not be created prior
65
  // to vm_init_globals() or otherwise have no logical home.
66

67
  create_misc_perfdata();
68

69
  // get copy of the sampled list
70
  _sampled = PerfDataManager::sampled();
71

72
}
73

74
/*
75
 * The engage() method is called at initialization time via
76
 * Thread::create_vm() to initialize the StatSampler and
77
 * register it with the WatcherThread as a periodic task.
78
 */
79
void StatSampler::engage() {
80

81
  if (!UsePerfData) return;
82

83
  if (!is_active()) {
84

85
    initialize();
86

87
    // start up the periodic task
88
    _task = new StatSamplerTask(PerfDataSamplingInterval);
89
    _task->enroll();
90
  }
91
}
92

93

94
/*
95
 * the disengage() method is responsible for deactivating the periodic
96
 * task and, if logging was enabled, for logging the final sample. This
97
 * method is called from before_exit() in java.cpp and is only called
98
 * after the WatcherThread has been stopped.
99
 */
100
void StatSampler::disengage() {
101

102
  if (!UsePerfData) return;
103

104
  if (!is_active())
105
    return;
106

107
  // remove StatSamplerTask
108
  _task->disenroll();
109
  delete _task;
110
  _task = nullptr;
111

112
  // force a final sample
113
  sample_data(_sampled);
114
}
115

116
/*
117
 * the destroy method is responsible for releasing any resources used by
118
 * the StatSampler prior to shutdown of the VM. this method is called from
119
 * before_exit() in java.cpp and is only called after the WatcherThread
120
 * has stopped.
121
 */
122
void StatSampler::destroy() {
123

124
  if (!UsePerfData) return;
125

126
  if (_sampled != nullptr) {
127
    delete(_sampled);
128
    _sampled = nullptr;
129
  }
130
}
131

132
/*
133
 * The sample_data() method is responsible for sampling the
134
 * the data value for each PerfData instance in the given list.
135
 */
136
void StatSampler::sample_data(PerfDataList* list) {
137

138
  assert(list != nullptr, "null list unexpected");
139

140
  for (int index = 0; index < list->length(); index++) {
141
    PerfData* item = list->at(index);
142
    item->sample();
143
  }
144
}
145

146
/*
147
 * the collect_sample() method is the method invoked by the
148
 * WatcherThread via the PeriodicTask::task() method. This method
149
 * is responsible for collecting data samples from sampled
150
 * PerfData instances every PerfDataSamplingInterval milliseconds.
151
 * It is also responsible for logging the requested set of
152
 * PerfData instances every _sample_count milliseconds. While
153
 * logging data, it will output a column header after every _print_header
154
 * rows of data have been logged.
155
 */
156
void StatSampler::collect_sample() {
157

158
  // future - check for new PerfData objects. PerfData objects might
159
  // get added to the PerfDataManager lists after we have already
160
  // built our local copies.
161
  //
162
  // if (PerfDataManager::count() > previous) {
163
  //   // get a new copy of the sampled list
164
  //   if (_sampled != nullptr) {
165
  //     delete(_sampled);
166
  //     _sampled = nullptr;
167
  //   }
168
  //   _sampled = PerfDataManager::sampled();
169
  // }
170

171
  assert(_sampled != nullptr, "list not initialized");
172

173
  sample_data(_sampled);
174
}
175

176
/*
177
 * Call into java.lang.System.getProperty to check that the value of the
178
 * specified property matches
179
 */
180
void StatSampler::assert_system_property(const char* name, const char* value, TRAPS) {
181
#ifdef ASSERT
182
  ResourceMark rm(THREAD);
183

184
  // setup the arguments to getProperty
185
  Handle key_str   = java_lang_String::create_from_str(name, CHECK);
186

187
  // return value
188
  JavaValue result(T_OBJECT);
189

190
  // public static String getProperty(String key, String def);
191
  JavaCalls::call_static(&result,
192
                         vmClasses::System_klass(),
193
                         vmSymbols::getProperty_name(),
194
                         vmSymbols::string_string_signature(),
195
                         key_str,
196
                         CHECK);
197

198
  oop value_oop = result.get_oop();
199
  assert(value_oop != nullptr, "property must have a value");
200

201
  // convert Java String to utf8 string
202
  char* system_value = java_lang_String::as_utf8_string(value_oop);
203

204
  assert(strcmp(value, system_value) == 0, "property value mustn't differ from System.getProperty");
205
#endif // ASSERT
206
}
207

208
/*
209
 * Adds a constant counter of the given property. Asserts the value does not
210
 * differ from the value retrievable from System.getProperty(name)
211
 */
212
void StatSampler::add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS) {
213
  // the property must exist
214
  assert(value != nullptr, "property name should be have a value: %s", name);
215
  assert_system_property(name, value, CHECK);
216
  if (value != nullptr) {
217
    // create the property counter
218
    PerfDataManager::create_string_constant(name_space, name, value, CHECK);
219
  }
220
}
221

222
/*
223
 * Adds a string constant of the given property. Retrieves the value via
224
 * Arguments::get_property() and asserts the value for the does not differ from
225
 * the value retrievable from System.getProperty()
226
 */
227
void StatSampler::add_property_constant(CounterNS name_space, const char* name, TRAPS) {
228
  add_property_constant(name_space, name, Arguments::get_property(name), CHECK);
229
}
230

231
/*
232
 * Adds a string constant of the given property. Retrieves the value via
233
 * Arguments::get_property() and asserts the value for the does not differ from
234
 * the value retrievable from System.getProperty()
235
 */
236
void StatSampler::add_optional_property_constant(CounterNS name_space, const char* name, TRAPS) {
237
  const char* value = Arguments::get_property(name);
238

239
  if (value != nullptr) {
240
    add_property_constant(name_space, name, value, CHECK);
241
  }
242
}
243

244
/*
245
 * Method to create PerfStringConstants containing the values of various
246
 * system properties. Constants are created from information known to HotSpot,
247
 * but are initialized as-if getting the values from System.getProperty()
248
 * during bootstrap.
249
 *
250
 * Property counters have a counter name space prefix prepended to the
251
 * property name.
252
 */
253
void StatSampler::create_system_property_instrumentation(TRAPS) {
254

255
  // Non-writeable, constant properties
256
  add_property_constant(JAVA_PROPERTY, "java.vm.specification.name", "Java Virtual Machine Specification", CHECK);
257
  add_property_constant(JAVA_PROPERTY, "java.version", JDK_Version::java_version(), CHECK);
258
  add_property_constant(JAVA_PROPERTY, "java.vm.version", VM_Version::vm_release(), CHECK);
259
  add_property_constant(JAVA_PROPERTY, "java.vm.name", VM_Version::vm_name(), CHECK);
260
  add_property_constant(JAVA_PROPERTY, "java.vm.vendor", VM_Version::vm_vendor(), CHECK);
261
  add_property_constant(JAVA_PROPERTY, "jdk.debug", VM_Version::jdk_debug_level(), CHECK);
262

263
  // Get remaining property constants via Arguments::get_property,
264
  // which does a linear search over the internal system properties list.
265

266
  // SUN_PROPERTY properties
267
  add_property_constant(SUN_PROPERTY, "sun.boot.library.path", CHECK);
268

269
  // JAVA_PROPERTY properties
270
  add_property_constant(JAVA_PROPERTY, "java.vm.specification.version", CHECK);
271
  add_property_constant(JAVA_PROPERTY, "java.vm.specification.vendor", CHECK);
272
  add_property_constant(JAVA_PROPERTY, "java.vm.info", CHECK);
273
  add_property_constant(JAVA_PROPERTY, "java.library.path", CHECK);
274
  add_property_constant(JAVA_PROPERTY, "java.class.path", CHECK);
275
  add_property_constant(JAVA_PROPERTY, "java.home", CHECK);
276

277
  add_optional_property_constant(JAVA_PROPERTY, "jdk.module.path", CHECK);
278
  add_optional_property_constant(JAVA_PROPERTY, "jdk.module.upgrade.path", CHECK);
279
  add_optional_property_constant(JAVA_PROPERTY, "jdk.module.main", CHECK);
280
}
281

282
/*
283
 * The create_misc_perfdata() method provides a place to create
284
 * PerfData instances that would otherwise have no better place
285
 * to exist.
286
 */
287
void StatSampler::create_misc_perfdata() {
288

289
  ResourceMark rm;
290
  EXCEPTION_MARK;
291

292
  // numeric constants
293

294
  // frequency of the native high resolution timer
295
  PerfDataManager::create_constant(SUN_OS, "hrt.frequency",
296
                                   PerfData::U_Hertz, os::elapsed_frequency(),
297
                                   CHECK);
298

299
  // string constants
300

301
  // create string instrumentation for various Java properties.
302
  create_system_property_instrumentation(CHECK);
303

304
  // HotSpot flags (from .hotspotrc) and args (from command line)
305
  //
306
  PerfDataManager::create_string_constant(JAVA_RT, "vmFlags",
307
                                          Arguments::jvm_flags(), CHECK);
308
  PerfDataManager::create_string_constant(JAVA_RT, "vmArgs",
309
                                          Arguments::jvm_args(), CHECK);
310

311
  // java class name/jar file and arguments to main class
312
  // note: name is coordinated with launcher and Arguments.cpp
313
  PerfDataManager::create_string_constant(SUN_RT, "javaCommand",
314
                                          Arguments::java_command(), CHECK);
315

316
  // the Java VM Internal version string
317
  PerfDataManager::create_string_constant(SUN_RT, "internalVersion",
318
                                         VM_Version::internal_vm_info_string(),
319
                                         CHECK);
320

321
  // create sampled instrumentation objects
322
  create_sampled_perfdata();
323
}
324

325
/*
326
 * helper class to provide for sampling of the elapsed_counter value
327
 * maintained in the OS class.
328
 */
329
class HighResTimeSampler : public PerfSampleHelper {
330
  public:
331
    jlong take_sample() { return os::elapsed_counter(); }
332
};
333

334
/*
335
 * the create_sampled_perdata() method provides a place to instantiate
336
 * sampled PerfData instances that would otherwise have no better place
337
 * to exist.
338
 */
339
void StatSampler::create_sampled_perfdata() {
340

341
  EXCEPTION_MARK;
342

343
  // setup sampling of the elapsed time counter maintained in the
344
  // the os class. This counter can be used as either a time stamp
345
  // for each logged entry or as a liveness indicator for the VM.
346
  PerfSampleHelper* psh = new HighResTimeSampler();
347
  PerfDataManager::create_counter(SUN_OS, "hrt.ticks",
348
                                  PerfData::U_Ticks, psh, CHECK);
349
}
350

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.