jdk/src/demo/share/jvmti/hprof/hprof_frame.c
changeset 25859 3317bb8137f4
parent 14342 8435a30053c1
equal deleted inserted replaced
25858:836adbf7a2cd 25859:3317bb8137f4
       
     1 /*
       
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  *   - Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer.
       
    10  *
       
    11  *   - Redistributions in binary form must reproduce the above copyright
       
    12  *     notice, this list of conditions and the following disclaimer in the
       
    13  *     documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  *   - Neither the name of Oracle nor the names of its
       
    16  *     contributors may be used to endorse or promote products derived
       
    17  *     from this software without specific prior written permission.
       
    18  *
       
    19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       
    20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    30  */
       
    31 
       
    32 /*
       
    33  * This source code is provided to illustrate the usage of a given feature
       
    34  * or technique and has been deliberately simplified. Additional steps
       
    35  * required for a production-quality application, such as security checks,
       
    36  * input validation and proper error handling, might not be present in
       
    37  * this sample code.
       
    38  */
       
    39 
       
    40 
       
    41 /* This file contains support for handling frames, or (method,location) pairs. */
       
    42 
       
    43 #include "hprof.h"
       
    44 
       
    45 /*
       
    46  *  Frames map 1-to-1 to (methodID,location) pairs.
       
    47  *  When no line number is known, -1 should be used.
       
    48  *
       
    49  *  Frames are mostly used in traces (see hprof_trace.c) and will be marked
       
    50  *    with their status flag as they are written out to the hprof output file.
       
    51  *
       
    52  */
       
    53 
       
    54 enum LinenoState {
       
    55     LINENUM_UNINITIALIZED = 0,
       
    56     LINENUM_AVAILABLE     = 1,
       
    57     LINENUM_UNAVAILABLE   = 2
       
    58 };
       
    59 
       
    60 typedef struct FrameKey {
       
    61     jmethodID   method;
       
    62     jlocation   location;
       
    63 } FrameKey;
       
    64 
       
    65 typedef struct FrameInfo {
       
    66     unsigned short      lineno;
       
    67     unsigned char       lineno_state; /* LinenoState */
       
    68     unsigned char       status;
       
    69     SerialNumber serial_num;
       
    70 } FrameInfo;
       
    71 
       
    72 static FrameKey*
       
    73 get_pkey(FrameIndex index)
       
    74 {
       
    75     void *key_ptr;
       
    76     int   key_len;
       
    77 
       
    78     table_get_key(gdata->frame_table, index, &key_ptr, &key_len);
       
    79     HPROF_ASSERT(key_len==sizeof(FrameKey));
       
    80     HPROF_ASSERT(key_ptr!=NULL);
       
    81     return (FrameKey*)key_ptr;
       
    82 }
       
    83 
       
    84 static FrameInfo *
       
    85 get_info(FrameIndex index)
       
    86 {
       
    87     FrameInfo *info;
       
    88 
       
    89     info = (FrameInfo*)table_get_info(gdata->frame_table, index);
       
    90     return info;
       
    91 }
       
    92 
       
    93 static void
       
    94 list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
       
    95 {
       
    96     FrameKey   key;
       
    97     FrameInfo *info;
       
    98 
       
    99     HPROF_ASSERT(key_ptr!=NULL);
       
   100     HPROF_ASSERT(key_len==sizeof(FrameKey));
       
   101     HPROF_ASSERT(info_ptr!=NULL);
       
   102 
       
   103     key = *((FrameKey*)key_ptr);
       
   104     info = (FrameInfo*)info_ptr;
       
   105     debug_message(
       
   106         "Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n",
       
   107                 i, (void*)key.method, (jint)key.location,
       
   108                 info->lineno, info->lineno_state, info->status);
       
   109 }
       
   110 
       
   111 void
       
   112 frame_init(void)
       
   113 {
       
   114     gdata->frame_table = table_initialize("Frame",
       
   115                             1024, 1024, 1023, (int)sizeof(FrameInfo));
       
   116 }
       
   117 
       
   118 FrameIndex
       
   119 frame_find_or_create(jmethodID method, jlocation location)
       
   120 {
       
   121     FrameIndex index;
       
   122     static FrameKey empty_key;
       
   123     FrameKey key;
       
   124     jboolean new_one;
       
   125 
       
   126     key          = empty_key;
       
   127     key.method   = method;
       
   128     key.location = location;
       
   129     new_one      = JNI_FALSE;
       
   130     index        = table_find_or_create_entry(gdata->frame_table,
       
   131                         &key, (int)sizeof(key), &new_one, NULL);
       
   132     if ( new_one ) {
       
   133         FrameInfo *info;
       
   134 
       
   135         info = get_info(index);
       
   136         info->lineno_state = LINENUM_UNINITIALIZED;
       
   137         if ( location < 0 ) {
       
   138             info->lineno_state = LINENUM_UNAVAILABLE;
       
   139         }
       
   140         info->serial_num = gdata->frame_serial_number_counter++;
       
   141     }
       
   142     return index;
       
   143 }
       
   144 
       
   145 void
       
   146 frame_list(void)
       
   147 {
       
   148     debug_message(
       
   149         "--------------------- Frame Table ------------------------\n");
       
   150     table_walk_items(gdata->frame_table, &list_item, NULL);
       
   151     debug_message(
       
   152         "----------------------------------------------------------\n");
       
   153 }
       
   154 
       
   155 void
       
   156 frame_cleanup(void)
       
   157 {
       
   158     table_cleanup(gdata->frame_table, NULL, NULL);
       
   159     gdata->frame_table = NULL;
       
   160 }
       
   161 
       
   162 void
       
   163 frame_set_status(FrameIndex index, jint status)
       
   164 {
       
   165     FrameInfo *info;
       
   166 
       
   167     info = get_info(index);
       
   168     info->status = (unsigned char)status;
       
   169 }
       
   170 
       
   171 void
       
   172 frame_get_location(FrameIndex index, SerialNumber *pserial_num,
       
   173                    jmethodID *pmethod, jlocation *plocation, jint *plineno)
       
   174 {
       
   175     FrameKey  *pkey;
       
   176     FrameInfo *info;
       
   177     jint       lineno;
       
   178 
       
   179     pkey       = get_pkey(index);
       
   180     *pmethod   = pkey->method;
       
   181     *plocation = pkey->location;
       
   182     info       = get_info(index);
       
   183     lineno     = (jint)info->lineno;
       
   184     if ( info->lineno_state == LINENUM_UNINITIALIZED ) {
       
   185         info->lineno_state = LINENUM_UNAVAILABLE;
       
   186         if ( gdata->lineno_in_traces ) {
       
   187             if ( pkey->location >= 0 && !isMethodNative(pkey->method) ) {
       
   188                 lineno = getLineNumber(pkey->method, pkey->location);
       
   189                 if ( lineno >= 0 ) {
       
   190                     info->lineno = (unsigned short)lineno; /* save it */
       
   191                     info->lineno_state = LINENUM_AVAILABLE;
       
   192                 }
       
   193             }
       
   194         }
       
   195     }
       
   196     if ( info->lineno_state == LINENUM_UNAVAILABLE ) {
       
   197         lineno = -1;
       
   198     }
       
   199     *plineno     = lineno;
       
   200     *pserial_num = info->serial_num;
       
   201 }
       
   202 
       
   203 jint
       
   204 frame_get_status(FrameIndex index)
       
   205 {
       
   206     FrameInfo *info;
       
   207 
       
   208     info = get_info(index);
       
   209     return (jint)info->status;
       
   210 }