1 | /* |
2 | * Copyright (c) 1997, 2019, 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 | #ifndef SHARE_CLASSFILE_CLASSLOADER_HPP |
26 | #define SHARE_CLASSFILE_CLASSLOADER_HPP |
27 | |
28 | #include "jimage.hpp" |
29 | #include "runtime/handles.hpp" |
30 | #include "runtime/perfData.hpp" |
31 | #include "utilities/exceptions.hpp" |
32 | #include "utilities/macros.hpp" |
33 | |
34 | // The VM class loader. |
35 | #include <sys/stat.h> |
36 | |
37 | // Name of boot "modules" image |
38 | #define MODULES_IMAGE_NAME "modules" |
39 | |
40 | // Class path entry (directory or zip file) |
41 | |
42 | class JImageFile; |
43 | class ClassFileStream; |
44 | class PackageEntry; |
45 | template <typename T> class GrowableArray; |
46 | |
47 | class ClassPathEntry : public CHeapObj<mtClass> { |
48 | private: |
49 | ClassPathEntry* volatile _next; |
50 | public: |
51 | ClassPathEntry* next() const; |
52 | virtual ~ClassPathEntry() {} |
53 | void set_next(ClassPathEntry* next); |
54 | virtual bool is_modules_image() const = 0; |
55 | virtual bool is_jar_file() const = 0; |
56 | virtual const char* name() const = 0; |
57 | virtual JImageFile* jimage() const = 0; |
58 | virtual void close_jimage() = 0; |
59 | // Constructor |
60 | ClassPathEntry() : _next(NULL) {} |
61 | // Attempt to locate file_name through this class path entry. |
62 | // Returns a class file parsing stream if successfull. |
63 | virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0; |
64 | // Open the stream for a specific class loader |
65 | virtual ClassFileStream* open_stream_for_loader(const char* name, ClassLoaderData* loader_data, TRAPS) { |
66 | return open_stream(name, THREAD); |
67 | } |
68 | }; |
69 | |
70 | class ClassPathDirEntry: public ClassPathEntry { |
71 | private: |
72 | const char* _dir; // Name of directory |
73 | public: |
74 | bool is_modules_image() const { return false; } |
75 | bool is_jar_file() const { return false; } |
76 | const char* name() const { return _dir; } |
77 | JImageFile* jimage() const { return NULL; } |
78 | void close_jimage() {} |
79 | ClassPathDirEntry(const char* dir); |
80 | virtual ~ClassPathDirEntry() {} |
81 | ClassFileStream* open_stream(const char* name, TRAPS); |
82 | }; |
83 | |
84 | |
85 | // Type definitions for zip file and zip file entry |
86 | typedef void* jzfile; |
87 | typedef struct { |
88 | char *name; /* entry name */ |
89 | jlong time; /* modification time */ |
90 | jlong size; /* size of uncompressed data */ |
91 | jlong csize; /* size of compressed data (zero if uncompressed) */ |
92 | jint crc; /* crc of uncompressed data */ |
93 | char *; /* optional zip file comment */ |
94 | jbyte *; /* optional extra data */ |
95 | jlong pos; /* position of LOC header (if negative) or data */ |
96 | } jzentry; |
97 | |
98 | class ClassPathZipEntry: public ClassPathEntry { |
99 | private: |
100 | jzfile* _zip; // The zip archive |
101 | const char* _zip_name; // Name of zip archive |
102 | public: |
103 | bool is_modules_image() const { return false; } |
104 | bool is_jar_file() const { return true; } |
105 | const char* name() const { return _zip_name; } |
106 | JImageFile* jimage() const { return NULL; } |
107 | void close_jimage() {} |
108 | ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append); |
109 | virtual ~ClassPathZipEntry(); |
110 | u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS); |
111 | ClassFileStream* open_stream(const char* name, TRAPS); |
112 | void contents_do(void f(const char* name, void* context), void* context); |
113 | }; |
114 | |
115 | |
116 | // For java image files |
117 | class ClassPathImageEntry: public ClassPathEntry { |
118 | private: |
119 | JImageFile* _jimage; |
120 | const char* _name; |
121 | DEBUG_ONLY(static ClassPathImageEntry* _singleton;) |
122 | public: |
123 | bool is_modules_image() const; |
124 | bool is_jar_file() const { return false; } |
125 | bool is_open() const { return _jimage != NULL; } |
126 | const char* name() const { return _name == NULL ? "" : _name; } |
127 | JImageFile* jimage() const { return _jimage; } |
128 | void close_jimage(); |
129 | ClassPathImageEntry(JImageFile* jimage, const char* name); |
130 | virtual ~ClassPathImageEntry(); |
131 | ClassFileStream* open_stream(const char* name, TRAPS); |
132 | ClassFileStream* open_stream_for_loader(const char* name, ClassLoaderData* loader_data, TRAPS); |
133 | }; |
134 | |
135 | // ModuleClassPathList contains a linked list of ClassPathEntry's |
136 | // that have been specified for a specific module. Currently, |
137 | // the only way to specify a module/path pair is via the --patch-module |
138 | // command line option. |
139 | class ModuleClassPathList : public CHeapObj<mtClass> { |
140 | private: |
141 | Symbol* _module_name; |
142 | // First and last entries of class path entries for a specific module |
143 | ClassPathEntry* _module_first_entry; |
144 | ClassPathEntry* _module_last_entry; |
145 | public: |
146 | Symbol* module_name() const { return _module_name; } |
147 | ClassPathEntry* module_first_entry() const { return _module_first_entry; } |
148 | ModuleClassPathList(Symbol* module_name); |
149 | ~ModuleClassPathList(); |
150 | void add_to_list(ClassPathEntry* new_entry); |
151 | }; |
152 | |
153 | class SharedPathsMiscInfo; |
154 | |
155 | class ClassLoader: AllStatic { |
156 | public: |
157 | enum ClassLoaderType { |
158 | BOOT_LOADER = 1, /* boot loader */ |
159 | PLATFORM_LOADER = 2, /* PlatformClassLoader */ |
160 | APP_LOADER = 3 /* AppClassLoader */ |
161 | }; |
162 | protected: |
163 | |
164 | // Performance counters |
165 | static PerfCounter* _perf_accumulated_time; |
166 | static PerfCounter* _perf_classes_inited; |
167 | static PerfCounter* _perf_class_init_time; |
168 | static PerfCounter* _perf_class_init_selftime; |
169 | static PerfCounter* _perf_classes_verified; |
170 | static PerfCounter* _perf_class_verify_time; |
171 | static PerfCounter* _perf_class_verify_selftime; |
172 | static PerfCounter* _perf_classes_linked; |
173 | static PerfCounter* _perf_class_link_time; |
174 | static PerfCounter* _perf_class_link_selftime; |
175 | static PerfCounter* _perf_class_parse_time; |
176 | static PerfCounter* _perf_class_parse_selftime; |
177 | static PerfCounter* _perf_sys_class_lookup_time; |
178 | static PerfCounter* _perf_shared_classload_time; |
179 | static PerfCounter* _perf_sys_classload_time; |
180 | static PerfCounter* _perf_app_classload_time; |
181 | static PerfCounter* _perf_app_classload_selftime; |
182 | static PerfCounter* _perf_app_classload_count; |
183 | static PerfCounter* _perf_define_appclasses; |
184 | static PerfCounter* _perf_define_appclass_time; |
185 | static PerfCounter* _perf_define_appclass_selftime; |
186 | static PerfCounter* _perf_app_classfile_bytes_read; |
187 | static PerfCounter* _perf_sys_classfile_bytes_read; |
188 | |
189 | static PerfCounter* _sync_systemLoaderLockContentionRate; |
190 | static PerfCounter* _sync_nonSystemLoaderLockContentionRate; |
191 | static PerfCounter* _sync_JVMFindLoadedClassLockFreeCounter; |
192 | static PerfCounter* _sync_JVMDefineClassLockFreeCounter; |
193 | static PerfCounter* _sync_JNIDefineClassLockFreeCounter; |
194 | |
195 | static PerfCounter* _unsafe_defineClassCallCounter; |
196 | |
197 | // The boot class path consists of 3 ordered pieces: |
198 | // 1. the module/path pairs specified to --patch-module |
199 | // --patch-module=<module>=<file>(<pathsep><file>)* |
200 | // 2. the base piece |
201 | // [jimage | build with exploded modules] |
202 | // 3. boot loader append path |
203 | // [-Xbootclasspath/a]; [jvmti appended entries] |
204 | // |
205 | // The boot loader must obey this order when attempting |
206 | // to load a class. |
207 | |
208 | // 1. Contains the module/path pairs specified to --patch-module |
209 | static GrowableArray<ModuleClassPathList*>* _patch_mod_entries; |
210 | |
211 | // 2. the base piece |
212 | // Contains the ClassPathEntry of the modular java runtime image. |
213 | // If no java runtime image is present, this indicates a |
214 | // build with exploded modules is being used instead. |
215 | static ClassPathEntry* _jrt_entry; |
216 | static GrowableArray<ModuleClassPathList*>* _exploded_entries; |
217 | enum { EXPLODED_ENTRY_SIZE = 80 }; // Initial number of exploded modules |
218 | |
219 | // 3. the boot loader's append path |
220 | // [-Xbootclasspath/a]; [jvmti appended entries] |
221 | // Note: boot loader append path does not support named modules. |
222 | static ClassPathEntry* _first_append_entry; |
223 | // Last entry in linked list of appended ClassPathEntry instances |
224 | static ClassPathEntry* _last_append_entry; |
225 | |
226 | // Info used by CDS |
227 | CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;) |
228 | |
229 | CDS_ONLY(static ClassPathEntry* _app_classpath_entries;) |
230 | CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;) |
231 | CDS_ONLY(static ClassPathEntry* _module_path_entries;) |
232 | CDS_ONLY(static ClassPathEntry* _last_module_path_entry;) |
233 | CDS_ONLY(static void setup_app_search_path(const char* class_path);) |
234 | CDS_ONLY(static void setup_module_search_path(const char* path, TRAPS);) |
235 | static void add_to_app_classpath_entries(const char* path, |
236 | ClassPathEntry* entry, |
237 | bool check_for_duplicates); |
238 | CDS_ONLY(static void add_to_module_path_entries(const char* path, |
239 | ClassPathEntry* entry);) |
240 | public: |
241 | CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;}) |
242 | CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;}) |
243 | |
244 | protected: |
245 | // Initialization: |
246 | // - setup the boot loader's system class path |
247 | // - setup the boot loader's patch mod entries, if present |
248 | // - create the ModuleEntry for java.base |
249 | static void setup_bootstrap_search_path(); |
250 | static void setup_boot_search_path(const char *class_path); |
251 | static void setup_patch_mod_entries(); |
252 | static void create_javabase(); |
253 | |
254 | static void load_zip_library(); |
255 | static void load_jimage_library(); |
256 | |
257 | public: |
258 | static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st, |
259 | bool throw_exception, |
260 | bool is_boot_append, TRAPS); |
261 | |
262 | // If the package for the fully qualified class name is in the boot |
263 | // loader's package entry table then add_package() sets the classpath_index |
264 | // field so that get_system_package() will know to return a non-null value |
265 | // for the package's location. And, so that the package will be added to |
266 | // the list of packages returned by get_system_packages(). |
267 | // For packages whose classes are loaded from the boot loader class path, the |
268 | // classpath_index indicates which entry on the boot loader class path. |
269 | static bool add_package(const char *fullq_class_name, s2 classpath_index, TRAPS); |
270 | |
271 | // Canonicalizes path names, so strcmp will work properly. This is mainly |
272 | // to avoid confusing the zip library |
273 | static bool get_canonical_path(const char* orig, char* out, int len); |
274 | static const char* file_name_for_class_name(const char* class_name, |
275 | int class_name_len); |
276 | static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS); |
277 | |
278 | public: |
279 | static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg); |
280 | static int crc32(int crc, const char* buf, int len); |
281 | static bool update_class_path_entry_list(const char *path, |
282 | bool check_for_duplicates, |
283 | bool is_boot_append, |
284 | bool throw_exception=true); |
285 | CDS_ONLY(static void update_module_path_entry_list(const char *path, TRAPS);) |
286 | static void print_bootclasspath(); |
287 | |
288 | // Timing |
289 | static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } |
290 | static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } |
291 | static PerfCounter* perf_class_init_time() { return _perf_class_init_time; } |
292 | static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; } |
293 | static PerfCounter* perf_classes_verified() { return _perf_classes_verified; } |
294 | static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } |
295 | static PerfCounter* perf_class_verify_selftime() { return _perf_class_verify_selftime; } |
296 | static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } |
297 | static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } |
298 | static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; } |
299 | static PerfCounter* perf_class_parse_time() { return _perf_class_parse_time; } |
300 | static PerfCounter* perf_class_parse_selftime() { return _perf_class_parse_selftime; } |
301 | static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; } |
302 | static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; } |
303 | static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; } |
304 | static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; } |
305 | static PerfCounter* perf_app_classload_selftime() { return _perf_app_classload_selftime; } |
306 | static PerfCounter* perf_app_classload_count() { return _perf_app_classload_count; } |
307 | static PerfCounter* perf_define_appclasses() { return _perf_define_appclasses; } |
308 | static PerfCounter* perf_define_appclass_time() { return _perf_define_appclass_time; } |
309 | static PerfCounter* perf_define_appclass_selftime() { return _perf_define_appclass_selftime; } |
310 | static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; } |
311 | static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; } |
312 | |
313 | // Record how often system loader lock object is contended |
314 | static PerfCounter* sync_systemLoaderLockContentionRate() { |
315 | return _sync_systemLoaderLockContentionRate; |
316 | } |
317 | |
318 | // Record how often non system loader lock object is contended |
319 | static PerfCounter* sync_nonSystemLoaderLockContentionRate() { |
320 | return _sync_nonSystemLoaderLockContentionRate; |
321 | } |
322 | |
323 | // Record how many calls to JVM_FindLoadedClass w/o holding a lock |
324 | static PerfCounter* sync_JVMFindLoadedClassLockFreeCounter() { |
325 | return _sync_JVMFindLoadedClassLockFreeCounter; |
326 | } |
327 | |
328 | // Record how many calls to JVM_DefineClass w/o holding a lock |
329 | static PerfCounter* sync_JVMDefineClassLockFreeCounter() { |
330 | return _sync_JVMDefineClassLockFreeCounter; |
331 | } |
332 | |
333 | // Record how many calls to jni_DefineClass w/o holding a lock |
334 | static PerfCounter* sync_JNIDefineClassLockFreeCounter() { |
335 | return _sync_JNIDefineClassLockFreeCounter; |
336 | } |
337 | |
338 | // Record how many calls to Unsafe_DefineClass |
339 | static PerfCounter* unsafe_defineClassCallCounter() { |
340 | return _unsafe_defineClassCallCounter; |
341 | } |
342 | |
343 | // Modular java runtime image is present vs. a build with exploded modules |
344 | static bool has_jrt_entry() { return (_jrt_entry != NULL); } |
345 | static ClassPathEntry* get_jrt_entry() { return _jrt_entry; } |
346 | static void close_jrt_image(); |
347 | |
348 | // Add a module's exploded directory to the boot loader's exploded module build list |
349 | static void add_to_exploded_build_list(Symbol* module_name, TRAPS); |
350 | |
351 | // Attempt load of individual class from either the patched or exploded modules build lists |
352 | static ClassFileStream* search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list, |
353 | const char* const class_name, |
354 | const char* const file_name, TRAPS); |
355 | |
356 | // Load individual .class file |
357 | static InstanceKlass* load_class(Symbol* class_name, bool search_append_only, TRAPS); |
358 | |
359 | // If the specified package has been loaded by the system, then returns |
360 | // the name of the directory or ZIP file that the package was loaded from. |
361 | // Returns null if the package was not loaded. |
362 | // Note: The specified name can either be the name of a class or package. |
363 | // If a package name is specified, then it must be "/"-separator and also |
364 | // end with a trailing "/". |
365 | static oop get_system_package(const char* name, TRAPS); |
366 | |
367 | // Returns an array of Java strings representing all of the currently |
368 | // loaded system packages. |
369 | // Note: The package names returned are "/"-separated and end with a |
370 | // trailing "/". |
371 | static objArrayOop get_system_packages(TRAPS); |
372 | |
373 | // Initialization |
374 | static void initialize(); |
375 | static void classLoader_init2(TRAPS); |
376 | CDS_ONLY(static void initialize_shared_path();) |
377 | CDS_ONLY(static void initialize_module_path(TRAPS);) |
378 | |
379 | static int compute_Object_vtable(); |
380 | |
381 | static ClassPathEntry* classpath_entry(int n); |
382 | |
383 | static bool is_in_patch_mod_entries(Symbol* module_name); |
384 | |
385 | #if INCLUDE_CDS |
386 | // Sharing dump and restore |
387 | |
388 | // Helper function used by CDS code to get the number of boot classpath |
389 | // entries during shared classpath setup time. |
390 | static int num_boot_classpath_entries(); |
391 | |
392 | static ClassPathEntry* get_next_boot_classpath_entry(ClassPathEntry* e); |
393 | |
394 | // Helper function used by CDS code to get the number of app classpath |
395 | // entries during shared classpath setup time. |
396 | static int num_app_classpath_entries(); |
397 | |
398 | // Helper function used by CDS code to get the number of module path |
399 | // entries during shared classpath setup time. |
400 | static int num_module_path_entries() { |
401 | assert(DumpSharedSpaces || DynamicDumpSharedSpaces, |
402 | "Should only be called at CDS dump time" ); |
403 | int num_entries = 0; |
404 | ClassPathEntry* e= ClassLoader::_module_path_entries; |
405 | while (e != NULL) { |
406 | num_entries ++; |
407 | e = e->next(); |
408 | } |
409 | return num_entries; |
410 | } |
411 | static void finalize_shared_paths_misc_info(); |
412 | static int get_shared_paths_misc_info_size(); |
413 | static void* get_shared_paths_misc_info(); |
414 | static bool check_shared_paths_misc_info(void* info, int size, bool is_static); |
415 | static void exit_with_path_failure(const char* error, const char* message); |
416 | static char* skip_uri_protocol(char* source); |
417 | static void record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS); |
418 | #endif |
419 | static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name, |
420 | const char* file_name, jlong &size); |
421 | |
422 | static void trace_class_path(const char* msg, const char* name = NULL); |
423 | |
424 | // VM monitoring and management support |
425 | static jlong classloader_time_ms(); |
426 | static jlong class_method_total_size(); |
427 | static jlong class_init_count(); |
428 | static jlong class_init_time_ms(); |
429 | static jlong class_verify_time_ms(); |
430 | static jlong class_link_count(); |
431 | static jlong class_link_time_ms(); |
432 | |
433 | // indicates if class path already contains a entry (exact match by name) |
434 | static bool contains_append_entry(const char* name); |
435 | |
436 | // adds a class path to the boot append entries |
437 | static void add_to_boot_append_entries(ClassPathEntry* new_entry); |
438 | |
439 | // creates a class path zip entry (returns NULL if JAR file cannot be opened) |
440 | static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append); |
441 | |
442 | static bool string_ends_with(const char* str, const char* str_to_find); |
443 | |
444 | // obtain package name from a fully qualified class name |
445 | // *bad_class_name is set to true if there's a problem with parsing class_name, to |
446 | // distinguish from a class_name with no package name, as both cases have a NULL return value |
447 | static const char* package_from_name(const char* const class_name, bool* bad_class_name = NULL); |
448 | |
449 | // Debugging |
450 | static void verify() PRODUCT_RETURN; |
451 | }; |
452 | |
453 | // PerfClassTraceTime is used to measure time for class loading related events. |
454 | // This class tracks cumulative time and exclusive time for specific event types. |
455 | // During the execution of one event, other event types (e.g. class loading and |
456 | // resolution) as well as recursive calls of the same event type could happen. |
457 | // Only one elapsed timer (cumulative) and one thread-local self timer (exclusive) |
458 | // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime |
459 | // instances have been created as multiple events are happening. |
460 | class PerfClassTraceTime { |
461 | public: |
462 | enum { |
463 | CLASS_LOAD = 0, |
464 | PARSE_CLASS = 1, |
465 | CLASS_LINK = 2, |
466 | CLASS_VERIFY = 3, |
467 | CLASS_CLINIT = 4, |
468 | DEFINE_CLASS = 5, |
469 | EVENT_TYPE_COUNT = 6 |
470 | }; |
471 | protected: |
472 | // _t tracks time from initialization to destruction of this timer instance |
473 | // including time for all other event types, and recursive calls of this type. |
474 | // When a timer is called recursively, the elapsedTimer _t would not be used. |
475 | elapsedTimer _t; |
476 | PerfLongCounter* _timep; |
477 | PerfLongCounter* _selftimep; |
478 | PerfLongCounter* _eventp; |
479 | // pointer to thread-local recursion counter and timer array |
480 | // The thread_local timers track cumulative time for specific event types |
481 | // exclusive of time for other event types, but including recursive calls |
482 | // of the same type. |
483 | int* _recursion_counters; |
484 | elapsedTimer* _timers; |
485 | int _event_type; |
486 | int _prev_active_event; |
487 | |
488 | public: |
489 | |
490 | inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ |
491 | PerfLongCounter* selftimep, /* counter incremented with exclusive time */ |
492 | PerfLongCounter* eventp, /* event counter */ |
493 | int* recursion_counters, /* thread-local recursion counter array */ |
494 | elapsedTimer* timers, /* thread-local timer array */ |
495 | int type /* event type */ ) : |
496 | _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) { |
497 | initialize(); |
498 | } |
499 | |
500 | inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ |
501 | elapsedTimer* timers, /* thread-local timer array */ |
502 | int type /* event type */ ) : |
503 | _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) { |
504 | initialize(); |
505 | } |
506 | |
507 | inline void suspend() { _t.stop(); _timers[_event_type].stop(); } |
508 | inline void resume() { _t.start(); _timers[_event_type].start(); } |
509 | |
510 | ~PerfClassTraceTime(); |
511 | void initialize(); |
512 | }; |
513 | |
514 | #endif // SHARE_CLASSFILE_CLASSLOADER_HPP |
515 | |