jhelper.d revision 3602:da91efe96a93
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 __1cIUniverseO_collectedHeap_;
48extern pointer __1cIUniverseL_narrow_oop_;
49#ifdef _LP64
50extern pointer UseCompressedOops;
51#endif
52
53extern pointer __1cHnmethodG__vtbl_;
54extern pointer __1cGMethodG__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->isMethod = 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_ConstantPool_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_Method_constMethod);
121  copyin_offset(OFFSET_ConstMethod_constants);
122  copyin_offset(OFFSET_ConstMethod_name_index);
123  copyin_offset(OFFSET_ConstMethod_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_ConstantPool);
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 methodPtr 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->methodPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
153#elif defined(__i386) || defined(__amd64)
154  this->methodPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
155#else
156#error "Don't know architecture"
157#endif
158
159  this->CodeCache_heap_address = copyin_ptr(&``__1cJCodeCacheF_heap_);
160
161  /* Reading volatile values */
162#ifdef _LP64
163  this->Use_Compressed_Oops  = copyin_uint8(&``UseCompressedOops);
164#else
165  this->Use_Compressed_Oops  = 0;
166#endif
167
168  this->Universe_narrow_oop_base  = copyin_ptr(&``__1cIUniverseL_narrow_oop_ +
169                                               OFFSET_NarrowOopStruct_base);
170  this->Universe_narrow_oop_shift = copyin_int32(&``__1cIUniverseL_narrow_oop_ +
171                                                 OFFSET_NarrowOopStruct_shift);
172
173  this->CodeCache_low = copyin_ptr(this->CodeCache_heap_address +
174      OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
175
176  this->CodeCache_high = copyin_ptr(this->CodeCache_heap_address +
177      OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
178
179  this->CodeCache_segmap_low = copyin_ptr(this->CodeCache_heap_address +
180      OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
181
182  this->CodeCache_segmap_high = copyin_ptr(this->CodeCache_heap_address +
183      OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_high);
184
185  this->CodeHeap_log2_segment_size = copyin_uint32(
186      this->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size);
187
188  this->Method_vtbl             = (pointer) &``__1cGMethodG__vtbl_;
189
190  /*
191   * Get Java heap bounds
192   */
193  this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
194  this->heap_start = copyin_ptr(this->Universe_collectedHeap +
195      OFFSET_CollectedHeap_reserved +
196      OFFSET_MemRegion_start);
197  this->heap_size = SIZE_HeapWord *
198    copyin_ptr(this->Universe_collectedHeap +
199        OFFSET_CollectedHeap_reserved +
200        OFFSET_MemRegion_word_size
201        );
202  this->heap_end = this->heap_start + this->heap_size;
203}
204
205dtrace:helper:ustack:
206/!this->done &&
207this->CodeCache_low <= this->pc && this->pc < this->CodeCache_high/
208{
209  MARK_LINE;
210  this->codecache = 1;
211
212  /*
213   * Find start.
214   */
215  this->segment = (this->pc - this->CodeCache_low) >>
216    this->CodeHeap_log2_segment_size;
217  this->block = this->CodeCache_segmap_low;
218  this->tag = copyin_uchar(this->block + this->segment);
219  "second";
220}
221
222dtrace:helper:ustack:
223/!this->done && this->codecache && this->tag > 0/
224{
225  MARK_LINE;
226  this->tag = copyin_uchar(this->block + this->segment);
227  this->segment = this->segment - this->tag;
228}
229
230dtrace:helper:ustack:
231/!this->done && this->codecache && this->tag > 0/
232{
233  MARK_LINE;
234  this->tag = copyin_uchar(this->block + this->segment);
235  this->segment = this->segment - this->tag;
236}
237
238dtrace:helper:ustack:
239/!this->done && this->codecache && this->tag > 0/
240{
241  MARK_LINE;
242  this->tag = copyin_uchar(this->block + this->segment);
243  this->segment = this->segment - this->tag;
244}
245
246dtrace:helper:ustack:
247/!this->done && this->codecache && this->tag > 0/
248{
249  MARK_LINE;
250  this->tag = copyin_uchar(this->block + this->segment);
251  this->segment = this->segment - this->tag;
252}
253
254dtrace:helper:ustack:
255/!this->done && this->codecache && this->tag > 0/
256{
257  MARK_LINE;
258  this->tag = copyin_uchar(this->block + this->segment);
259  this->segment = this->segment - this->tag;
260}
261
262dtrace:helper:ustack:
263/!this->done && this->codecache && this->tag > 0/
264{
265  MARK_LINE;
266  this->error = "<couldn't find start>";
267  this->done = 1;
268}
269
270dtrace:helper:ustack:
271/!this->done && this->codecache/
272{
273  MARK_LINE;
274  this->block = this->CodeCache_low +
275    (this->segment << this->CodeHeap_log2_segment_size);
276  this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
277}
278
279dtrace:helper:ustack:
280/!this->done && this->codecache && !this->used/
281{
282  MARK_LINE;
283  this->error = "<block not in use>";
284  this->done = 1;
285}
286
287dtrace:helper:ustack:
288/!this->done && this->codecache/
289{
290  MARK_LINE;
291  this->start = this->block + SIZE_HeapBlockHeader;
292  this->vtbl = copyin_ptr(this->start);
293
294  this->nmethod_vtbl            = (pointer) &``__1cHnmethodG__vtbl_;
295  this->BufferBlob_vtbl         = (pointer) &``__1cKBufferBlobG__vtbl_;
296}
297
298dtrace:helper:ustack:
299/!this->done && this->vtbl == this->nmethod_vtbl/
300{
301  MARK_LINE;
302  this->methodPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
303  this->suffix = '*';
304  this->isMethod = 1;
305}
306
307dtrace:helper:ustack:
308/!this->done && this->vtbl == this->BufferBlob_vtbl/
309{
310  MARK_LINE;
311  this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
312}
313
314
315dtrace:helper:ustack:
316/!this->done && this->vtbl == this->BufferBlob_vtbl && this->methodPtr != 0/
317{
318  MARK_LINE;
319  this->klass = copyin_ptr(this->methodPtr);
320  this->isMethod = this->klass == this->Method_vtbl;
321  this->done = !this->isMethod;
322}
323
324dtrace:helper:ustack:
325/!this->done && !this->isMethod/
326{
327  MARK_LINE;
328  this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
329  this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
330  this->done = 1;
331}
332
333dtrace:helper:ustack:
334/!this->done && this->isMethod/
335{
336  MARK_LINE;
337  this->constMethod = copyin_ptr(this->methodPtr +
338      OFFSET_Method_constMethod);
339
340  this->nameIndex = copyin_uint16(this->constMethod +
341      OFFSET_ConstMethod_name_index);
342
343  this->signatureIndex = copyin_uint16(this->constMethod +
344      OFFSET_ConstMethod_signature_index);
345
346  this->constantPool = copyin_ptr(this->constMethod +
347      OFFSET_ConstMethod_constants);
348
349  this->nameSymbol = copyin_ptr(this->constantPool +
350      this->nameIndex * sizeof (pointer) + SIZE_ConstantPool);
351
352  this->nameSymbolLength = copyin_uint16(this->nameSymbol +
353      OFFSET_Symbol_length);
354
355  this->signatureSymbol = copyin_ptr(this->constantPool +
356      this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
357
358  this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
359      OFFSET_Symbol_length);
360
361  this->klassPtr = copyin_ptr(this->constantPool +
362      OFFSET_ConstantPool_pool_holder);
363
364  this->klassSymbol = copyin_ptr(this->klassPtr +
365      OFFSET_Klass_name);
366
367  this->klassSymbolLength = copyin_uint16(this->klassSymbol +
368      OFFSET_Symbol_length);
369
370  /*
371   * Enough for three strings, plus the '.', plus the trailing '\0'.
372   */
373  this->result = (char *) alloca(this->klassSymbolLength +
374      this->nameSymbolLength +
375      this->signatureSymbolLength + 2 + 1);
376
377  copyinto(this->klassSymbol + OFFSET_Symbol_body,
378      this->klassSymbolLength, this->result);
379
380  /*
381   * Add the '.' between the class and the name.
382   */
383  this->result[this->klassSymbolLength] = '.';
384
385  copyinto(this->nameSymbol + OFFSET_Symbol_body,
386      this->nameSymbolLength,
387      this->result + this->klassSymbolLength + 1);
388
389  copyinto(this->signatureSymbol + OFFSET_Symbol_body,
390      this->signatureSymbolLength,
391      this->result + this->klassSymbolLength +
392      this->nameSymbolLength + 1);
393
394  /*
395   * Now we need to add a trailing '\0' and possibly a tag character.
396   */
397  this->result[this->klassSymbolLength + 1 +
398      this->nameSymbolLength +
399      this->signatureSymbolLength] = this->suffix;
400  this->result[this->klassSymbolLength + 2 +
401      this->nameSymbolLength +
402      this->signatureSymbolLength] = '\0';
403
404  this->done = 1;
405}
406
407dtrace:helper:ustack:
408/this->done && this->error == (char *) NULL/
409{
410  this->result;
411}
412
413dtrace:helper:ustack:
414/this->done && this->error != (char *) NULL/
415{
416  this->error;
417}
418
419dtrace:helper:ustack:
420/!this->done && this->codecache/
421{
422  this->done = 1;
423  "error";
424}
425
426
427dtrace:helper:ustack:
428/!this->done/
429{
430  NULL;
431}
432