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