Wed, 27 Mar 2013 19:21:18 +0100
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
Summary: Ergonomics now also takes available virtual memory into account when deciding for a heap size. The helper method to determine the maximum allocatable memory block now uses the appropriate OS specific calls to retrieve available virtual memory for the java process. In 32 bit environments this method now also searches for the maximum actually reservable amount of memory. Merge previously separate implementations for Linux/BSD/Solaris into a single method.
Reviewed-by: jmasa, tamao
1 /*
2 * Copyright (c) 2005, 2012, 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 */
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "code/codeBlob.hpp"
28 #include "memory/allocation.hpp"
29 #include "prims/jvm.h"
30 #include "runtime/dtraceJSDT.hpp"
31 #include "runtime/jniHandles.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/signature.hpp"
34 #include "utilities/globalDefinitions.hpp"
36 #ifdef HAVE_DTRACE_H
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <dtrace.h>
44 static const char* devname = "/dev/dtrace/helper";
45 static const char* olddevname = "/devices/pseudo/dtrace@0:helper";
47 static const char* string_sig = "uintptr_t";
48 static const char* int_sig = "long";
49 static const char* long_sig = "long long";
51 static void printDOFHelper(dof_helper_t* helper);
53 static int dofhelper_open() {
54 int fd;
55 if ((fd = open64(devname, O_RDWR)) < 0) {
56 // Optimize next calls
57 devname = olddevname;
58 if ((fd = open64(devname, O_RDWR)) < 0) {
59 return -1;
60 }
61 }
62 return fd;
63 }
65 static jint dof_register(jstring module, uint8_t* dof, void* modaddr) {
66 int probe;
67 dof_helper_t dh;
68 int fd;
70 memset(&dh, 0, sizeof(dh));
72 char* module_name = java_lang_String::as_utf8_string(
73 JNIHandles::resolve_non_null(module));
74 jio_snprintf(dh.dofhp_mod, sizeof(dh.dofhp_mod), "%s", module_name);
75 dh.dofhp_dof = (uint64_t)dof;
76 dh.dofhp_addr = (uint64_t)modaddr;
78 fd = dofhelper_open();
79 if (fd < 0)
80 return -1;
81 probe = ioctl(fd, DTRACEHIOC_ADDDOF, &dh);
82 close(fd);
83 if (PrintDTraceDOF) {
84 printDOFHelper(&dh);
85 tty->print_cr("DOF helper id = %d", probe);
86 }
87 return probe;
88 }
90 int DTraceJSDT::pd_activate(
91 void* moduleBaseAddress, jstring module,
92 jint providers_count, JVM_DTraceProvider* providers) {
94 // We need sections:
95 // (1) STRTAB
96 // (
97 // (2) PROVIDER
98 // (3) PROBES
99 // (4) PROBOFFS
100 // (5) PROBARGS
101 // ) * Number of Providers
103 // Type of sections we create
104 enum {
105 STRTAB = 0,
106 PROVIDERS = 1,
107 PROBES = 2,
108 PROBE_OFFSETS = 3,
109 ARG_OFFSETS = 4,
110 NUM_SECTIONS = 5
111 };
113 static int alignment_for[NUM_SECTIONS] = { 1, 4, 8, 4, 1 };
115 ResourceMark rm;
117 uint32_t num_sections = 1 + 4 * providers_count;
118 uint32_t offset = sizeof(dof_hdr_t) + (num_sections * sizeof(dof_sec_t));
119 uint32_t* secoffs = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
120 uint32_t* secsize = NEW_RESOURCE_ARRAY(uint32_t, num_sections);
122 // Store offsets of all strings here in such order:
123 // zero-string (always 0)
124 // provider1-name
125 // probe1-function
126 // probe1-name
127 // arg-1
128 // arg-2
129 // ...
130 // probe2-function
131 // probe2-name
132 // arg-1
133 // arg-2
134 // provider2-name
135 // ...
137 uint32_t strcount = 0;
138 // Count the number of strings we'll need
139 for(int prvc = 0; prvc < providers_count; ++prvc) {
140 JVM_DTraceProvider* provider = &providers[prvc];
141 // Provider name
142 ++strcount;
143 for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
144 JVM_DTraceProbe* p = &(provider->probes[prbc]);
145 Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
146 // function + name + one per argument
147 strcount += 2 + ArgumentCount(sig).size();
148 }
149 }
151 // Create place for string offsets
152 uint32_t* stroffs = NEW_RESOURCE_ARRAY(uint32_t, strcount + 1);
153 uint32_t string_index = 0;
154 uint32_t curstr = 0;
156 // First we need an empty string: ""
157 stroffs[curstr++] = string_index;
158 string_index += strlen("") + 1;
160 for(int prvc = 0; prvc < providers_count; ++prvc) {
161 JVM_DTraceProvider* provider = &providers[prvc];
162 char* provider_name = java_lang_String::as_utf8_string(
163 JNIHandles::resolve_non_null(provider->name));
164 stroffs[curstr++] = string_index;
165 string_index += strlen(provider_name) + 1;
167 // All probes
168 for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
169 JVM_DTraceProbe* p = &(provider->probes[prbc]);
171 char* function = java_lang_String::as_utf8_string(
172 JNIHandles::resolve_non_null(p->function));
173 stroffs[curstr++] = string_index;
174 string_index += strlen(function) + 1;
176 char* name = java_lang_String::as_utf8_string(
177 JNIHandles::resolve_non_null(p->name));
178 stroffs[curstr++] = string_index;
179 string_index += strlen(name) + 1;
181 Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
182 SignatureStream ss(sig);
183 for ( ; !ss.at_return_type(); ss.next()) {
184 BasicType bt = ss.type();
185 const char* t = NULL;
186 if (bt == T_OBJECT &&
187 ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
188 t = string_sig;
189 } else if (bt == T_LONG) {
190 t = long_sig;
191 } else {
192 t = int_sig;
193 }
194 stroffs[curstr++] = string_index;
195 string_index += strlen(t) + 1;
196 }
197 }
198 }
199 secoffs[STRTAB] = offset;
200 secsize[STRTAB] = string_index;
201 offset += string_index;
203 // Calculate the size of the rest
204 for(int prvc = 0; prvc < providers_count; ++prvc) {
205 JVM_DTraceProvider* provider = &providers[prvc];
206 size_t provider_sec = PROVIDERS + prvc * 4;
207 size_t probe_sec = PROBES + prvc * 4;
208 size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
209 size_t argoffs_sec = ARG_OFFSETS + prvc * 4;
211 // Allocate space for the provider data struction
212 secoffs[provider_sec] = align_size_up(offset, alignment_for[PROVIDERS]);
213 secsize[provider_sec] = sizeof(dof_provider_t);
214 offset = secoffs[provider_sec] + secsize[provider_sec];
216 // Allocate space for all the probes
217 secoffs[probe_sec] = align_size_up(offset, alignment_for[PROBES]);
218 secsize[probe_sec] = sizeof(dof_probe_t) * provider->probe_count;
219 offset = secoffs[probe_sec] + secsize[probe_sec];
221 // Allocate space for the probe offsets
222 secoffs[probeoffs_sec] = align_size_up(offset, alignment_for[PROBE_OFFSETS]);
223 secsize[probeoffs_sec] = sizeof(uint32_t) * provider->probe_count;
224 offset = secoffs[probeoffs_sec] + secsize[probeoffs_sec];
226 // We need number of arguments argoffs
227 uint32_t argscount = 0;
228 for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
229 JVM_DTraceProbe* p = &(provider->probes[prbc]);
230 Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
231 argscount += ArgumentCount(sig).size();
232 }
233 secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
234 secsize[argoffs_sec] = sizeof(uint8_t) * argscount;
235 offset = secoffs[argoffs_sec] + secsize[argoffs_sec];
236 }
238 uint32_t size = offset;
240 uint8_t* dof = NEW_RESOURCE_ARRAY(uint8_t, size);
241 if (!dof) {
242 return -1;
243 }
244 memset((void*)dof, 0, size);
246 // Fill memory with proper values
247 dof_hdr_t* hdr = (dof_hdr_t*)dof;
248 hdr->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
249 hdr->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
250 hdr->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
251 hdr->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
252 hdr->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE; // No variants
253 hdr->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; // No variants
254 hdr->dofh_ident[DOF_ID_VERSION] = DOF_VERSION_1; // No variants
255 hdr->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION_2; // No variants
256 // all other fields of ident to zero
258 hdr->dofh_flags = 0;
259 hdr->dofh_hdrsize = sizeof(dof_hdr_t);
260 hdr->dofh_secsize = sizeof(dof_sec_t);
261 hdr->dofh_secnum = num_sections;
262 hdr->dofh_secoff = sizeof(dof_hdr_t);
263 hdr->dofh_loadsz = size;
264 hdr->dofh_filesz = size;
266 // First section: STRTAB
267 dof_sec_t* sec = (dof_sec_t*)(dof + sizeof(dof_hdr_t));
268 sec->dofs_type = DOF_SECT_STRTAB;
269 sec->dofs_align = alignment_for[STRTAB];
270 sec->dofs_flags = DOF_SECF_LOAD;
271 sec->dofs_entsize = 0;
272 sec->dofs_offset = secoffs[STRTAB];
273 sec->dofs_size = secsize[STRTAB];
274 // Make data for this section
275 char* str = (char*)(dof + sec->dofs_offset);
277 *str = 0; str += 1; // ""
279 // Run through all strings again
280 for(int prvc = 0; prvc < providers_count; ++prvc) {
281 JVM_DTraceProvider* provider = &providers[prvc];
282 char* provider_name = java_lang_String::as_utf8_string(
283 JNIHandles::resolve_non_null(provider->name));
284 strcpy(str, provider_name);
285 str += strlen(provider_name) + 1;
287 // All probes
288 for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
289 JVM_DTraceProbe* p = &(provider->probes[prbc]);
291 char* function = java_lang_String::as_utf8_string(
292 JNIHandles::resolve_non_null(p->function));
293 strcpy(str, function);
294 str += strlen(str) + 1;
296 char* name = java_lang_String::as_utf8_string(
297 JNIHandles::resolve_non_null(p->name));
298 strcpy(str, name);
299 str += strlen(name) + 1;
301 Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
302 SignatureStream ss(sig);
303 for ( ; !ss.at_return_type(); ss.next()) {
304 BasicType bt = ss.type();
305 const char* t;
306 if (bt == T_OBJECT &&
307 ss.as_symbol_or_null() == vmSymbols::java_lang_String()) {
308 t = string_sig;
309 } else if (bt == T_LONG) {
310 t = long_sig;
311 } else {
312 t = int_sig;
313 }
314 strcpy(str, t);
315 str += strlen(t) + 1;
316 }
317 }
318 }
320 curstr = 1;
321 for(int prvc = 0; prvc < providers_count; ++prvc) {
322 JVM_DTraceProvider* provider = &providers[prvc];
323 size_t provider_sec = PROVIDERS + prvc * 4;
324 size_t probe_sec = PROBES + prvc * 4;
325 size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4;
326 size_t argoffs_sec = ARG_OFFSETS + prvc * 4;
328 // PROVIDER ///////////////////////////////////////////////////////////////
329 // Section header
330 sec = (dof_sec_t*)
331 (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * provider_sec);
332 sec->dofs_type = DOF_SECT_PROVIDER;
333 sec->dofs_align = alignment_for[PROVIDERS];
334 sec->dofs_flags = DOF_SECF_LOAD;
335 sec->dofs_entsize = 0;
336 sec->dofs_offset = secoffs[provider_sec];
337 sec->dofs_size = secsize[provider_sec];
338 // Make provider decriiption
339 dof_provider_t* prv = (dof_provider_t*)(dof + sec->dofs_offset);
340 prv->dofpv_strtab = STRTAB;
341 prv->dofpv_probes = probe_sec;
342 prv->dofpv_prargs = argoffs_sec;
343 prv->dofpv_proffs = probeoffs_sec;
344 prv->dofpv_name = stroffs[curstr++]; // Index in string table
345 prv->dofpv_provattr = DOF_ATTR(
346 provider->providerAttributes.nameStability,
347 provider->providerAttributes.dataStability,
348 provider->providerAttributes.dependencyClass);
349 prv->dofpv_modattr = DOF_ATTR(
350 provider->moduleAttributes.nameStability,
351 provider->moduleAttributes.dataStability,
352 provider->moduleAttributes.dependencyClass);
353 prv->dofpv_funcattr = DOF_ATTR(
354 provider->functionAttributes.nameStability,
355 provider->functionAttributes.dataStability,
356 provider->functionAttributes.dependencyClass);
357 prv->dofpv_nameattr = DOF_ATTR(
358 provider->nameAttributes.nameStability,
359 provider->nameAttributes.dataStability,
360 provider->nameAttributes.dependencyClass);
361 prv->dofpv_argsattr = DOF_ATTR(
362 provider->argsAttributes.nameStability,
363 provider->argsAttributes.dataStability,
364 provider->argsAttributes.dependencyClass);
366 // PROBES /////////////////////////////////////////////////////////////////
367 // Section header
368 sec = (dof_sec_t*)
369 (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probe_sec);
370 sec->dofs_type = DOF_SECT_PROBES;
371 sec->dofs_align = alignment_for[PROBES];
372 sec->dofs_flags = DOF_SECF_LOAD;
373 sec->dofs_entsize = sizeof(dof_probe_t);
374 sec->dofs_offset = secoffs[probe_sec];
375 sec->dofs_size = secsize[probe_sec];
376 // Make probes descriptions
377 uint32_t argsoffs = 0;
378 for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
379 JVM_DTraceProbe* probe = &(provider->probes[prbc]);
380 Method* m = Method::resolve_jmethod_id(probe->method);
381 int arg_count = ArgumentCount(m->signature()).size();
382 assert(m->code() != NULL, "must have an nmethod");
384 dof_probe_t* prb =
385 (dof_probe_t*)(dof + sec->dofs_offset + prbc * sizeof(dof_probe_t));
387 prb->dofpr_addr = (uint64_t)m->code()->entry_point();
388 prb->dofpr_func = stroffs[curstr++]; // Index in string table
389 prb->dofpr_name = stroffs[curstr++]; // Index in string table
390 prb->dofpr_nargv = stroffs[curstr ]; // Index in string table
391 // We spent siglen strings here
392 curstr += arg_count;
393 prb->dofpr_xargv = prb->dofpr_nargv; // Same bunch of strings
394 prb->dofpr_argidx = argsoffs;
395 prb->dofpr_offidx = prbc;
396 prb->dofpr_nargc = arg_count;
397 prb->dofpr_xargc = arg_count;
398 prb->dofpr_noffs = 1; // Number of offsets
399 // Next bunch of offsets
400 argsoffs += arg_count;
401 }
403 // PROFFS /////////////////////////////////////////////////////////////////
404 // Section header
405 sec = (dof_sec_t*)
406 (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probeoffs_sec);
407 sec->dofs_type = DOF_SECT_PROFFS;
408 sec->dofs_align = alignment_for[PROBE_OFFSETS];
409 sec->dofs_flags = DOF_SECF_LOAD;
410 sec->dofs_entsize = sizeof(uint32_t);
411 sec->dofs_offset = secoffs[probeoffs_sec];
412 sec->dofs_size = secsize[probeoffs_sec];
413 // Make offsets
414 for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
415 uint32_t* pof =
416 (uint32_t*)(dof + sec->dofs_offset + sizeof(uint32_t) * prbc);
417 JVM_DTraceProbe* probe = &(provider->probes[prbc]);
418 Method* m = Method::resolve_jmethod_id(probe->method);
419 *pof = m->code()->trap_offset();
420 }
422 // PRARGS /////////////////////////////////////////////////////////////////
423 // Section header
424 sec = (dof_sec_t*)
425 (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * argoffs_sec);
426 sec->dofs_type = DOF_SECT_PRARGS;
427 sec->dofs_align = alignment_for[ARG_OFFSETS];
428 sec->dofs_flags = DOF_SECF_LOAD;
429 sec->dofs_entsize = sizeof(uint8_t);
430 sec->dofs_offset = secoffs[argoffs_sec];
431 sec->dofs_size = secsize[argoffs_sec];
432 // Make arguments
433 uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
434 for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
435 JVM_DTraceProbe* p = &(provider->probes[prbc]);
436 Symbol* sig = Method::resolve_jmethod_id(p->method)->signature();
437 uint8_t count = (uint8_t)ArgumentCount(sig).size();
438 for (uint8_t i = 0; i < count; ++i) {
439 *par++ = i;
440 }
441 }
442 }
444 // Register module
445 return dof_register(module, dof, moduleBaseAddress);
446 }
449 void DTraceJSDT::pd_dispose(int handle) {
450 int fd;
451 if (handle == -1) {
452 return;
453 }
454 fd = dofhelper_open();
455 if (fd < 0)
456 return;
457 ioctl(fd, DTRACEHIOC_REMOVE, handle);
458 close(fd);
459 }
461 jboolean DTraceJSDT::pd_is_supported() {
462 int fd = dofhelper_open();
463 if (fd < 0) {
464 return false;
465 }
466 close(fd);
467 return true;
468 }
470 static const char* dofSecTypeFor(uint32_t type) {
471 switch (type) {
472 case 0: return "DOF_SECT_NONE";
473 case 1: return "DOF_SECT_COMMENTS";
474 case 2: return "DOF_SECT_SOURCE";
475 case 3: return "DOF_SECT_ECBDESC";
476 case 4: return "DOF_SECT_PROBEDESC";
477 case 5: return "DOF_SECT_ACTDESC";
478 case 6: return "DOF_SECT_DIFOHDR";
479 case 7: return "DOF_SECT_DIF";
480 case 8: return "DOF_SECT_STRTAB";
481 case 9: return "DOF_SECT_VARTAB";
482 case 10: return "DOF_SECT_RELTAB";
483 case 11: return "DOF_SECT_TYPETAB";
484 case 12: return "DOF_SECT_URELHDR";
485 case 13: return "DOF_SECT_KRELHDR";
486 case 14: return "DOF_SECT_OPTDESC";
487 case 15: return "DOF_SECT_PROVIDER";
488 case 16: return "DOF_SECT_PROBES";
489 case 17: return "DOF_SECT_PRARGS";
490 case 18: return "DOF_SECT_PROFFS";
491 case 19: return "DOF_SECT_INTTAB";
492 case 20: return "DOF_SECT_UTSNAME";
493 case 21: return "DOF_SECT_XLTAB";
494 case 22: return "DOF_SECT_XLMEMBERS";
495 case 23: return "DOF_SECT_XLIMPORT";
496 case 24: return "DOF_SECT_XLEXPORT";
497 case 25: return "DOF_SECT_PREXPORT";
498 case 26: return "DOF_SECT_PRENOFFS";
499 default: return "<unknown>";
500 }
501 }
503 static void printDOFStringTabSec(void* dof, dof_sec_t* sec) {
504 size_t tab = sec->dofs_offset;
505 size_t limit = sec->dofs_size;
506 tty->print_cr("// String Table:");
507 for (size_t idx = 0; idx < limit; /*empty*/) {
508 char* str = ((char*)dof) + tab + idx;
509 tty->print_cr("// [0x%x + 0x%x] '%s'", tab, idx, str);
510 idx += strlen(str) + 1;
511 }
512 }
514 static void printDOFProviderSec(void* dof, dof_sec_t* sec) {
515 dof_provider_t* prov = (dof_provider_t*)((char*)dof + sec->dofs_offset);
516 tty->print_cr("// dof_provider_t {");
517 tty->print_cr("// dofpv_strtab = %d", prov->dofpv_strtab);
518 tty->print_cr("// dofpv_probes = %d", prov->dofpv_probes);
519 tty->print_cr("// dofpv_prargs = %d", prov->dofpv_prargs);
520 tty->print_cr("// dofpv_proffs = %d", prov->dofpv_proffs);
521 tty->print_cr("// dofpv_name = 0x%x", prov->dofpv_name);
522 tty->print_cr("// dofpv_provattr = 0x%08x", prov->dofpv_provattr);
523 tty->print_cr("// dofpv_modattr = 0x%08x", prov->dofpv_modattr);
524 tty->print_cr("// dofpv_funcattr = 0x%08x", prov->dofpv_funcattr);
525 tty->print_cr("// dofpv_nameattr = 0x%08x", prov->dofpv_nameattr);
526 tty->print_cr("// dofpv_argsattr = 0x%08x", prov->dofpv_argsattr);
527 tty->print_cr("// }");
528 }
530 static void printDOFProbesSec(void* dof, dof_sec_t* sec) {
531 size_t idx = sec->dofs_offset;
532 size_t limit = idx + sec->dofs_size;
533 for (size_t idx = sec->dofs_offset; idx < limit; idx += sec->dofs_entsize) {
534 dof_probe_t* prb = (dof_probe_t*)((char*)dof + idx);
535 tty->print_cr("// dof_probe_t {");
536 tty->print_cr("// dofpr_addr = 0x%016llx", prb->dofpr_addr);
537 tty->print_cr("// dofpr_func = 0x%x", prb->dofpr_func);
538 tty->print_cr("// dofpr_name = 0x%x", prb->dofpr_name);
539 tty->print_cr("// dofpr_nargv = 0x%x", prb->dofpr_nargv);
540 tty->print_cr("// dofpr_xargv = 0x%x", prb->dofpr_xargv);
541 tty->print_cr("// dofpr_argidx = 0x%x", prb->dofpr_argidx);
542 tty->print_cr("// dofpr_offidx = 0x%x", prb->dofpr_offidx);
543 tty->print_cr("// dofpr_nargc = %d", prb->dofpr_nargc);
544 tty->print_cr("// dofpr_xargc = %d", prb->dofpr_xargc);
545 tty->print_cr("// dofpr_noffs = %d", prb->dofpr_noffs);
546 tty->print_cr("// }");
547 }
548 }
550 static void printDOFOffsetsSec(void* dof, dof_sec_t* sec) {
551 size_t tab = sec->dofs_offset;
552 size_t limit = sec->dofs_size;
553 tty->print_cr("// Offsets:");
554 for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
555 uint32_t* off = (uint32_t*)((char*)dof + tab + idx);
556 tty->print_cr("// [0x%x + 0x%x]: %d", tab, idx, *off);
557 }
558 }
560 static void printDOFArgsSec(void* dof, dof_sec_t* sec) {
561 size_t tab = sec->dofs_offset;
562 size_t limit = sec->dofs_size;
563 tty->print_cr("// Arguments:");
564 for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) {
565 uint8_t* arg = (uint8_t*)((char*)dof + tab + idx);
566 tty->print_cr("// [0x%x + 0x%x]: %d", tab, idx, *arg);
567 }
568 }
570 static void printDOFSection(void* dof, dof_sec_t* sec) {
571 tty->print_cr("// dof_sec_t {");
572 tty->print_cr("// dofs_type = 0x%x /* %s */",
573 sec->dofs_type, dofSecTypeFor(sec->dofs_type));
574 tty->print_cr("// dofs_align = %d", sec->dofs_align);
575 tty->print_cr("// dofs_flags = 0x%x", sec->dofs_flags);
576 tty->print_cr("// dofs_entsize = %d", sec->dofs_entsize);
577 tty->print_cr("// dofs_offset = 0x%llx", sec->dofs_offset);
578 tty->print_cr("// dofs_size = %lld", sec->dofs_size);
579 tty->print_cr("// }");
580 switch (sec->dofs_type) {
581 case DOF_SECT_STRTAB: printDOFStringTabSec(dof, sec); break;
582 case DOF_SECT_PROVIDER: printDOFProviderSec(dof, sec); break;
583 case DOF_SECT_PROBES: printDOFProbesSec(dof, sec); break;
584 case DOF_SECT_PROFFS: printDOFOffsetsSec(dof, sec); break;
585 case DOF_SECT_PRARGS: printDOFArgsSec(dof, sec); break;
586 default: tty->print_cr("// <section type not recognized>");
587 }
588 }
590 static void printDOFHeader(dof_hdr_t* hdr) {
591 tty->print_cr("// dof_hdr_t {");
592 tty->print_cr("// dofh_ident[DOF_ID_MAG0] = 0x%x",
593 hdr->dofh_ident[DOF_ID_MAG0]);
594 tty->print_cr("// dofh_ident[DOF_ID_MAG1] = 0x%x",
595 hdr->dofh_ident[DOF_ID_MAG1]);
596 tty->print_cr("// dofh_ident[DOF_ID_MAG2] = 0x%x",
597 hdr->dofh_ident[DOF_ID_MAG2]);
598 tty->print_cr("// dofh_ident[DOF_ID_MAG3] = 0x%x",
599 hdr->dofh_ident[DOF_ID_MAG3]);
600 tty->print_cr("// dofh_ident[DOF_ID_MODEL] = 0x%x",
601 hdr->dofh_ident[DOF_ID_MODEL]);
602 tty->print_cr("// dofh_ident[DOF_ID_ENCODING] = 0x%x",
603 hdr->dofh_ident[DOF_ID_ENCODING]);
604 tty->print_cr("// dofh_ident[DOF_ID_VERSION] = 0x%x",
605 hdr->dofh_ident[DOF_ID_VERSION]);
606 tty->print_cr("// dofh_ident[DOF_ID_DIFVERS] = 0x%x",
607 hdr->dofh_ident[DOF_ID_DIFVERS]);
608 tty->print_cr("// dofh_flags = 0x%x", hdr->dofh_flags);
609 tty->print_cr("// dofh_hdrsize = %d", hdr->dofh_hdrsize);
610 tty->print_cr("// dofh_secsize = %d", hdr->dofh_secsize);
611 tty->print_cr("// dofh_secnum = %d", hdr->dofh_secnum);
612 tty->print_cr("// dofh_secoff = %lld", hdr->dofh_secoff);
613 tty->print_cr("// dofh_loadsz = %lld", hdr->dofh_loadsz);
614 tty->print_cr("// dofh_filesz = %lld", hdr->dofh_filesz);
615 tty->print_cr("// }");
616 }
618 static void printDOF(void* dof) {
619 dof_hdr_t* hdr = (dof_hdr_t*)dof;
620 printDOFHeader(hdr);
621 for (int i = 0; i < hdr->dofh_secnum; ++i) {
622 dof_sec_t* sec =
623 (dof_sec_t*)((char*)dof + sizeof(dof_hdr_t) + i * sizeof(dof_sec_t));
624 tty->print_cr("// [Section #%d]", i);
625 printDOFSection(dof, sec);
626 }
627 }
629 static void printDOFHelper(dof_helper_t* helper) {
630 tty->print_cr("// dof_helper_t {");
631 tty->print_cr("// dofhp_mod = \"%s\"", helper->dofhp_mod);
632 tty->print_cr("// dofhp_addr = 0x%016llx", helper->dofhp_addr);
633 tty->print_cr("// dofhp_dof = 0x%016llx", helper->dofhp_dof);
634 printDOF((void*)helper->dofhp_dof);
635 tty->print_cr("// }");
636 size_t len = ((dof_hdr_t*)helper)->dofh_loadsz;
637 tty->print_data((void*)helper->dofhp_dof, len, true);
638 }
640 #else // ndef HAVE_DTRACE_H
642 // Get here if we're not building on at least Solaris 10
643 int DTraceJSDT::pd_activate(
644 void* baseAddress, jstring module,
645 jint provider_count, JVM_DTraceProvider* providers) {
646 return -1;
647 }
649 void DTraceJSDT::pd_dispose(int handle) {
650 }
652 jboolean DTraceJSDT::pd_is_supported() {
653 return false;
654 }
655 #endif