/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/* This file is auto-generated */
#include "JvmOffsetsIndex.h"
#define DEBUG
#ifdef DEBUG
#define MARK_LINE this->line = __LINE__
#else
#define MARK_LINE
#endif
#ifdef _LP64
#define STACK_BIAS 0x7ff
#define pointer uint64_t
#else
#define STACK_BIAS 0
#define pointer uint32_t
#endif
extern pointer __JvmOffsets;
/* GrowableArray<CodeHeaps*>* */
extern pointer __1cJCodeCacheG_heaps_;
extern pointer __1cIUniverseO_collectedHeap_;
extern pointer __1cHnmethodG__vtbl_;
extern pointer __1cGMethodG__vtbl_;
extern pointer __1cKBufferBlobG__vtbl_;
#define copyin_ptr(ADDR) *(pointer*) copyin((pointer) (ADDR), sizeof(pointer))
#define copyin_uchar(ADDR) *(uchar_t*) copyin((pointer) (ADDR), sizeof(uchar_t))
#define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t))
#define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t))
#define copyin_int32(ADDR) *(int32_t*) copyin((pointer) (ADDR), sizeof(int32_t))
#define copyin_uint8(ADDR) *(uint8_t*) copyin((pointer) (ADDR), sizeof(uint8_t))
#define copyin_offset(JVM_CONST) JVM_CONST = \
copyin_int32(JvmOffsetsPtr + IDX_##JVM_CONST * sizeof(int32_t))
int init_done;
dtrace:helper:ustack:
{
MARK_LINE;
this->done = 0;
/*
* TBD:
* Here we initialize init_done, otherwise jhelper does not work.
* Therefore, copyin_offset() statements work multiple times now.
* There is a hope we could avoid it in the future, and so,
* this initialization can be removed.
*/
init_done = 0;
this->error = (char *) NULL;
this->result = (char *) NULL;
this->isMethod = 0;
this->codecache = 0;
this->klass = (pointer) NULL;
this->vtbl = (pointer) NULL;
this->suffix = '\0';
}
dtrace:helper:ustack:
{
MARK_LINE;
/* Initialization of JvmOffsets constants */
JvmOffsetsPtr = (pointer) &``__JvmOffsets;
}
dtrace:helper:ustack:
/!init_done && !this->done/
{
MARK_LINE;
copyin_offset(POINTER_SIZE);
copyin_offset(COMPILER);
copyin_offset(OFFSET_CollectedHeap_reserved);
copyin_offset(OFFSET_MemRegion_start);
copyin_offset(OFFSET_MemRegion_word_size);
copyin_offset(SIZE_HeapWord);
copyin_offset(OFFSET_interpreter_frame_method);
copyin_offset(OFFSET_Klass_name);
copyin_offset(OFFSET_ConstantPool_pool_holder);
copyin_offset(OFFSET_HeapBlockHeader_used);
copyin_offset(OFFSET_oopDesc_metadata);
copyin_offset(OFFSET_Symbol_length_and_refcount);
copyin_offset(OFFSET_Symbol_body);
copyin_offset(OFFSET_Method_constMethod);
copyin_offset(OFFSET_ConstMethod_constants);
copyin_offset(OFFSET_ConstMethod_name_index);
copyin_offset(OFFSET_ConstMethod_signature_index);
copyin_offset(OFFSET_CodeHeap_memory);
copyin_offset(OFFSET_CodeHeap_segmap);
copyin_offset(OFFSET_CodeHeap_log2_segment_size);
copyin_offset(OFFSET_GrowableArray_CodeHeap_data);
copyin_offset(OFFSET_GrowableArray_CodeHeap_len);
copyin_offset(OFFSET_VirtualSpace_low);
copyin_offset(OFFSET_VirtualSpace_high);
copyin_offset(OFFSET_CodeBlob_name);
copyin_offset(OFFSET_nmethod_method);
copyin_offset(SIZE_HeapBlockHeader);
copyin_offset(SIZE_oopDesc);
copyin_offset(SIZE_ConstantPool);
copyin_offset(OFFSET_NarrowPtrStruct_base);
copyin_offset(OFFSET_NarrowPtrStruct_shift);
/*
* The PC to translate is in arg0.
*/
this->pc = arg0;
/*
* The methodPtr is in %l2 on SPARC. This can be found at
* offset 8 from the frame pointer on 32-bit processes.
*/
#if defined(__sparc)
this->methodPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
#elif defined(__i386) || defined(__amd64)
this->methodPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
#else
#error "Don't know architecture"
#endif
/* Read address of GrowableArray<CodeHeaps*> */
// this->code_heaps_address = copyin_ptr(&``__1cJCodeCacheG_heaps_);
this->code_heaps_address = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cJCodeCacheG_heaps_ ) , sizeof ( uint64_t ) );
/* Read address of _data array field in GrowableArray */
this->code_heaps_array_address = copyin_ptr(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_data);
this->number_of_heaps = copyin_uint32(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_len);
this->Method_vtbl = (pointer) &``__1cGMethodG__vtbl_;
/*
* Get Java heap bounds
*/
// this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
this->Universe_collectedHeap = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cIUniverseO_collectedHeap_ ) , sizeof ( uint64_t ) );
this->heap_start = copyin_ptr(this->Universe_collectedHeap +
OFFSET_CollectedHeap_reserved +
OFFSET_MemRegion_start);
this->heap_size = SIZE_HeapWord *
copyin_ptr(this->Universe_collectedHeap +
OFFSET_CollectedHeap_reserved +
OFFSET_MemRegion_word_size
);
this->heap_end = this->heap_start + this->heap_size;
}
/*
* IMPORTANT: At the moment the ustack helper supports up to 5 code heaps in
* the code cache. If more code heaps are added the following probes have to
* be extended. This is done by simply adding a probe to get the heap bounds
* and another probe to set the code heap address of the newly created heap.
*/
/*
* ----- BEGIN: Get bounds of code heaps -----
*/
dtrace:helper:ustack:
/init_done < 1 && this->number_of_heaps >= 1 && !this->done/
{
MARK_LINE;
/* CodeHeap 1 */
init_done = 1;
this->code_heap1_address = copyin_ptr(this->code_heaps_array_address);
this->code_heap1_low = copyin_ptr(this->code_heap1_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap1_high = copyin_ptr(this->code_heap1_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
}
dtrace:helper:ustack:
/init_done < 2 && this->number_of_heaps >= 2 && !this->done/
{
MARK_LINE;
/* CodeHeap 2 */
init_done = 2;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap2_address = copyin_ptr(this->code_heaps_array_address);
this->code_heap2_low = copyin_ptr(this->code_heap2_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap2_high = copyin_ptr(this->code_heap2_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
}
dtrace:helper:ustack:
/init_done < 3 && this->number_of_heaps >= 3 && !this->done/
{
/* CodeHeap 3 */
init_done = 3;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap3_address = copyin_ptr(this->code_heaps_array_address);
this->code_heap3_low = copyin_ptr(this->code_heap3_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap3_high = copyin_ptr(this->code_heap3_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
}
dtrace:helper:ustack:
/init_done < 4 && this->number_of_heaps >= 4 && !this->done/
{
/* CodeHeap 4 */
init_done = 4;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap4_address = copyin_ptr(this->code_heaps_array_address);
this->code_heap4_low = copyin_ptr(this->code_heap4_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap4_high = copyin_ptr(this->code_heap4_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
}
dtrace:helper:ustack:
/init_done < 5 && this->number_of_heaps >= 5 && !this->done/
{
/* CodeHeap 5 */
init_done = 5;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap5_address = copyin_ptr(this->code_heaps_array_address);
this->code_heap5_low = copyin_ptr(this->code_heap5_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap5_high = copyin_ptr(this->code_heap5_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
}
/*
* ----- END: Get bounds of code heaps -----
*/
/*
* ----- BEGIN: Get address of the code heap pc points to -----
*/
dtrace:helper:ustack:
/!this->done && this->number_of_heaps >= 1 && this->code_heap1_low <= this->pc && this->pc < this->code_heap1_high/
{
MARK_LINE;
this->codecache = 1;
this->code_heap_address = this->code_heap1_address;
}
dtrace:helper:ustack:
/!this->done && this->number_of_heaps >= 2 && this->code_heap2_low <= this->pc && this->pc < this->code_heap2_high/
{
MARK_LINE;
this->codecache = 1;
this->code_heap_address = this->code_heap2_address;
}
dtrace:helper:ustack:
/!this->done && this->number_of_heaps >= 3 && this->code_heap3_low <= this->pc && this->pc < this->code_heap3_high/
{
MARK_LINE;
this->codecache = 1;
this->code_heap_address = this->code_heap3_address;
}
dtrace:helper:ustack:
/!this->done && this->number_of_heaps >= 4 && this->code_heap4_low <= this->pc && this->pc < this->code_heap4_high/
{
MARK_LINE;
this->codecache = 1;
this->code_heap_address = this->code_heap4_address;
}
dtrace:helper:ustack:
/!this->done && this->number_of_heaps >= 5 && this->code_heap5_low <= this->pc && this->pc < this->code_heap5_high/
{
MARK_LINE;
this->codecache = 1;
this->code_heap_address = this->code_heap5_address;
}
/*
* ----- END: Get address of the code heap pc points to -----
*/
dtrace:helper:ustack:
/!this->done && this->codecache/
{
MARK_LINE;
/*
* Get code heap configuration
*/
this->code_heap_low = copyin_ptr(this->code_heap_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap_segmap_low = copyin_ptr(this->code_heap_address +
OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
this->code_heap_log2_segment_size = copyin_uint32(
this->code_heap_address + OFFSET_CodeHeap_log2_segment_size);
/*
* Find start
*/
this->segment = (this->pc - this->code_heap_low) >>
this->code_heap_log2_segment_size;
this->block = this->code_heap_segmap_low;
this->tag = copyin_uchar(this->block + this->segment);
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->tag = copyin_uchar(this->block + this->segment);
this->segment = this->segment - this->tag;
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->tag = copyin_uchar(this->block + this->segment);
this->segment = this->segment - this->tag;
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->tag = copyin_uchar(this->block + this->segment);
this->segment = this->segment - this->tag;
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->tag = copyin_uchar(this->block + this->segment);
this->segment = this->segment - this->tag;
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->tag = copyin_uchar(this->block + this->segment);
this->segment = this->segment - this->tag;
}
dtrace:helper:ustack:
/!this->done && this->codecache && this->tag > 0/
{
MARK_LINE;
this->error = "<couldn't find start>";
this->done = 1;
}
dtrace:helper:ustack:
/!this->done && this->codecache/
{
MARK_LINE;
this->block = this->code_heap_low +
(this->segment << this->code_heap_log2_segment_size);
this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
}
dtrace:helper:ustack:
/!this->done && this->codecache && !this->used/
{
MARK_LINE;
this->error = "<block not in use>";
this->done = 1;
}
dtrace:helper:ustack:
/!this->done && this->codecache/
{
MARK_LINE;
this->start = this->block + SIZE_HeapBlockHeader;
this->vtbl = copyin_ptr(this->start);
this->nmethod_vtbl = (pointer) &``__1cHnmethodG__vtbl_;
this->BufferBlob_vtbl = (pointer) &``__1cKBufferBlobG__vtbl_;
}
dtrace:helper:ustack:
/!this->done && this->vtbl == this->nmethod_vtbl/
{
MARK_LINE;
this->methodPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
this->suffix = '*';
this->isMethod = 1;
}
dtrace:helper:ustack:
/!this->done && this->vtbl == this->BufferBlob_vtbl/
{
MARK_LINE;
this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
}
dtrace:helper:ustack:
/!this->done && this->vtbl == this->BufferBlob_vtbl && this->methodPtr != 0/
{
MARK_LINE;
this->klass = copyin_ptr(this->methodPtr);
this->isMethod = this->klass == this->Method_vtbl;
this->done = !this->isMethod;
}
dtrace:helper:ustack:
/!this->done && !this->isMethod/
{
MARK_LINE;
this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
this->done = 1;
}
dtrace:helper:ustack:
/!this->done && this->isMethod/
{
MARK_LINE;
this->constMethod = copyin_ptr(this->methodPtr +
OFFSET_Method_constMethod);
this->nameIndex = copyin_uint16(this->constMethod +
OFFSET_ConstMethod_name_index);
this->signatureIndex = copyin_uint16(this->constMethod +
OFFSET_ConstMethod_signature_index);
this->constantPool = copyin_ptr(this->constMethod +
OFFSET_ConstMethod_constants);
this->nameSymbol = copyin_ptr(this->constantPool +
this->nameIndex * sizeof (pointer) + SIZE_ConstantPool);
/* The symbol is a CPSlot and has lower bit set to indicate metadata */
this->nameSymbol &= (~1); /* remove metadata lsb */
/* Because sparc is big endian, the top half length is at the correct offset. */
this->nameSymbolLength = copyin_uint16(this->nameSymbol +
OFFSET_Symbol_length_and_refcount);
this->signatureSymbol = copyin_ptr(this->constantPool +
this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
this->signatureSymbol &= (~1); /* remove metadata lsb */
/* Because sparc is big endian, the top half length is at the correct offset. */
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
OFFSET_Symbol_length_and_refcount);
this->klassPtr = copyin_ptr(this->constantPool +
OFFSET_ConstantPool_pool_holder);
this->klassSymbol = copyin_ptr(this->klassPtr +
OFFSET_Klass_name);
/* Because sparc is big endian, the top half length is at the correct offset. */
this->klassSymbolLength = copyin_uint16(this->klassSymbol +
OFFSET_Symbol_length_and_refcount);
/*
* Enough for three strings, plus the '.', plus the trailing '\0'.
*/
this->result = (char *) alloca(this->klassSymbolLength +
this->nameSymbolLength +
this->signatureSymbolLength + 2 + 1);
copyinto(this->klassSymbol + OFFSET_Symbol_body,
this->klassSymbolLength, this->result);
/*
* Add the '.' between the class and the name.
*/
this->result[this->klassSymbolLength] = '.';
copyinto(this->nameSymbol + OFFSET_Symbol_body,
this->nameSymbolLength,
this->result + this->klassSymbolLength + 1);
copyinto(this->signatureSymbol + OFFSET_Symbol_body,
this->signatureSymbolLength,
this->result + this->klassSymbolLength +
this->nameSymbolLength + 1);
/*
* Now we need to add a trailing '\0' and possibly a tag character.
*/
this->result[this->klassSymbolLength + 1 +
this->nameSymbolLength +
this->signatureSymbolLength] = this->suffix;
this->result[this->klassSymbolLength + 2 +
this->nameSymbolLength +
this->signatureSymbolLength] = '\0';
this->done = 1;
}
dtrace:helper:ustack:
/this->done && this->error == (char *) NULL/
{
this->result;
}
dtrace:helper:ustack:
/this->done && this->error != (char *) NULL/
{
this->error;
}
dtrace:helper:ustack:
/!this->done && this->codecache/
{
this->done = 1;
"error";
}
dtrace:helper:ustack:
/!this->done/
{
NULL;
}