1 /*
   2  * Copyright (c) 2003, 2011, 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 /* This file is auto-generated */
  26 #include "JvmOffsetsIndex.h"
  27 
  28 #define DEBUG
  29 
  30 #ifdef DEBUG
  31 #define MARK_LINE this->line = __LINE__
  32 #else
  33 #define MARK_LINE 
  34 #endif
  35 
  36 #ifdef _LP64
  37 #define STACK_BIAS 0x7ff
  38 #define pointer uint64_t
  39 #else
  40 #define STACK_BIAS 0
  41 #define pointer uint32_t
  42 #endif
  43 
  44 extern pointer __JvmOffsets;
  45 
  46 extern pointer __1cJCodeCacheF_heap_;
  47 extern pointer __1cIUniverseP_methodKlassObj_;
  48 extern pointer __1cIUniverseO_collectedHeap_;
  49 extern pointer __1cIUniverseL_narrow_oop_;
  50 #ifdef _LP64
  51 extern pointer UseCompressedOops;
  52 #endif
  53 
  54 extern pointer __1cHnmethodG__vtbl_;
  55 extern pointer __1cKBufferBlobG__vtbl_;
  56 
  57 #define copyin_ptr(ADDR)    *(pointer*)  copyin((pointer) (ADDR), sizeof(pointer))
  58 #define copyin_uchar(ADDR)  *(uchar_t*)  copyin((pointer) (ADDR), sizeof(uchar_t))
  59 #define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t))
  60 #define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t))
  61 #define copyin_int32(ADDR)  *(int32_t*)  copyin((pointer) (ADDR), sizeof(int32_t))
  62 #define copyin_uint8(ADDR)  *(uint8_t*)  copyin((pointer) (ADDR), sizeof(uint8_t))
  63 
  64 #define SAME(x) x
  65 #define copyin_offset(JVM_CONST)  JVM_CONST = \
  66         copyin_int32(JvmOffsetsPtr + SAME(IDX_)JVM_CONST * sizeof(int32_t))
  67 
  68 int init_done;
  69 
  70 dtrace:helper:ustack:
  71 {
  72   MARK_LINE;
  73   this->done = 0;
  74   /*
  75    * TBD:
  76    * Here we initialize init_done, otherwise jhelper does not work.
  77    * Therefore, copyin_offset() statements work multiple times now.
  78    * There is a hope we could avoid it in the future, and so,
  79    * this initialization can be removed.
  80    */
  81   init_done  = 0;
  82   this->error = (char *) NULL;
  83   this->result = (char *) NULL;
  84   this->methodOop = 0;
  85   this->codecache = 0;
  86   this->klass = (pointer) NULL;
  87   this->vtbl  = (pointer) NULL;
  88   this->suffix = '\0';
  89 }
  90 
  91 dtrace:helper:ustack:
  92 {
  93   MARK_LINE;
  94   /* Initialization of JvmOffsets constants */
  95   JvmOffsetsPtr = (pointer) &``__JvmOffsets;
  96 }
  97 
  98 dtrace:helper:ustack:
  99 /!init_done && !this->done/
 100 {
 101   MARK_LINE;
 102   init_done = 1;
 103 
 104   copyin_offset(COMPILER);
 105   copyin_offset(OFFSET_CollectedHeap_reserved);
 106   copyin_offset(OFFSET_MemRegion_start);
 107   copyin_offset(OFFSET_MemRegion_word_size);
 108   copyin_offset(SIZE_HeapWord);
 109 
 110   copyin_offset(OFFSET_interpreter_frame_method);
 111   copyin_offset(OFFSET_Klass_name);
 112   copyin_offset(OFFSET_constantPoolOopDesc_pool_holder);
 113 
 114   copyin_offset(OFFSET_HeapBlockHeader_used);
 115   copyin_offset(OFFSET_oopDesc_metadata);
 116 
 117   copyin_offset(OFFSET_Symbol_length);
 118   copyin_offset(OFFSET_Symbol_body);
 119 
 120   copyin_offset(OFFSET_methodOopDesc_constMethod);
 121   copyin_offset(OFFSET_methodOopDesc_constants);
 122   copyin_offset(OFFSET_constMethodOopDesc_name_index);
 123   copyin_offset(OFFSET_constMethodOopDesc_signature_index);
 124 
 125   copyin_offset(OFFSET_CodeHeap_memory);
 126   copyin_offset(OFFSET_CodeHeap_segmap);
 127   copyin_offset(OFFSET_CodeHeap_log2_segment_size);
 128 
 129   copyin_offset(OFFSET_VirtualSpace_low);
 130   copyin_offset(OFFSET_VirtualSpace_high);
 131 
 132   copyin_offset(OFFSET_CodeBlob_name);
 133 
 134   copyin_offset(OFFSET_nmethod_method);
 135   copyin_offset(SIZE_HeapBlockHeader);
 136   copyin_offset(SIZE_oopDesc);
 137   copyin_offset(SIZE_constantPoolOopDesc);
 138 
 139   copyin_offset(OFFSET_NarrowOopStruct_base);
 140   copyin_offset(OFFSET_NarrowOopStruct_shift);
 141 
 142   /*
 143    * The PC to translate is in arg0.
 144    */
 145   this->pc = arg0;
 146 
 147   /*
 148    * The methodOopPtr is in %l2 on SPARC.  This can be found at
 149    * offset 8 from the frame pointer on 32-bit processes.
 150    */
 151 #if   defined(__sparc)
 152   this->methodOopPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
 153 #elif defined(__i386) || defined(__amd64)
 154   this->methodOopPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
 155 #else
 156 #error "Don't know architecture"
 157 #endif
 158 
 159   this->Universe_methodKlassOop = copyin_ptr(&``__1cIUniverseP_methodKlassObj_);
 160   this->CodeCache_heap_address = copyin_ptr(&``__1cJCodeCacheF_heap_);
 161 
 162   /* Reading volatile values */
 163 #ifdef _LP64
 164   this->Use_Compressed_Oops  = copyin_uint8(&``UseCompressedOops);
 165 #else
 166   this->Use_Compressed_Oops  = 0;
 167 #endif
 168 
 169   this->Universe_narrow_oop_base  = copyin_ptr(&``__1cIUniverseL_narrow_oop_ +
 170                                                OFFSET_NarrowOopStruct_base);
 171   this->Universe_narrow_oop_shift = copyin_int32(&``__1cIUniverseL_narrow_oop_ +
 172                                                  OFFSET_NarrowOopStruct_shift);
 173 
 174   this->CodeCache_low = copyin_ptr(this->CodeCache_heap_address + 
 175       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
 176 
 177   this->CodeCache_high = copyin_ptr(this->CodeCache_heap_address +
 178       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
 179 
 180   this->CodeCache_segmap_low = copyin_ptr(this->CodeCache_heap_address +
 181       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
 182 
 183   this->CodeCache_segmap_high = copyin_ptr(this->CodeCache_heap_address +
 184       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_high);
 185 
 186   this->CodeHeap_log2_segment_size = copyin_uint32(
 187       this->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size);
 188 
 189   /*
 190    * Get Java heap bounds
 191    */
 192   this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
 193   this->heap_start = copyin_ptr(this->Universe_collectedHeap +
 194       OFFSET_CollectedHeap_reserved +
 195       OFFSET_MemRegion_start);
 196   this->heap_size = SIZE_HeapWord *
 197     copyin_ptr(this->Universe_collectedHeap +
 198         OFFSET_CollectedHeap_reserved +
 199         OFFSET_MemRegion_word_size
 200         );
 201   this->heap_end = this->heap_start + this->heap_size;
 202 }
 203 
 204 dtrace:helper:ustack:
 205 /!this->done &&
 206 this->CodeCache_low <= this->pc && this->pc < this->CodeCache_high/
 207 {
 208   MARK_LINE;
 209   this->codecache = 1;
 210 
 211   /*
 212    * Find start.
 213    */
 214   this->segment = (this->pc - this->CodeCache_low) >>
 215     this->CodeHeap_log2_segment_size;
 216   this->block = this->CodeCache_segmap_low;
 217   this->tag = copyin_uchar(this->block + this->segment);
 218   "second";
 219 }
 220 
 221 dtrace:helper:ustack:
 222 /!this->done && this->codecache && this->tag > 0/
 223 {
 224   MARK_LINE;
 225   this->tag = copyin_uchar(this->block + this->segment);
 226   this->segment = this->segment - this->tag;
 227 }
 228 
 229 dtrace:helper:ustack:
 230 /!this->done && this->codecache && this->tag > 0/
 231 {
 232   MARK_LINE;
 233   this->tag = copyin_uchar(this->block + this->segment);
 234   this->segment = this->segment - this->tag;
 235 }
 236 
 237 dtrace:helper:ustack:
 238 /!this->done && this->codecache && this->tag > 0/
 239 {
 240   MARK_LINE;
 241   this->tag = copyin_uchar(this->block + this->segment);
 242   this->segment = this->segment - this->tag;
 243 }
 244 
 245 dtrace:helper:ustack:
 246 /!this->done && this->codecache && this->tag > 0/
 247 {
 248   MARK_LINE;
 249   this->tag = copyin_uchar(this->block + this->segment);
 250   this->segment = this->segment - this->tag;
 251 }
 252 
 253 dtrace:helper:ustack:
 254 /!this->done && this->codecache && this->tag > 0/
 255 {
 256   MARK_LINE;
 257   this->tag = copyin_uchar(this->block + this->segment);
 258   this->segment = this->segment - this->tag;
 259 }
 260 
 261 dtrace:helper:ustack:
 262 /!this->done && this->codecache && this->tag > 0/
 263 {
 264   MARK_LINE;
 265   this->error = "<couldn't find start>";
 266   this->done = 1;
 267 }
 268 
 269 dtrace:helper:ustack:
 270 /!this->done && this->codecache/
 271 {
 272   MARK_LINE;
 273   this->block = this->CodeCache_low +
 274     (this->segment << this->CodeHeap_log2_segment_size);
 275   this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
 276 }
 277 
 278 dtrace:helper:ustack:
 279 /!this->done && this->codecache && !this->used/
 280 {
 281   MARK_LINE;
 282   this->error = "<block not in use>";
 283   this->done = 1;
 284 }
 285 
 286 dtrace:helper:ustack:
 287 /!this->done && this->codecache/
 288 {
 289   MARK_LINE;
 290   this->start = this->block + SIZE_HeapBlockHeader;
 291   this->vtbl = copyin_ptr(this->start);
 292 
 293   this->nmethod_vtbl            = (pointer) &``__1cHnmethodG__vtbl_;
 294   this->BufferBlob_vtbl         = (pointer) &``__1cKBufferBlobG__vtbl_;
 295 }
 296 
 297 dtrace:helper:ustack:
 298 /!this->done && this->vtbl == this->nmethod_vtbl/
 299 {
 300   MARK_LINE;
 301   this->methodOopPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
 302   this->suffix = '*';
 303   this->methodOop = 1;
 304 }
 305 
 306 dtrace:helper:ustack:
 307 /!this->done && this->vtbl == this->BufferBlob_vtbl/
 308 {
 309   MARK_LINE;
 310   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
 311 }
 312 
 313 dtrace:helper:ustack:
 314 /!this->done && this->vtbl == this->BufferBlob_vtbl &&
 315 this->Use_Compressed_Oops == 0 &&
 316 this->methodOopPtr > this->heap_start && this->methodOopPtr < this->heap_end/
 317 {
 318   MARK_LINE;
 319   this->klass = copyin_ptr(this->methodOopPtr + OFFSET_oopDesc_metadata);
 320   this->methodOop = this->klass == this->Universe_methodKlassOop;
 321   this->done = !this->methodOop;
 322 }
 323 
 324 dtrace:helper:ustack:
 325 /!this->done && this->vtbl == this->BufferBlob_vtbl &&
 326 this->Use_Compressed_Oops != 0 &&
 327 this->methodOopPtr > this->heap_start && this->methodOopPtr < this->heap_end/
 328 {
 329   MARK_LINE;
 330   /*
 331    * Read compressed pointer and  decode heap oop, same as oop.inline.hpp
 332    */
 333   this->cklass = copyin_uint32(this->methodOopPtr + OFFSET_oopDesc_metadata);
 334   this->klass = (uint64_t)((uintptr_t)this->Universe_narrow_oop_base +
 335                 ((uintptr_t)this->cklass << this->Universe_narrow_oop_shift));
 336   this->methodOop = this->klass == this->Universe_methodKlassOop;
 337   this->done = !this->methodOop;
 338 }
 339 
 340 dtrace:helper:ustack:
 341 /!this->done && !this->methodOop/
 342 {
 343   MARK_LINE;
 344   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
 345   this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
 346   this->done = 1;
 347 }
 348 
 349 dtrace:helper:ustack:
 350 /!this->done && this->methodOop/
 351 {
 352   MARK_LINE;
 353   this->constMethod = copyin_ptr(this->methodOopPtr +
 354       OFFSET_methodOopDesc_constMethod);
 355 
 356   this->nameIndex = copyin_uint16(this->constMethod +
 357       OFFSET_constMethodOopDesc_name_index);
 358 
 359   this->signatureIndex = copyin_uint16(this->constMethod +
 360       OFFSET_constMethodOopDesc_signature_index);
 361 
 362   this->constantPool = copyin_ptr(this->methodOopPtr +
 363       OFFSET_methodOopDesc_constants);
 364 
 365   this->nameSymbol = copyin_ptr(this->constantPool +
 366       this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
 367 
 368   this->nameSymbolLength = copyin_uint16(this->nameSymbol +
 369       OFFSET_Symbol_length);
 370 
 371   this->signatureSymbol = copyin_ptr(this->constantPool +
 372       this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
 373 
 374   this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
 375       OFFSET_Symbol_length);
 376 
 377   this->klassPtr = copyin_ptr(this->constantPool +
 378       OFFSET_constantPoolOopDesc_pool_holder);
 379 
 380   this->klassSymbol = copyin_ptr(this->klassPtr +
 381       OFFSET_Klass_name + SIZE_oopDesc);
 382 
 383   this->klassSymbolLength = copyin_uint16(this->klassSymbol +
 384       OFFSET_Symbol_length);
 385 
 386   /*
 387    * Enough for three strings, plus the '.', plus the trailing '\0'.
 388    */
 389   this->result = (char *) alloca(this->klassSymbolLength +
 390       this->nameSymbolLength +
 391       this->signatureSymbolLength + 2 + 1);
 392 
 393   copyinto(this->klassSymbol + OFFSET_Symbol_body,
 394       this->klassSymbolLength, this->result);
 395 
 396   /*
 397    * Add the '.' between the class and the name.
 398    */
 399   this->result[this->klassSymbolLength] = '.';
 400 
 401   copyinto(this->nameSymbol + OFFSET_Symbol_body,
 402       this->nameSymbolLength,
 403       this->result + this->klassSymbolLength + 1);
 404 
 405   copyinto(this->signatureSymbol + OFFSET_Symbol_body,
 406       this->signatureSymbolLength,
 407       this->result + this->klassSymbolLength +
 408       this->nameSymbolLength + 1);
 409 
 410   /*
 411    * Now we need to add a trailing '\0' and possibly a tag character.
 412    */
 413   this->result[this->klassSymbolLength + 1 + 
 414       this->nameSymbolLength +
 415       this->signatureSymbolLength] = this->suffix;
 416   this->result[this->klassSymbolLength + 2 + 
 417       this->nameSymbolLength +
 418       this->signatureSymbolLength] = '\0';
 419 
 420   this->done = 1;
 421 }
 422 
 423 dtrace:helper:ustack:
 424 /this->done && this->error == (char *) NULL/
 425 {
 426   this->result;   
 427 }
 428 
 429 dtrace:helper:ustack:
 430 /this->done && this->error != (char *) NULL/
 431 {
 432   this->error;
 433 }
 434 
 435 dtrace:helper:ustack:
 436 /!this->done && this->codecache/
 437 {
 438   this->done = 1;
 439   "error";
 440 }
 441 
 442 
 443 dtrace:helper:ustack:
 444 /!this->done/
 445 {
 446   NULL;
 447 }