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

     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

mercurial