jhelper.d revision 3391:2fe087c3e814
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
44extern pointer __JvmOffsets;
45
46extern pointer __1cJCodeCacheF_heap_;
47extern pointer __1cIUniverseP_methodKlassObj_;
48extern pointer __1cIUniverseO_collectedHeap_;
49extern pointer __1cIUniverseL_narrow_oop_;
50#ifdef _LP64
51extern pointer UseCompressedOops;
52#endif
53
54extern pointer __1cHnmethodG__vtbl_;
55extern 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
68int init_done;
69
70dtrace: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
91dtrace:helper:ustack:
92{
93  MARK_LINE;
94  /* Initialization of JvmOffsets constants */
95  JvmOffsetsPtr = (pointer) &``__JvmOffsets;
96}
97
98dtrace: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_constMethodOopDesc_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
204dtrace:helper:ustack:
205/!this->done &&
206this->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
221dtrace: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
229dtrace: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
237dtrace: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
245dtrace: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
253dtrace: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
261dtrace: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
269dtrace: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
278dtrace: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
286dtrace: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
297dtrace: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
306dtrace: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
313dtrace:helper:ustack:
314/!this->done && this->vtbl == this->BufferBlob_vtbl &&
315this->Use_Compressed_Oops == 0 &&
316this->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
324dtrace:helper:ustack:
325/!this->done && this->vtbl == this->BufferBlob_vtbl &&
326this->Use_Compressed_Oops != 0 &&
327this->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
340dtrace: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
349dtrace: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->constMethod +
363      OFFSET_constMethodOopDesc_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
423dtrace:helper:ustack:
424/this->done && this->error == (char *) NULL/
425{
426  this->result;
427}
428
429dtrace:helper:ustack:
430/this->done && this->error != (char *) NULL/
431{
432  this->error;
433}
434
435dtrace:helper:ustack:
436/!this->done && this->codecache/
437{
438  this->done = 1;
439  "error";
440}
441
442
443dtrace:helper:ustack:
444/!this->done/
445{
446  NULL;
447}
448