This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 212480
Collapse All | Expand All

(-)a/lib.profiler/native/src-jdk15/Stacks.c (-30 / +9 lines)
Lines 82-89 Link Here
82
82
83
#define MAX_FRAMES 100
83
#define MAX_FRAMES 100
84
84
85
static jvmtiFrameInfo *_stack_frames_buffer = NULL;
85
static jint stackSizeInFrames = 0;
86
static jint *_stack_id_buffer = NULL;
87
static jclass threadType = NULL;
86
static jclass threadType = NULL;
88
static jclass intArrType = NULL;
87
static jclass intArrType = NULL;
89
static long base_addresses[NO_OF_BASE_ADDRESS]={-1L,-1L,-1L,-1L};
88
static long base_addresses[NO_OF_BASE_ADDRESS]={-1L,-1L,-1L,-1L};
Lines 148-182 Link Here
148
 * Method:    createNativeStackFrameBuffer
147
 * Method:    createNativeStackFrameBuffer
149
 * Signature: (I)V
148
 * Signature: (I)V
150
 */
149
 */
151
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_createNativeStackFrameBuffer
150
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_setStackFrameBufferSize
152
    (JNIEnv *env, jclass clz, jint sizeInFrames)
151
    (JNIEnv *env, jclass clz, jint sizeInFrames)
153
{
152
{
154
    if (_stack_frames_buffer != NULL) {
153
    stackSizeInFrames = sizeInFrames;
155
        Java_org_netbeans_lib_profiler_server_system_Stacks_clearNativeStackFrameBuffer(env, clz);
156
    }
157
    _stack_frames_buffer = calloc(sizeInFrames, sizeof(jvmtiFrameInfo));
158
    _stack_id_buffer = calloc(sizeInFrames, sizeof(jint));
159
}
154
}
160
155
161
156
162
/*
163
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
164
 * Method:    clearNativeStackFrameBuffer
165
 * Signature: ()V
166
 */
167
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_clearNativeStackFrameBuffer
168
    (JNIEnv *env, jclass clz)
169
{
170
    if (_stack_frames_buffer != NULL) {
171
        free(_stack_frames_buffer);
172
    }
173
    if (_stack_id_buffer != NULL) {
174
        free(_stack_id_buffer);
175
    }
176
    _stack_frames_buffer = NULL;
177
    _stack_id_buffer = NULL;
178
}
179
180
157
181
/*
158
/*
182
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
159
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
Lines 187-203 Link Here
187
    (JNIEnv *env, jclass clz, jthread jni_thread, jint depth, jintArray ret)
164
    (JNIEnv *env, jclass clz, jthread jni_thread, jint depth, jintArray ret)
188
{
165
{
189
    jint i, count;
166
    jint i, count;
190
    if (_stack_frames_buffer == NULL) {
167
    jvmtiFrameInfo *_stack_frames_buffer;
191
        /* Can happen if profiling stopped concurrently */
168
    jint *_stack_id_buffer;
192
        return 0;
193
    }
194
169
170
    _stack_frames_buffer = calloc(stackSizeInFrames, sizeof(jvmtiFrameInfo));
171
    _stack_id_buffer = calloc(stackSizeInFrames, sizeof(jint));
195
    (*_jvmti)->GetStackTrace(_jvmti, jni_thread, 0, depth, _stack_frames_buffer, &count);
172
    (*_jvmti)->GetStackTrace(_jvmti, jni_thread, 0, depth, _stack_frames_buffer, &count);
196
173
197
    for (i = 0; i < count; i++) {
174
    for (i = 0; i < count; i++) {
198
        _stack_id_buffer[i] = convert_jmethodID_to_jint(_stack_frames_buffer[i].method);
175
        _stack_id_buffer[i] = convert_jmethodID_to_jint(_stack_frames_buffer[i].method);
199
    }
176
    }
200
    (*env)->SetIntArrayRegion(env, ret, 0, count, _stack_id_buffer);
177
    (*env)->SetIntArrayRegion(env, ret, 0, count, _stack_id_buffer);
178
    free(_stack_frames_buffer);
179
    free(_stack_id_buffer);
201
180
202
    return count;
181
    return count;
203
}
182
}
(-)a/lib.profiler/native/src-jdk15/org_netbeans_lib_profiler_server_system_Stacks.h (-9 / +1 lines)
Lines 84-101 Link Here
84
84
85
/*
85
/*
86
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
86
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
87
 * Method:    clearNativeStackFrameBuffer
88
 * Signature: ()V
89
 */
90
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_clearNativeStackFrameBuffer
91
  (JNIEnv *, jclass);
92
93
/*
94
 * Class:     org_netbeans_lib_profiler_server_system_Stacks
95
 * Method:    createNativeStackFrameBuffer
87
 * Method:    createNativeStackFrameBuffer
96
 * Signature: (I)V
88
 * Signature: (I)V
97
 */
89
 */
98
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_createNativeStackFrameBuffer
90
JNIEXPORT void JNICALL Java_org_netbeans_lib_profiler_server_system_Stacks_setStackFrameBufferSize
99
  (JNIEnv *, jclass, jint);
91
  (JNIEnv *, jclass, jint);
100
92
101
#ifdef __cplusplus
93
#ifdef __cplusplus
(-)a/lib.profiler/src/org/netbeans/lib/profiler/results/memory/MemoryDataFrameProcessor.java (+12 lines)
Lines 54-59 Link Here
54
 * @author Jaroslav Bachorik
54
 * @author Jaroslav Bachorik
55
 */
55
 */
56
public class MemoryDataFrameProcessor extends AbstractDataFrameProcessor {
56
public class MemoryDataFrameProcessor extends AbstractDataFrameProcessor {
57
    //~ Instance fields ----------------------------------------------------------------------------------------------------------
58
59
    private volatile int currentThreadId = -1;
57
    //~ Methods ------------------------------------------------------------------------------------------------------------------
60
    //~ Methods ------------------------------------------------------------------------------------------------------------------
58
61
59
    public void doProcessDataFrame(byte[] buffer) {
62
    public void doProcessDataFrame(byte[] buffer) {
Lines 166-171 Link Here
166
169
167
                    break;
170
                    break;
168
                }
171
                }
172
                case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {
173
                    if (LOGGER.isLoggable(Level.FINEST)) {
174
                        LOGGER.log(Level.FINEST, "Change current thread , tId={0}", currentThreadId); // NOI18N
175
                    }
176
177
                    currentThreadId = (char) ((((int) buffer[curPos++] & 0xFF) << 8) | ((int) buffer[curPos++] & 0xFF));
178
179
                    break;
180
                }
169
                default: {
181
                default: {
170
                    LOGGER.severe("*** Profiler Engine: internal error: got unknown event type in MemoryDataFrameProcessor: " // NOI18N
182
                    LOGGER.severe("*** Profiler Engine: internal error: got unknown event type in MemoryDataFrameProcessor: " // NOI18N
171
                                  + (int) eventType
183
                                  + (int) eventType
(-)a/lib.profiler/src/org/netbeans/lib/profiler/server/ProfilerRuntimeMemory.java (-81 / +112 lines)
Lines 67-74 Link Here
67
    protected static char[] objectSize;
67
    protected static char[] objectSize;
68
    protected static short samplingInterval;
68
    protected static short samplingInterval;
69
    protected static int samplingDepth;
69
    protected static int samplingDepth;
70
    private static int stackDepth;
71
    private static int[] stackFrameIds;
72
    private static Map classIdMap;
70
    private static Map classIdMap;
73
71
74
    // -------------------------------------- Miscellaneous support routines ------------------------------------------
72
    // -------------------------------------- Miscellaneous support routines ------------------------------------------
Lines 84-92 Link Here
84
        if (aic == null) {
82
        if (aic == null) {
85
            allocatedInstThreshold = null;
83
            allocatedInstThreshold = null;
86
            objectSize = null;
84
            objectSize = null;
87
            stackFrameIds = null;
88
            Stacks.clearNativeStackFrameBuffer();
89
90
            return;
85
            return;
91
        } else if (allocatedInstArrayLength < aic.length) {
86
        } else if (allocatedInstArrayLength < aic.length) {
92
            short[] oldThresh = (allocatedInstThreshold != null) ? allocatedInstThreshold : null;
87
            short[] oldThresh = (allocatedInstThreshold != null) ? allocatedInstThreshold : null;
Lines 117-124 Link Here
117
            if (val > MAX_STACK_FRAMES) {
112
            if (val > MAX_STACK_FRAMES) {
118
                val = MAX_STACK_FRAMES;
113
                val = MAX_STACK_FRAMES;
119
            }
114
            }
120
        } else {
121
            stackDepth = 0;
122
        }
115
        }
123
116
124
        samplingDepth = val;
117
        samplingDepth = val;
Lines 165-170 Link Here
165
158
166
        if (!ti.isInitialized()) {
159
        if (!ti.isInitialized()) {
167
            ti.initialize(true);
160
            ti.initialize(true);
161
            ti.useEventBuffer();
162
            ti.useStackBuffer(MAX_STACK_FRAMES);
168
        }
163
        }
169
164
170
        ti.inProfilingRuntimeMethod++;
165
        ti.inProfilingRuntimeMethod++;
Lines 201-235 Link Here
201
    // ------------------------------------------ Stack trace obtaining -----------------------------------------------
196
    // ------------------------------------------ Stack trace obtaining -----------------------------------------------
202
197
203
    /** This is used in Object Allocation profiling mode */
198
    /** This is used in Object Allocation profiling mode */
204
    protected static synchronized void getAndSendCurrentStackTrace(char classId, long objSize) {
199
    protected static void getAndSendCurrentStackTrace(ThreadInfo ti, char classId, long objSize) {
200
        int stackDepth = 0;
201
        
202
        if (eventBuffer == null) {
203
            return; // Chances are that instrumentation has been removed while we were executing instrumentation code
204
        }
205
        
206
        if (samplingDepth != 0) {
207
            stackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), samplingDepth, ti.stackFrameIds);
208
        }
209
210
        writeObjAllocStackTraceEvent(ti, classId, objSize, stackDepth);
211
    }
212
213
    /** This is used in Object Liveness profiling mode */
214
    protected static void getAndSendCurrentStackTrace(ThreadInfo ti, char classId, char epoch, int objCount, long objSize) {
215
        int stackDepth = 0;
216
205
        if (eventBuffer == null) {
217
        if (eventBuffer == null) {
206
            return; // Chances are that instrumentation has been removed while we were executing instrumentation code
218
            return; // Chances are that instrumentation has been removed while we were executing instrumentation code
207
        }
219
        }
208
220
209
        synchronized (eventBuffer) { // Note that we have to use synchronization here due to the static stackFrameIds[] array
221
        if (samplingDepth != 0) {
210
222
            stackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), samplingDepth, ti.stackFrameIds);
211
            if (samplingDepth != 0) {
212
                stackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), samplingDepth, stackFrameIds);
213
            }
214
215
            writeObjAllocStackTraceEvent(classId, objSize);
216
        }
217
    }
218
219
    /** This is used in Object Liveness profiling mode */
220
    protected static synchronized void getAndSendCurrentStackTrace(char classId, char epoch, int objCount, long objSize) {
221
        if (eventBuffer == null) {
222
            return; // Chances are that instrumentation has been removed while we were executing instrumentation code
223
        }
223
        }
224
224
225
        synchronized (eventBuffer) { // Note that we have to use synchronization here due to the static stackFrameIds[] array
225
        writeObjLivenessStackTraceEvent(ti, classId, epoch, objCount, objSize, stackDepth);
226
227
            if (samplingDepth != 0) {
228
                stackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), samplingDepth, stackFrameIds);
229
            }
230
231
            writeObjLivenessStackTraceEvent(classId, epoch, objCount, objSize);
232
        }
233
    }
226
    }
234
227
235
    protected static long getCachedObjectSize(char classId, Object object) {
228
    protected static long getCachedObjectSize(char classId, Object object) {
Lines 263-276 Link Here
263
    protected static void clearDataStructures() {
256
    protected static void clearDataStructures() {
264
        ProfilerRuntime.clearDataStructures();
257
        ProfilerRuntime.clearDataStructures();
265
        allocatedInstancesCount = null;
258
        allocatedInstancesCount = null;
266
        stackFrameIds = null;
267
        Stacks.clearNativeStackFrameBuffer();
268
    }
259
    }
269
260
270
    protected static void createNewDataStructures() {
261
    protected static void createNewDataStructures() {
271
        ProfilerRuntime.createNewDataStructures();
262
        ProfilerRuntime.createNewDataStructures();
272
        stackFrameIds = new int[MAX_STACK_FRAMES];
263
        Stacks.setStackFrameBufferSize(MAX_STACK_FRAMES);
273
        Stacks.createNativeStackFrameBuffer(MAX_STACK_FRAMES);
274
        classIdMap = new HashMap();
264
        classIdMap = new HashMap();
275
    }
265
    }
276
266
Lines 323-330 Link Here
323
313
324
    // ---------------------------------------- Writing profiler events -----------------------------------------
314
    // ---------------------------------------- Writing profiler events -----------------------------------------
325
315
326
    /** Note that there is no synchronized(eventBuffer) in this method, since synchronization is already required by its callers */
316
    protected static void writeObjAllocStackTraceEvent(ThreadInfo ti, char classId, long objSize, int stackDepth) {
327
    protected static void writeObjAllocStackTraceEvent(char classId, long objSize) {
328
        if (eventBuffer == null) {
317
        if (eventBuffer == null) {
329
            return; // Instrumentation removal happened when we were in instrumentation 
318
            return; // Instrumentation removal happened when we were in instrumentation 
330
        }
319
        }
Lines 337-361 Link Here
337
            ProfilerServer.notifyClientOnResultsAvailability();
326
            ProfilerServer.notifyClientOnResultsAvailability();
338
        }
327
        }
339
328
340
        int curPos = globalEvBufPos;
329
        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment
341
330
342
        if ((curPos + 16 + (stackDepth * 4)) > globalEvBufPosThreshold) { // Dump the buffer
331
        if (curPos + 18 + (stackDepth * 4) > ThreadInfo.evBufPosThreshold) {
343
            externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);
332
            copyLocalBuffer(ti);
344
            curPos = 0;
333
            curPos = ti.evBufPos;
345
        }
334
        }
346
335
347
        eventBuffer[curPos++] = OBJ_ALLOC_STACK_TRACE;
336
        byte[] evBuf = ti.evBuf;
348
        eventBuffer[curPos++] = (byte) ((classId >> 8) & 0xFF);
337
        if (!ti.isInitialized()) return;    // Reset collectors performed when we were already executing instrumentation code 
349
        eventBuffer[curPos++] = (byte) ((classId) & 0xFF);
350
338
351
        eventBuffer[curPos++] = (byte) ((objSize >> 32) & 0xFF);
339
        evBuf[curPos++] = OBJ_ALLOC_STACK_TRACE;
352
        eventBuffer[curPos++] = (byte) ((objSize >> 24) & 0xFF);
340
        evBuf[curPos++] = (byte) ((classId >> 8) & 0xFF);
353
        eventBuffer[curPos++] = (byte) ((objSize >> 16) & 0xFF);
341
        evBuf[curPos++] = (byte) ((classId) & 0xFF);
354
        eventBuffer[curPos++] = (byte) ((objSize >> 8) & 0xFF);
355
        eventBuffer[curPos++] = (byte) (objSize & 0xFF);
356
342
357
        curPos = writeStack(curPos);
343
        evBuf[curPos++] = (byte) ((objSize >> 32) & 0xFF);
358
        globalEvBufPos = curPos;
344
        evBuf[curPos++] = (byte) ((objSize >> 24) & 0xFF);
345
        evBuf[curPos++] = (byte) ((objSize >> 16) & 0xFF);
346
        evBuf[curPos++] = (byte) ((objSize >> 8) & 0xFF);
347
        evBuf[curPos++] = (byte) (objSize & 0xFF);
348
349
        curPos = writeStack(evBuf, curPos, ti, stackDepth);
350
        ti.evBufPos = curPos;
359
    }
351
    }
360
352
361
    protected static void writeObjGCEvent(long objectId) {
353
    protected static void writeObjGCEvent(long objectId) {
Lines 384-391 Link Here
384
        }
376
        }
385
    }
377
    }
386
378
387
    /** Note that there is no synchronized(eventBuffer) in this method, since synchronization is already required by its callers */
379
    protected static void writeObjLivenessStackTraceEvent(ThreadInfo ti, char classId, char epoch, int objCount, long objSize, int stackDepth) {
388
    protected static void writeObjLivenessStackTraceEvent(char classId, char epoch, int objCount, long objSize) {
389
        if (eventBuffer == null) {
380
        if (eventBuffer == null) {
390
            return; // Instrumentation removal happened when we were in instrumentation 
381
            return; // Instrumentation removal happened when we were in instrumentation 
391
        }
382
        }
Lines 398-434 Link Here
398
            ProfilerServer.notifyClientOnResultsAvailability();
389
            ProfilerServer.notifyClientOnResultsAvailability();
399
        }
390
        }
400
391
401
        int curPos = globalEvBufPos;
392
        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment
402
393
403
        if ((curPos + 24 + (stackDepth * 4)) > globalEvBufPosThreshold) { // Dump the buffer
394
        if (curPos + 24 + (stackDepth * 4) > ThreadInfo.evBufPosThreshold) {
404
            externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);
395
            copyLocalBuffer(ti);
405
            curPos = 0;
396
            curPos = ti.evBufPos;
406
        }
397
        }
407
398
408
        eventBuffer[curPos++] = OBJ_LIVENESS_STACK_TRACE;
399
        byte[] evBuf = ti.evBuf;
409
        eventBuffer[curPos++] = (byte) ((classId >> 8) & 0xFF);
400
        if (!ti.isInitialized()) return;    // Reset collectors performed when we were already executing instrumentation code 
410
        eventBuffer[curPos++] = (byte) ((classId) & 0xFF);
411
        eventBuffer[curPos++] = (byte) ((epoch >> 8) & 0xFF);
412
        eventBuffer[curPos++] = (byte) ((epoch) & 0xFF);
413
        eventBuffer[curPos++] = (byte) ((objCount >> 24) & 0xFF);
414
        eventBuffer[curPos++] = (byte) ((objCount >> 16) & 0xFF);
415
        eventBuffer[curPos++] = (byte) ((objCount >> 8) & 0xFF);
416
        eventBuffer[curPos++] = (byte) ((objCount) & 0xFF);
417
401
418
        eventBuffer[curPos++] = (byte) ((objSize >> 32) & 0xFF);
402
        evBuf[curPos++] = OBJ_LIVENESS_STACK_TRACE;
419
        eventBuffer[curPos++] = (byte) ((objSize >> 24) & 0xFF);
403
        evBuf[curPos++] = (byte) ((classId >> 8) & 0xFF);
420
        eventBuffer[curPos++] = (byte) ((objSize >> 16) & 0xFF);
404
        evBuf[curPos++] = (byte) ((classId) & 0xFF);
421
        eventBuffer[curPos++] = (byte) ((objSize >> 8) & 0xFF);
405
        evBuf[curPos++] = (byte) ((epoch >> 8) & 0xFF);
422
        eventBuffer[curPos++] = (byte) (objSize & 0xFF);
406
        evBuf[curPos++] = (byte) ((epoch) & 0xFF);
407
        evBuf[curPos++] = (byte) ((objCount >> 24) & 0xFF);
408
        evBuf[curPos++] = (byte) ((objCount >> 16) & 0xFF);
409
        evBuf[curPos++] = (byte) ((objCount >> 8) & 0xFF);
410
        evBuf[curPos++] = (byte) ((objCount) & 0xFF);
423
411
424
        curPos = writeStack(curPos);
412
        evBuf[curPos++] = (byte) ((objSize >> 32) & 0xFF);
425
        globalEvBufPos = curPos;
413
        evBuf[curPos++] = (byte) ((objSize >> 24) & 0xFF);
414
        evBuf[curPos++] = (byte) ((objSize >> 16) & 0xFF);
415
        evBuf[curPos++] = (byte) ((objSize >> 8) & 0xFF);
416
        evBuf[curPos++] = (byte) (objSize & 0xFF);
417
418
        curPos = writeStack(evBuf, curPos, ti, stackDepth);
419
        ti.evBufPos = curPos;
426
    }
420
    }
427
421
428
    private static int writeStack(int curPos) {
422
    protected static void copyLocalBuffer(ThreadInfo ti) {
429
        eventBuffer[curPos++] = (byte) ((stackDepth >> 16) & 0xFF);
423
        // Copy the local buffer into the main buffer - however avoid doing that if we have already reset profiler collectors
430
        eventBuffer[curPos++] = (byte) ((stackDepth >> 8) & 0xFF);
424
        if (eventBuffer == null) {
431
        eventBuffer[curPos++] = (byte) ((stackDepth) & 0xFF);
425
            return;
426
        }
427
428
        synchronized (eventBuffer) {
429
            if (!ti.isInitialized()) {
430
                return; // Reset collectors performed when we were already executing instrumentation code
431
            }
432
433
            int curPos = ti.evBufPos;
434
435
            // First check if the global buffer itself needs to be dumped
436
            int evBufDumpLastPos = ti.evBufDumpLastPos;
437
438
            if (((globalEvBufPos + curPos) - evBufDumpLastPos) > globalEvBufPosThreshold) {
439
                sendingBuffer = true;
440
441
                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, globalEvBufPos);
442
                globalEvBufPos = 0;
443
                sendingBuffer = false;
444
            }
445
446
            // Finally copy the local buffer into the global one
447
            eventBuffer[globalEvBufPos++] = SET_FOLLOWING_EVENTS_THREAD;
448
            eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId >> 8) & 0xFF);
449
            eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId) & 0xFF);
450
            System.arraycopy(ti.evBuf, evBufDumpLastPos, eventBuffer, globalEvBufPos, curPos - evBufDumpLastPos);
451
            globalEvBufPos += (curPos - evBufDumpLastPos);
452
            ti.evBufPos = 0;
453
            ti.evBufDumpLastPos = 0;
454
        }
455
    }
456
457
458
    private static int writeStack(byte[] evBuf, int curPos, ThreadInfo ti, int stackDepth) {
459
        evBuf[curPos++] = (byte) ((stackDepth >> 16) & 0xFF);
460
        evBuf[curPos++] = (byte) ((stackDepth >> 8) & 0xFF);
461
        evBuf[curPos++] = (byte) ((stackDepth) & 0xFF);
432
462
433
        /// A variant when we send non-reversed call graph
463
        /// A variant when we send non-reversed call graph
434
        //int base = depth + NO_OF_PROFILER_FRAMES - 1;
464
        //int base = depth + NO_OF_PROFILER_FRAMES - 1;
Lines 437-448 Link Here
437
        //  eventBuffer[curPos++] = (char) ((stackFrameIds[base-i]) & 0xFFFF);
467
        //  eventBuffer[curPos++] = (char) ((stackFrameIds[base-i]) & 0xFFFF);
438
        //}
468
        //}
439
        int frameIdx = NO_OF_PROFILER_FRAMES;
469
        int frameIdx = NO_OF_PROFILER_FRAMES;
440
470
        int[] frames = ti.stackFrameIds;
471
        
441
        for (int i = 0; i < stackDepth; i++) {
472
        for (int i = 0; i < stackDepth; i++) {
442
            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 24) & 0xFF);
473
            evBuf[curPos++] = (byte) ((frames[frameIdx] >> 24) & 0xFF);
443
            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 16) & 0xFF);
474
            evBuf[curPos++] = (byte) ((frames[frameIdx] >> 16) & 0xFF);
444
            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 8) & 0xFF);
475
            evBuf[curPos++] = (byte) ((frames[frameIdx] >> 8) & 0xFF);
445
            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx]) & 0xFF);
476
            evBuf[curPos++] = (byte) ((frames[frameIdx]) & 0xFF);
446
            frameIdx++;
477
            frameIdx++;
447
        }
478
        }
448
479
(-)a/lib.profiler/src/org/netbeans/lib/profiler/server/ProfilerRuntimeObjAlloc.java (-1 / +3 lines)
Lines 100-105 Link Here
100
100
101
        if (!ti.isInitialized()) {
101
        if (!ti.isInitialized()) {
102
            ti.initialize(true);
102
            ti.initialize(true);
103
            ti.useEventBuffer();
104
            ti.useStackBuffer(MAX_STACK_FRAMES);
103
        }
105
        }
104
106
105
        ti.inProfilingRuntimeMethod++;
107
        ti.inProfilingRuntimeMethod++;
Lines 113-119 Link Here
113
115
114
        if (allocatedInstThreshold[classId] <= 0) {
116
        if (allocatedInstThreshold[classId] <= 0) {
115
            long objSize = getCachedObjectSize(classId, object);
117
            long objSize = getCachedObjectSize(classId, object);
116
            getAndSendCurrentStackTrace(classId, objSize);
118
            getAndSendCurrentStackTrace(ti, classId, objSize);
117
            allocatedInstThreshold[classId] = nextRandomizedInterval();
119
            allocatedInstThreshold[classId] = nextRandomizedInterval();
118
        }
120
        }
119
121
(-)a/lib.profiler/src/org/netbeans/lib/profiler/server/ProfilerRuntimeObjLiveness.java (-1 / +3 lines)
Lines 250-255 Link Here
250
250
251
        if (!ti.isInitialized()) {
251
        if (!ti.isInitialized()) {
252
            ti.initialize(true);
252
            ti.initialize(true);
253
            ti.useEventBuffer();
254
            ti.useStackBuffer(MAX_STACK_FRAMES);
253
        }
255
        }
254
256
255
        if (ti.inProfilingRuntimeMethod > 0) {
257
        if (ti.inProfilingRuntimeMethod > 0) {
Lines 278-284 Link Here
278
280
279
            long objSize = getCachedObjectSize(classId, object);
281
            long objSize = getCachedObjectSize(classId, object);
280
282
281
            getAndSendCurrentStackTrace(classId, epoch, objCount, objSize);
283
            getAndSendCurrentStackTrace(ti, classId, epoch, objCount, objSize);
282
284
283
            allocatedInstThreshold[classId] = nextRandomizedInterval();
285
            allocatedInstThreshold[classId] = nextRandomizedInterval();
284
        }
286
        }
(-)a/lib.profiler/src/org/netbeans/lib/profiler/server/ThreadInfo.java (+7 lines)
Lines 83-88 Link Here
83
83
84
    Thread thread; // Thread object for this ThreadInfo
84
    Thread thread; // Thread object for this ThreadInfo
85
    byte[] evBuf; // Thread-local event (rough profiling data) buffer. Currently used in CPU profiling only.
85
    byte[] evBuf; // Thread-local event (rough profiling data) buffer. Currently used in CPU profiling only.
86
    int[] stackFrameIds; // used im memory profiling to store allocation stacktrace
86
    boolean inCallGraph; // Indicates whether the thread is currently in the profiled subgraph
87
    boolean inCallGraph; // Indicates whether the thread is currently in the profiled subgraph
87
    boolean sampleDue; // In sampled instrumentation mode, indicates that next sampling should be done
88
    boolean sampleDue; // In sampled instrumentation mode, indicates that next sampling should be done
88
    int evBufDumpLastPos; // Used to avoid synchronization in writeEvent() and yet to allow for asynchronous event buffer dumps.
89
    int evBufDumpLastPos; // Used to avoid synchronization in writeEvent() and yet to allow for asynchronous event buffer dumps.
Lines 247-252 Link Here
247
        evBuf = new byte[evBufSize];
248
        evBuf = new byte[evBufSize];
248
    }
249
    }
249
250
251
    final void useStackBuffer(int bufferSize) {
252
        stackFrameIds = new int[bufferSize];
253
    }
254
    
250
    static int getNProfiledAppThreads() {
255
    static int getNProfiledAppThreads() {
251
        return nProfiledAppThreads;
256
        return nProfiledAppThreads;
252
    }
257
    }
Lines 349-354 Link Here
349
                            ProfilerRuntimeCPU.copyLocalBuffer(ti);
354
                            ProfilerRuntimeCPU.copyLocalBuffer(ti);
350
                        }
355
                        }
351
                        ti.evBuf = null; // release results buffer
356
                        ti.evBuf = null; // release results buffer
357
                        ti.stackFrameIds = null; // release also srackFrameIds buffer
352
                    }
358
                    }
353
                    ti.thread = null; // release dead thread
359
                    ti.thread = null; // release dead thread
354
                    hasDeadThreads = true;
360
                    hasDeadThreads = true;
Lines 445-449 Link Here
445
        rootMethodStackDepth = stackDepth = 0;
451
        rootMethodStackDepth = stackDepth = 0;
446
        inCallGraph = sampleDue = false;
452
        inCallGraph = sampleDue = false;
447
        evBuf = null;
453
        evBuf = null;
454
        stackFrameIds = null;
448
    }
455
    }
449
}
456
}
(-)a/lib.profiler/src/org/netbeans/lib/profiler/server/system/Stacks.java (-9 / +2 lines)
Lines 84-100 Link Here
84
     */
84
     */
85
    public static native void getAllStackTraces(Thread[][] threads, int[][] states, int[][][] frames);
85
    public static native void getAllStackTraces(Thread[][] threads, int[][] states, int[][][] frames);
86
    
86
    
87
    /** Clear the above stack frame buffer permanently. */
88
    public static native void clearNativeStackFrameBuffer();
89
90
    /**
87
    /**
91
     * Creates the internal, C-level stack frame buffer, used for intermediate storage of data obtained using
88
     * Sets maximum stack size
92
     * getCurrentStackFrameIds. Since just a single buffer is used, getCurrentStackFrameIds is obviously not
93
     * multithread-safe. The code that uses this stuff has to use a single lock - so far not a problem for memory
94
     * profiling where we use it, since normally it collects data for just every 10th object, thus the probability
95
     * of contention is not very high.
96
     */
89
     */
97
    public static native void createNativeStackFrameBuffer(int sizeInFrames);
90
    public static native void setStackFrameBufferSize(int sizeInFrames);
98
91
99
    /** Should be called at earliest possible time */
92
    /** Should be called at earliest possible time */
100
    public static void initialize() {
93
    public static void initialize() {

Return to bug 212480