src/os/solaris/vm/dtraceJSDT_solaris.cpp

Wed, 27 Mar 2013 19:21:18 +0100

author
tschatzl
date
Wed, 27 Mar 2013 19:21:18 +0100
changeset 4854
754c24457b20
parent 4037
da91efe96a93
child 6876
710a3c8b516e
permissions
-rw-r--r--

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

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

mercurial