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 }