Sindbad~EG File Manager
/*
* @(#)hprof_frame.c 1.21 05/11/17
*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/
/* This file contains support for handling frames, or (method,location) pairs. */
#include "hprof.h"
/*
* Frames map 1-to-1 to (methodID,location) pairs.
* When no line number is known, -1 should be used.
*
* Frames are mostly used in traces (see hprof_trace.c) and will be marked
* with their status flag as they are written out to the hprof output file.
*
*/
enum LinenoState {
LINENUM_UNINITIALIZED = 0,
LINENUM_AVAILABLE = 1,
LINENUM_UNAVAILABLE = 2
};
typedef struct FrameKey {
jmethodID method;
jlocation location;
} FrameKey;
typedef struct FrameInfo {
unsigned short lineno;
unsigned char lineno_state; /* LinenoState */
unsigned char status;
SerialNumber serial_num;
} FrameInfo;
static FrameKey*
get_pkey(FrameIndex index)
{
void *key_ptr;
int key_len;
table_get_key(gdata->frame_table, index, &key_ptr, &key_len);
HPROF_ASSERT(key_len==sizeof(FrameKey));
HPROF_ASSERT(key_ptr!=NULL);
return (FrameKey*)key_ptr;
}
static FrameInfo *
get_info(FrameIndex index)
{
FrameInfo *info;
info = (FrameInfo*)table_get_info(gdata->frame_table, index);
return info;
}
static void
list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
FrameKey key;
FrameInfo *info;
HPROF_ASSERT(key_ptr!=NULL);
HPROF_ASSERT(key_len==sizeof(FrameKey));
HPROF_ASSERT(info_ptr!=NULL);
key = *((FrameKey*)key_ptr);
info = (FrameInfo*)info_ptr;
debug_message(
"Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n",
i, (void*)key.method, (jint)key.location,
info->lineno, info->lineno_state, info->status);
}
void
frame_init(void)
{
gdata->frame_table = table_initialize("Frame",
1024, 1024, 1023, (int)sizeof(FrameInfo));
}
FrameIndex
frame_find_or_create(jmethodID method, jlocation location)
{
FrameIndex index;
static FrameKey empty_key;
FrameKey key;
jboolean new_one;
key = empty_key;
key.method = method;
key.location = location;
new_one = JNI_FALSE;
index = table_find_or_create_entry(gdata->frame_table,
&key, (int)sizeof(key), &new_one, NULL);
if ( new_one ) {
FrameInfo *info;
info = get_info(index);
info->lineno_state = LINENUM_UNINITIALIZED;
if ( location < 0 ) {
info->lineno_state = LINENUM_UNAVAILABLE;
}
info->serial_num = gdata->frame_serial_number_counter++;
}
return index;
}
void
frame_list(void)
{
debug_message(
"--------------------- Frame Table ------------------------\n");
table_walk_items(gdata->frame_table, &list_item, NULL);
debug_message(
"----------------------------------------------------------\n");
}
void
frame_cleanup(void)
{
table_cleanup(gdata->frame_table, NULL, NULL);
gdata->frame_table = NULL;
}
void
frame_set_status(FrameIndex index, jint status)
{
FrameInfo *info;
info = get_info(index);
info->status = (unsigned char)status;
}
void
frame_get_location(FrameIndex index, SerialNumber *pserial_num,
jmethodID *pmethod, jlocation *plocation, jint *plineno)
{
FrameKey *pkey;
FrameInfo *info;
jint lineno;
pkey = get_pkey(index);
*pmethod = pkey->method;
*plocation = pkey->location;
info = get_info(index);
lineno = (jint)info->lineno;
if ( info->lineno_state == LINENUM_UNINITIALIZED ) {
info->lineno_state = LINENUM_UNAVAILABLE;
if ( gdata->lineno_in_traces ) {
if ( pkey->location >= 0 && !isMethodNative(pkey->method) ) {
lineno = getLineNumber(pkey->method, pkey->location);
if ( lineno >= 0 ) {
info->lineno = (unsigned short)lineno; /* save it */
info->lineno_state = LINENUM_AVAILABLE;
}
}
}
}
if ( info->lineno_state == LINENUM_UNAVAILABLE ) {
lineno = -1;
}
*plineno = lineno;
*pserial_num = info->serial_num;
}
jint
frame_get_status(FrameIndex index)
{
FrameInfo *info;
info = get_info(index);
return (jint)info->status;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists