jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tls.c
author sla
Tue, 26 Aug 2014 07:55:08 +0200
changeset 26201 40a873d21081
parent 25859 jdk/src/demo/share/jvmti/hprof/hprof_tls.c@3317bb8137f4
permissions -rw-r--r--
8043936: Drop HPROF as demo, keep as HPROF agent shipped with JDK Reviewed-by: erikj, alanb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
14342
8435a30053c1 7197491: update copyright year to match last edit in jdk8 jdk repository
alanb
parents: 10292
diff changeset
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * Redistribution and use in source and binary forms, with or without
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * modification, are permitted provided that the following conditions
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * are met:
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *   - Redistributions of source code must retain the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *     notice, this list of conditions and the following disclaimer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 *   - Redistributions in binary form must reproduce the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 *     notice, this list of conditions and the following disclaimer in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 *     documentation and/or other materials provided with the distribution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    15
 *   - Neither the name of Oracle nor the names of its
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *     contributors may be used to endorse or promote products derived
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 *     from this software without specific prior written permission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
10292
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    32
/*
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    33
 * This source code is provided to illustrate the usage of a given feature
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    34
 * or technique and has been deliberately simplified. Additional steps
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    35
 * required for a production-quality application, such as security checks,
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    36
 * input validation and proper error handling, might not be present in
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    37
 * this sample code.
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    38
 */
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    39
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 5506
diff changeset
    40
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
#include "hprof.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
/* Thread Local Storage Table and method entry/exit handling. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * The tls table items have a key of it's serial number, but may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *   searched via a walk of the table looking for a jthread match.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *   This isn't a performance
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *   issue because the table index should normally be stored in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 *   Thread Local Storage for the thread. The table is only searched
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *   when the jthread is seen before the Thread Local Storage is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *   (e.g. before VM_INIT or the ThreadStart).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 *   The key is only used when we need to lookup a tls table entry by
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *   way of it's serial number, which should be unique per thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * Each active thread that we have seen should have a unique TlsIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *   which is an index into this table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * For cpu=times, each table entry will have a stack to hold the method
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *   that have been called, effectively keeping an active stack trace
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *   for the thread. As each method exits, the statistics for the trace
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *   associated with the current stack contents is updated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * For cpu=samples, each thread is checked to see if it's runnable,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *   and not suspended, and has a stack associated with it, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *   that stack trace is updated with an additional 'hit'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * This file also contains the dump logic for owned monitors, and for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 *   threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * Initial number of stack elements to track per thread. This
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * value should be set to a reasonable guess as to the number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * methods deep a thread calls. This stack doubles in size for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * reallocation and does not shrink.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
#define INITIAL_THREAD_STACK_LIMIT 64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
typedef struct StackElement {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    FrameIndex  frame_index;            /* Frame (method/location(-1)) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    jmethodID   method;                 /* Method ID */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    jlong       method_start_time;      /* method start time */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    jlong       time_in_callees;        /* time in callees */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
} StackElement;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
typedef struct TlsInfo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    jint            sample_status;      /* Thread status for cpu sampling */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    jboolean        agent_thread;       /* Is thread our own agent thread? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    jthread         globalref;          /* Global reference for thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    Stack          *stack;              /* Stack of StackElements entry/exit */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    MonitorIndex    monitor_index;      /* last contended mon */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    jint            tracker_status;     /* If we are inside Tracker class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    FrameIndex     *frames_buffer;      /* Buffer used to create TraceIndex */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    jvmtiFrameInfo *jframes_buffer;     /* Buffer used to create TraceIndex */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    int             buffer_depth;       /* Frames allowed in buffer */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    TraceIndex      last_trace;         /* Last trace for this thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    ObjectIndex     thread_object_index;/* If heap=dump */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    jlong           monitor_start_time; /* Start time for monitor */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    jint            in_heap_dump;       /* If we are an object in the dump */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
} TlsInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
typedef struct SearchData {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    JNIEnv      *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    jthread      thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    TlsIndex     found;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
} SearchData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
typedef struct IterateInfo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    TlsIndex *          ptls_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    jthread  *          pthreads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    jint                count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
} IterateInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
typedef struct ThreadList {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    jthread      *threads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    SerialNumber *serial_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    TlsInfo     **infos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    jint          count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    JNIEnv       *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
} ThreadList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
typedef struct SampleData {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    ObjectIndex  thread_object_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    jint         sample_status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
} SampleData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
/* Private internal functions. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
static SerialNumber
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
get_key(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    SerialNumber *pkey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    int           key_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    if ( index == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    pkey    = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    key_len = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    table_get_key(gdata->tls_table, index, (void**)&pkey, &key_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    HPROF_ASSERT(pkey!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    HPROF_ASSERT(key_len==(int)sizeof(SerialNumber));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    return *pkey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
static TlsInfo *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
get_info(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    return (TlsInfo*)table_get_info(gdata->tls_table, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
delete_globalref(JNIEnv *env, TlsInfo *info)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    jthread ref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    ref = info->globalref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    info->globalref = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    if ( ref != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        deleteWeakGlobalReference(env, ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
clean_info(TlsInfo *info)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    /* Free up any allocated space in this TlsInfo structure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    if ( info->stack != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        stack_term(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        info->stack = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    if ( info->frames_buffer != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        HPROF_FREE(info->frames_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        info->frames_buffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    if ( info->jframes_buffer != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        HPROF_FREE(info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        info->jframes_buffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
cleanup_item(TableIndex index, void *key_ptr, int key_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                        void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    TlsInfo *   info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    info = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    clean_info(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
delete_ref_item(TableIndex index, void *key_ptr, int key_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                        void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    delete_globalref((JNIEnv*)arg, (TlsInfo*)info_ptr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
list_item(TableIndex index, void *key_ptr, int key_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                        void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    info        = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    debug_message( "Tls 0x%08x: SN=%u, sample_status=%d, agent=%d, "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                          "thread=%p, monitor=0x%08x, "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                          "tracker_status=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                *(SerialNumber*)key_ptr,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                info->sample_status,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                info->agent_thread,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                (void*)info->globalref,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                info->monitor_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                info->tracker_status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
search_item(TableIndex index, void *key_ptr, int key_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                        void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    SearchData  *data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    jobject      lref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    HPROF_ASSERT(arg!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    info        = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    data        = (SearchData*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    lref        = newLocalReference(data->env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    if ( lref != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        if ( isSameObject(data->env, data->thread, lref) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            HPROF_ASSERT(data->found==0); /* Did we find more than one? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            data->found = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        deleteLocalReference(data->env, lref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
static TlsIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
search(JNIEnv *env, jthread thread)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    SearchData  data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    HPROF_ASSERT(thread!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    data.env = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    data.thread = thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    data.found = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    table_walk_items(gdata->tls_table, &search_item, (void*)&data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    return data.found;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
garbage_collect_item(TableIndex index, void *key_ptr, int key_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                        void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    JNIEnv      *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    jobject      lref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    HPROF_ASSERT(arg!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    info        = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    env         = (JNIEnv*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    lref        = newLocalReference(env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    if ( lref == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        delete_globalref(env, info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        clean_info(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        table_free_entry(gdata->tls_table, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        deleteLocalReference(env, lref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
tls_garbage_collect(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    rawMonitorEnter(gdata->data_access_lock); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        table_walk_items(gdata->tls_table, &garbage_collect_item, (void*)env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    } rawMonitorExit(gdata->data_access_lock);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
sum_sample_status_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    info                = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    if ( !info->agent_thread ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        (*(jint*)arg)      += info->sample_status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
setup_trace_buffers(TlsInfo *info, int max_depth)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    int nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    int max_frames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    if ( info->frames_buffer != NULL && info->buffer_depth >= max_depth ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    if ( info->frames_buffer != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        HPROF_FREE(info->frames_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    if ( info->jframes_buffer != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        HPROF_FREE(info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    info->buffer_depth      = max_depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    max_frames              = max_depth + 4; /* Allow for BCI & <init> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    nbytes                  = (int)sizeof(FrameIndex)*(max_frames+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    info->frames_buffer     = HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    nbytes                  = (int)sizeof(jvmtiFrameInfo)*(max_frames+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    info->jframes_buffer    = HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
static TraceIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
get_trace(jthread thread, SerialNumber thread_serial_num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                int depth, jboolean skip_init,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                FrameIndex *frames_buffer, jvmtiFrameInfo *jframes_buffer)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    TraceIndex trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    trace_index = gdata->system_trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        trace_index = trace_get_current(thread,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                        thread_serial_num, depth, skip_init,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                        frames_buffer, jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    return trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
/* Find thread with certain object index */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
sample_setter(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    info  = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    if ( info->globalref != NULL && !info->agent_thread ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        SampleData *data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        data   = (SampleData*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        if ( data->thread_object_index == info->thread_object_index ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            info->sample_status = data->sample_status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
/* Get various lists on known threads */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
get_thread_list(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    SerialNumber thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    ThreadList  *list;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    jthread      thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    HPROF_ASSERT(key_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    thread_serial_num = *(SerialNumber*)key_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    info              = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    list              = (ThreadList*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    thread            = newLocalReference(list->env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    if ( thread != NULL && info->sample_status != 0 && !info->agent_thread ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        if ( list->infos != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            list->infos[list->count] = info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        if ( list->serial_nums != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            list->serial_nums[list->count] = thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        list->threads[list->count] = thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        list->count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        /* Local reference gets freed by caller */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        /* If we don't use the local reference, delete it now */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            deleteLocalReference(list->env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
adjust_stats(jlong total_time, jlong self_time, TraceIndex trace_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
             StackElement *parent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    if ( total_time > 0 && parent != NULL ) {  /* if a caller exists */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        parent->time_in_callees += total_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    trace_increment_cost(trace_index, 1, self_time, total_time);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
push_method(Stack *stack, jlong method_start_time, jmethodID method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    StackElement new_element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    FrameIndex   frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    HPROF_ASSERT(stack!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    frame_index                  = frame_find_or_create(method, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    HPROF_ASSERT(frame_index != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    new_element.frame_index      = frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    new_element.method           = method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    new_element.method_start_time= method_start_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    new_element.time_in_callees  = (jlong)0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    stack_push(stack, &new_element);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
static Stack *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
insure_method_on_stack(jthread thread, TlsInfo *info, jlong current_time,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                FrameIndex frame_index, jmethodID method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    StackElement  element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    void         *p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    int           depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    int           count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    int           fcount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    int           i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    Stack         *new_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    Stack         *stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    stack = info->stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    /* If this method is on the stack, just return */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    depth   = stack_depth(stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    p = stack_top(stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    if ( p != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        if ( element.frame_index == frame_index ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            return stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    for ( i = 0 ; i < depth ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        p = stack_element(stack, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        if ( element.frame_index == frame_index ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            return stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    /* It wasn't found, create a new stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    getFrameCount(thread, &count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    if ( count <= 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        HPROF_ERROR(JNI_FALSE, "no frames, method can't be on stack");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    setup_trace_buffers(info, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    getStackTrace(thread, info->jframes_buffer, count, &fcount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    HPROF_ASSERT(count==fcount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    /* Create a new stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    new_stack = stack_init(INITIAL_THREAD_STACK_LIMIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                            INITIAL_THREAD_STACK_LIMIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                            (int)sizeof(StackElement));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    for ( i = count-1; i >= 0 ; i-- ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        push_method(new_stack, current_time, info->jframes_buffer[i].method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    if ( depth > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        for ( i = depth-1 ; i >= 0; i-- ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            stack_push(new_stack, stack_element(stack, i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    stack_term(stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    return new_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
pop_method(TlsIndex index, jlong current_time, jmethodID method, FrameIndex frame_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    SerialNumber  thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    TlsInfo  *    info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    StackElement  element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    void         *p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    int           depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    int           trace_depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    jlong         total_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    jlong         self_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    int           i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    TraceIndex    trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    HPROF_ASSERT(frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    thread_serial_num  = get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    info               = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    HPROF_ASSERT(info->stack!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    depth   = stack_depth(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    p = stack_pop(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    if (p == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        HPROF_ERROR(JNI_FALSE, "method return tracked, but stack is empty");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    HPROF_ASSERT(element.frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    /* The depth of frames we should keep track for reporting */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    if (gdata->prof_trace_depth > depth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        trace_depth = depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        trace_depth = gdata->prof_trace_depth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    /* Create a trace entry */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    HPROF_ASSERT(info->frames_buffer!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    HPROF_ASSERT(info->jframes_buffer!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    setup_trace_buffers(info, trace_depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    info->frames_buffer[0] = element.frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    for (i = 1; i < trace_depth; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        StackElement e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        e = *(StackElement*)stack_element(info->stack, (depth - i) - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        info->frames_buffer[i] = e.frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        HPROF_ASSERT(e.frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    trace_index = trace_find_or_create(thread_serial_num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                    trace_depth, info->frames_buffer, info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    /* Calculate time spent */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    total_time = current_time - element.method_start_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    if ( total_time < 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        total_time = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        self_time = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        self_time = total_time - element.time_in_callees;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    /* Update stats */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    p = stack_top(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    if ( p != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        adjust_stats(total_time, self_time, trace_index, (StackElement*)p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        adjust_stats(total_time, self_time, trace_index, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
dump_thread_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
    SerialNumber thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    jthread      thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    JNIEnv      *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    HPROF_ASSERT(key_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    env                  = (JNIEnv*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    thread_serial_num    = *(SerialNumber*)key_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    info                 = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    thread               = newLocalReference(env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        jint         threadState;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        SerialNumber trace_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        getThreadState(thread, &threadState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        /* A 0 trace at this time means the thread is in unknown territory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
         *   The trace serial number MUST be a valid serial number, so we use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
         *   the system trace (empty) just so it has a valid trace.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        if ( info->last_trace == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            trace_serial_num = trace_get_serial_number(gdata->system_trace_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            trace_serial_num = trace_get_serial_number(info->last_trace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        io_write_monitor_dump_thread_state(thread_serial_num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                       trace_serial_num, threadState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        deleteLocalReference(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
static SerialNumber
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
get_serial_number(JNIEnv *env, jthread thread)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    TlsIndex     index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    if ( thread == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        return gdata->unknown_thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    index = tls_find_or_create(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    return get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
dump_monitor_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    jthread  thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    JNIEnv  *env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    env = (JNIEnv*)arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    info = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    thread = newLocalReference(env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        jobject *objects;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        jint     ocount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        int      i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        getOwnedMonitorInfo(thread, &objects, &ocount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        if ( ocount > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            for ( i = 0 ; i < ocount ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                jvmtiMonitorUsage usage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                SerialNumber *waiter_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                SerialNumber *notify_waiter_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                int           t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                char *        sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                WITH_LOCAL_REFS(env, 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                    jclass clazz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                    clazz = getObjectClass(env, objects[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                    getClassSignature(clazz, &sig, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                } END_WITH_LOCAL_REFS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                getObjectMonitorUsage(objects[i], &usage);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                waiter_nums = HPROF_MALLOC(usage.waiter_count*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                                        (int)sizeof(SerialNumber)+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                for ( t = 0 ; t < usage.waiter_count ; t++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                    waiter_nums[t] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                        get_serial_number(env, usage.waiters[t]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                notify_waiter_nums = HPROF_MALLOC(usage.notify_waiter_count*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                                        (int)sizeof(SerialNumber)+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                for ( t = 0 ; t < usage.notify_waiter_count ; t++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                    notify_waiter_nums[t] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                        get_serial_number(env, usage.notify_waiters[t]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                io_write_monitor_dump_state(sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                       get_serial_number(env, usage.owner),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                       usage.entry_count,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                       waiter_nums, usage.waiter_count,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                       notify_waiter_nums, usage.notify_waiter_count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                jvmtiDeallocate(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                jvmtiDeallocate(usage.waiters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                jvmtiDeallocate(usage.notify_waiters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                HPROF_FREE(waiter_nums);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                HPROF_FREE(notify_waiter_nums);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        jvmtiDeallocate(objects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        deleteLocalReference(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
static jlong
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
monitor_time(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    jlong mtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
    mtime = md_get_timemillis(); /* gettimeofday() */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    return mtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
static jlong
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
method_time(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    jlong method_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    method_time = md_get_thread_cpu_timemillis(); /* thread CPU time */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    return method_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
/* External interfaces */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
TlsIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
tls_find_or_create(JNIEnv *env, jthread thread)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    SerialNumber    thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    static TlsInfo  empty_info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    TlsInfo         info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    TlsIndex        index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    HPROF_ASSERT(thread!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    /*LINTED*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    index = (TlsIndex)(ptrdiff_t)getThreadLocalStorage(thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    if ( index != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        HPROF_ASSERT(isSameObject(env, thread, get_info(index)->globalref));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        return index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    index = search(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    if ( index != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        return index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    thread_serial_num      = gdata->thread_serial_number_counter++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    info                   = empty_info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    info.monitor_index     = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    info.sample_status     = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    info.agent_thread      = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    info.stack             = stack_init(INITIAL_THREAD_STACK_LIMIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                                INITIAL_THREAD_STACK_LIMIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                                (int)sizeof(StackElement));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    setup_trace_buffers(&info, gdata->max_trace_depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    info.globalref = newWeakGlobalReference(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    index = table_create_entry(gdata->tls_table, &thread_serial_num, (int)sizeof(SerialNumber), (void*)&info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    HPROF_ASSERT(search(env,thread)==index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    return index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
/* Mark a new or existing entry as being an agent thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
tls_agent_thread(JNIEnv *env, jthread thread)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    TlsIndex  index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    index              = tls_find_or_create(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    info               = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    info->agent_thread = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
tls_init(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    gdata->tls_table = table_initialize("TLS",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                            16, 16, 16, (int)sizeof(TlsInfo));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
tls_list(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    debug_message(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        "--------------------- TLS Table ------------------------\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    table_walk_items(gdata->tls_table, &list_item, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    debug_message(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        "----------------------------------------------------------\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
tls_sum_sample_status(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    jint sample_status_total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    sample_status_total = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    table_walk_items(gdata->tls_table, &sum_sample_status_item, (void*)&sample_status_total);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    return sample_status_total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
tls_set_sample_status(ObjectIndex object_index, jint sample_status)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    SampleData  data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    data.thread_object_index = object_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    data.sample_status       = sample_status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    table_walk_items(gdata->tls_table, &sample_setter, (void*)&data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
tls_get_tracker_status(JNIEnv *env, jthread thread, jboolean skip_init,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        jint **ppstatus, TlsIndex* pindex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        SerialNumber *pthread_serial_num, TraceIndex *ptrace_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    TlsInfo      *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    TlsIndex      index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    SerialNumber  thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    jint          status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    index             = tls_find_or_create(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    info              = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    *ppstatus         = &(info->tracker_status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    status            = **ppstatus;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    thread_serial_num = get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    if ( pindex != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        *pindex = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    if ( status != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    if ( ptrace_index != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        setup_trace_buffers(info, gdata->max_trace_depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        *ptrace_index = get_trace(thread, thread_serial_num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                            gdata->max_trace_depth, skip_init,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                            info->frames_buffer, info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    if ( pthread_serial_num != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        *pthread_serial_num = thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
    return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
MonitorIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
tls_get_monitor(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
    return info->monitor_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
tls_set_thread_object_index(TlsIndex index, ObjectIndex thread_object_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    info->thread_object_index = thread_object_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
SerialNumber
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
tls_get_thread_serial_number(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    return get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
tls_set_monitor(TlsIndex index, MonitorIndex monitor_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    info->monitor_index = monitor_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
tls_cleanup(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
    table_cleanup(gdata->tls_table, &cleanup_item, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    gdata->tls_table = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
tls_delete_global_references(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    table_walk_items(gdata->tls_table, &delete_ref_item, (void*)env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
tls_thread_ended(JNIEnv *env, TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
    /* Sample thread stack for last time, do NOT free the entry yet. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
    table_lock_enter(gdata->tls_table); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        SerialNumber thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        jthread      thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        thread_serial_num = get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        info              = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        thread            = newLocalReference(env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        if (gdata->heap_dump && thread!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            setup_trace_buffers(info, gdata->max_trace_depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            info->last_trace = get_trace(thread, thread_serial_num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                                    gdata->max_trace_depth, JNI_FALSE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                                    info->frames_buffer, info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            deleteLocalReference(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    } table_lock_exit(gdata->tls_table);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
/* Sample ALL threads and update the trace costs */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
tls_sample_all_threads(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
    ThreadList    list;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    jthread      *threads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    SerialNumber *serial_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    table_lock_enter(gdata->tls_table); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        int           max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        int           nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        int           i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        /* Get buffers to hold thread list and serial number list */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        max_count   = table_element_count(gdata->tls_table);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        nbytes      = (int)sizeof(jthread)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        threads     = (jthread*)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        nbytes      = (int)sizeof(SerialNumber)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
        serial_nums = (SerialNumber*)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        /* Get list of threads and serial numbers */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        list.threads     = threads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        list.infos       = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        list.serial_nums = serial_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        list.count       = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        list.env         = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        table_walk_items(gdata->tls_table, &get_thread_list, (void*)&list);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        /* Increment the cost on the traces for these threads */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        trace_increment_all_sample_costs(list.count, threads, serial_nums,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
                              gdata->max_trace_depth, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        /* Loop over local refs and free them */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        for ( i = 0 ; i < list.count ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
            if ( threads[i] != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                deleteLocalReference(env, threads[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    } table_lock_exit(gdata->tls_table);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    /* Free up allocated space */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    HPROF_FREE(threads);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    HPROF_FREE(serial_nums);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
tls_push_method(TlsIndex index, jmethodID method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
    jlong    method_start_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    info        = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    method_start_time  = method_time();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    HPROF_ASSERT(info->stack!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
    push_method(info->stack, method_start_time, method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
tls_pop_exception_catch(TlsIndex index, jthread thread, jmethodID method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    TlsInfo      *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    StackElement  element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
    void         *p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
    FrameIndex    frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    jlong         current_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    frame_index = frame_find_or_create(method, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
    HPROF_ASSERT(frame_index != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
    HPROF_ASSERT(info->stack!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
    HPROF_ASSERT(frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
    current_time = method_time();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    info->stack = insure_method_on_stack(thread, info, current_time,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
                        frame_index, method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    p = stack_top(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    if (p == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        HPROF_ERROR(JNI_FALSE, "expection pop, nothing on stack");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    HPROF_ASSERT(element.frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    while ( element.frame_index != frame_index ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        pop_method(index, current_time, element.method, frame_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        p = stack_top(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
        if ( p == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    if (p == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        HPROF_ERROR(JNI_FALSE, "exception pop stack empty");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
tls_pop_method(TlsIndex index, jthread thread, jmethodID method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    TlsInfo      *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    StackElement  element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    void         *p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    FrameIndex    frame_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    jlong         current_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    HPROF_ASSERT(method!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    frame_index = frame_find_or_create(method, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    HPROF_ASSERT(frame_index != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    HPROF_ASSERT(info->stack!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    current_time = method_time();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    HPROF_ASSERT(frame_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    info->stack = insure_method_on_stack(thread, info, current_time,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                frame_index, method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    p = stack_top(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    HPROF_ASSERT(p!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    while ( element.frame_index != frame_index ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        pop_method(index, current_time, element.method, frame_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        p = stack_top(info->stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
        if ( p == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        element = *(StackElement*)p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
    pop_method(index, current_time, method, frame_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
/* For all TLS entries, update the last_trace on all threads */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
update_all_last_traces(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    jthread        *threads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
    TlsInfo       **infos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    SerialNumber   *serial_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
    TraceIndex     *traces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
    if ( gdata->max_trace_depth == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    table_lock_enter(gdata->tls_table); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        ThreadList      list;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        int             max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        int             nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
        int             i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
        /* Get buffers to hold thread list and serial number list */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
        max_count   = table_element_count(gdata->tls_table);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
        nbytes      = (int)sizeof(jthread)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        threads     = (jthread*)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
        nbytes      = (int)sizeof(SerialNumber)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
        serial_nums = (SerialNumber*)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
        nbytes      = (int)sizeof(TlsInfo*)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
        infos       = (TlsInfo**)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
        /* Get list of threads, serial numbers, and info pointers */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        list.threads     = threads;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
        list.serial_nums = serial_nums;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        list.infos       = infos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
        list.count       = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        list.env         = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
        table_walk_items(gdata->tls_table, &get_thread_list, (void*)&list);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
        /* Get all stack trace index's for all these threadss */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        nbytes      = (int)sizeof(TraceIndex)*max_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        traces      = (TraceIndex*)HPROF_MALLOC(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        trace_get_all_current(list.count, threads, serial_nums,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                              gdata->max_trace_depth, JNI_FALSE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                              traces, JNI_TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        /* Loop over traces and update last_trace's */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        for ( i = 0 ; i < list.count ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
            if ( threads[i] != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                deleteLocalReference(env, threads[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            infos[i]->last_trace = traces[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
    } table_lock_exit(gdata->tls_table);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
    /* Free up all allocated space */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
    HPROF_FREE(threads);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    HPROF_FREE(serial_nums);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
    HPROF_FREE(infos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    HPROF_FREE(traces);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
tls_dump_traces(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    rawMonitorEnter(gdata->data_access_lock); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
        update_all_last_traces(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
        trace_output_unmarked(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
    } rawMonitorExit(gdata->data_access_lock);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
tls_dump_monitor_state(JNIEnv *env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
    HPROF_ASSERT(env!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    rawMonitorEnter(gdata->data_access_lock); {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        tls_dump_traces(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        io_write_monitor_dump_header();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        table_walk_items(gdata->tls_table, &dump_thread_state, (void*)env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
        table_walk_items(gdata->tls_table, &dump_monitor_state, (void*)env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        io_write_monitor_dump_footer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
    } rawMonitorExit(gdata->data_access_lock);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
tls_monitor_start_timer(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
    HPROF_ASSERT(info->globalref!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
    info->monitor_start_time = monitor_time();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
jlong
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
tls_monitor_stop_timer(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
    jlong    t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
    t =  monitor_time() - info->monitor_start_time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    info->monitor_start_time = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
TraceIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
tls_get_trace(TlsIndex index, JNIEnv *env, int depth, jboolean skip_init)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
    SerialNumber thread_serial_num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
    TraceIndex   trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
    TlsInfo     *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
    jthread      thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
    thread_serial_num = get_key(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    info              = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
    HPROF_ASSERT(info!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
    setup_trace_buffers(info, depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
    thread = newLocalReference(env, info->globalref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
    if ( thread != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
        trace_index = get_trace(thread, thread_serial_num, depth, skip_init,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                        info->frames_buffer, info->jframes_buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
        deleteLocalReference(env, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        trace_index = gdata->system_trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
    return trace_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
tls_set_in_heap_dump(TlsIndex index, jint in_heap_dump)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
    info->in_heap_dump = in_heap_dump;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
tls_get_in_heap_dump(TlsIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    TlsInfo  *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
    info = get_info(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
    return info->in_heap_dump;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
clean_in_heap_dump(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
    TlsInfo *info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
    HPROF_ASSERT(info_ptr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
    info  = (TlsInfo*)info_ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    info->in_heap_dump = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
tls_clear_in_heap_dump(void)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
    table_walk_items(gdata->tls_table, &clean_in_heap_dump, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
TlsIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
tls_find(SerialNumber thread_serial_num)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
    TlsIndex index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
    if ( thread_serial_num == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
    index = table_find_entry(gdata->tls_table,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
          (void*)&thread_serial_num, (int)sizeof(SerialNumber));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
    return index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
}