Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/jcl/common/jcltrace.c
6000 views
1
/*******************************************************************************
2
* Copyright (c) 1998, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include <stdlib.h>
24
#include <string.h>
25
#include <ctype.h>
26
#include <assert.h>
27
28
#include "jclprots.h"
29
#include "jclglob.h"
30
#include "j9protos.h"
31
32
#define UT_TRACE_VERSION 7
33
#define MAX_APPLICATION_NAME_CHARS 256 /*ibm@94275*/
34
35
/* ibm@94077 starts */
36
#define TRACEDOTCGLOBAL(x) JCL_CACHE_GET(env, traceGlobals).x
37
38
/* Argument type codes. These are combined to build a word describing the
39
* expected argument for a particular trace point.
40
*/
41
42
#define JWORD 0x01
43
#define JDOUBLEWORD 0x02
44
#define JFLOATPOINT 0x04
45
#define JCHAR 0x08
46
#define JSTRING 0x10
47
#define JOBJECT 0x20
48
/*Pointers can be passed in as objects or double words*/
49
#define JPOINTER (JOBJECT | JDOUBLEWORD)
50
51
static I_32 CompareAndSwap32(volatile U_32 *target, U_32 old, U_32 new32);
52
53
static I_32 CompareAndSwapPtr(volatile UDATA *target, UDATA old, UDATA newptr);
54
55
/**
56
* Thread-safe array list used for mapping handles to module info structures
57
*/
58
struct ArrayList {
59
UDATA slabSize;
60
void ** header;
61
};
62
63
/*Data type function prototypes*/
64
/**
65
* Allocates new array list
66
*
67
* @param slabSize Size of each array slab
68
* @return Pointer to a new array list or NULL if there was a problem
69
*/
70
static struct ArrayList *allocArrayList(JNIEnv *const env, const UDATA slabSize);
71
72
/**
73
* Inserts an element into the array list
74
*
75
* @param list Array list to insert into
76
* @param index Location to put value
77
* @param value Value to insert
78
* @return 0 on success, non-zero on failure
79
*
80
*/
81
static IDATA arrayListPut(JNIEnv *const env, const struct ArrayList *const list, const UDATA index, void *const value);
82
83
/**
84
* Gets an element from the array list
85
*
86
* @param list Array list to get from
87
* @param index Location to get
88
* @return Value at that position or NULL if that position is not filled
89
*/
90
static void *arrayListGet(JNIEnv *const env, const struct ArrayList *const list, const UDATA index);
91
92
/* Deep frees a modInfo structure */
93
static void freeModInfo(JNIEnv *const env, UtModuleInfo *toFree);
94
95
/*Size of the slabs used to build array lists*/
96
#define SLAB_SIZE 10
97
98
#define ERROR_MESSAGE_BUFFER_LENGTH 256
99
100
/* Macros for building argument descriptors (magic values describing a sequence of arguments) for the application trace methods.
101
* This has been done as macros rather than as a function so the work can be done at compile time.
102
*/
103
#define ARGUMENT_DESCRIPTOR() 0
104
#define ARGUMENT_DESCRIPTOR_1(x) x
105
#define ARGUMENT_DESCRIPTOR_2(x, y) ((x << 8) | y)
106
#define ARGUMENT_DESCRIPTOR_3(x, y, z) ((x << 16) | (y << 8) | z)
107
108
static void
109
throwNewThrowable(JNIEnv *const env, const char *const exceptionClassName, const char *const message)
110
{
111
jclass exceptionClass = (*env)->FindClass(env, exceptionClassName);
112
113
if (NULL == exceptionClass) {
114
return;
115
}
116
117
(*env)->ThrowNew(env, exceptionClass, message);
118
}
119
120
static void
121
throwIllegalArgumentException(JNIEnv *const env, const char *const message)
122
{
123
throwNewThrowable(env, "java/lang/IllegalArgumentException", message);
124
}
125
126
static void
127
throwRuntimeException(JNIEnv *const env, const char *const message)
128
{
129
throwNewThrowable(env, "java/lang/RuntimeException", message);
130
}
131
132
/* Terminates the trace structures. Must not be called while it's still possible for an application to call register */
133
void
134
terminateTrace(JNIEnv *env)
135
{
136
int lastIndex = 0;
137
void **slab = NULL;
138
139
PORT_ACCESS_FROM_ENV(env);
140
141
if ((NULL == TRACEDOTCGLOBAL(utIntf)) || (NULL == TRACEDOTCGLOBAL(utIntf)->server)) {
142
/* nothing to be done without the interfaces, so bail */
143
return;
144
}
145
146
/* null the app trace handle count so that any attempts to trace will fail and save the tail index
147
* to iterate with
148
*/
149
do {
150
lastIndex = TRACEDOTCGLOBAL(numberOfAppTraceApplications);
151
} while (! CompareAndSwap32(&TRACEDOTCGLOBAL(numberOfAppTraceApplications), lastIndex, 0));
152
153
/* free the modInfo and argument structures */
154
for (;lastIndex > 0; lastIndex--) {
155
UtModuleInfo *modInfo = (UtModuleInfo *)arrayListGet(env, TRACEDOTCGLOBAL(modInfoList), lastIndex);
156
UDATA **callPatternsArray = (UDATA **)arrayListGet(env, TRACEDOTCGLOBAL(argumentStructureList), lastIndex);
157
158
assert((NULL != modInfo) && (NULL != callPatternsArray));
159
160
freeModInfo(env, modInfo);
161
j9mem_free_memory(callPatternsArray);
162
}
163
164
/* free the modInfo list */
165
slab = TRACEDOTCGLOBAL(modInfoList)->header;
166
while (NULL != slab) {
167
void **nextSlab = slab[TRACEDOTCGLOBAL(modInfoList)->slabSize];
168
j9mem_free_memory(slab);
169
slab = nextSlab;
170
}
171
j9mem_free_memory(TRACEDOTCGLOBAL(modInfoList));
172
173
/* free the argument structures list */
174
slab = TRACEDOTCGLOBAL(argumentStructureList)->header;
175
while (NULL != slab) {
176
void **nextSlab = slab[TRACEDOTCGLOBAL(argumentStructureList)->slabSize];
177
j9mem_free_memory(slab);
178
slab = nextSlab;
179
}
180
j9mem_free_memory(TRACEDOTCGLOBAL(argumentStructureList));
181
}
182
183
/**************************************************************************
184
* name - Java_com_ibm_jvm_Trace_initTrace
185
* description - Obtain system properties and initialize trace for JAVA.DLL
186
* parameters - JNIEnv, this
187
* returns - none
188
*************************************************************************/
189
void JNICALL
190
Java_com_ibm_jvm_Trace_initTraceImpl(JNIEnv *env, jobject this)
191
{
192
int rc = 0;
193
JavaVM *vm = NULL;
194
195
TRACEDOTCGLOBAL(rasIntf) = NULL;
196
TRACEDOTCGLOBAL(utIntf) = NULL;
197
TRACEDOTCGLOBAL(numberOfAppTraceApplications) = 0;
198
199
rc = (*env)->GetJavaVM(env, &vm);
200
if (JNI_OK == rc) {
201
/* Get RAS interface (Might not be available if trace not loaded) */
202
if ((JNI_OK == (*vm)->GetEnv(vm, (void **)&TRACEDOTCGLOBAL(rasIntf), JVMRAS_VERSION_1_3)) &&
203
(JNI_OK == (*vm)->GetEnv(vm, (void **)&TRACEDOTCGLOBAL(utIntf), UTE_VERSION_1_1))) {
204
TRACEDOTCGLOBAL(modInfoList) = allocArrayList(env, SLAB_SIZE);
205
TRACEDOTCGLOBAL(argumentStructureList) = allocArrayList(env, SLAB_SIZE);
206
207
if ((NULL == TRACEDOTCGLOBAL(modInfoList)) || (NULL == TRACEDOTCGLOBAL(argumentStructureList))) {
208
/*Exception will have been thrown*/
209
TRACEDOTCGLOBAL(utIntf) = NULL;
210
TRACEDOTCGLOBAL(rasIntf) = NULL;
211
}
212
} else {
213
TRACEDOTCGLOBAL(utIntf) = NULL;
214
TRACEDOTCGLOBAL(rasIntf) = NULL;
215
/* No option but to return silently */
216
return;
217
}
218
}
219
return;
220
}
221
222
/*
223
* Extracts UTF chars from string object and checks length against MAX_APPLICATION_NAME_CHARS
224
*
225
* @param *env [in] JNI environment
226
* @param name [in] String object
227
* @param **applicationName [out] Pointer to pointer that will be assigned with GetStringUTFChars
228
*/
229
static UDATA
230
processAndCheckNameString(JNIEnv *env, jobject name, const char **applicationName) {
231
*applicationName = (*env)->GetStringUTFChars(env, name, NULL);
232
233
if (NULL == *applicationName) {
234
return 1;
235
}
236
237
/* Check the application name does not exceed MAX_APPLICATION_NAME_CHARS */
238
if (strlen(*applicationName) > MAX_APPLICATION_NAME_CHARS) {
239
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
240
PORT_ACCESS_FROM_ENV(env);
241
242
memset(messageBuffer, 0, sizeof(messageBuffer));
243
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Application name is too long. Maximum length %d characters, supplied string was %d characters.\n", MAX_APPLICATION_NAME_CHARS, strlen(*applicationName));
244
throwIllegalArgumentException(env, messageBuffer);
245
return 2;
246
}
247
248
return 0;
249
}
250
251
/*
252
* A strcpy that won't copy beyond the end pointer
253
*
254
* @param **p [inout] Pointer to buffer to write out in
255
* @param *from [in] Buffer to copy from (must be NULL terminated
256
* @param end [in] Pointer to end of buffer *p
257
*/
258
static void
259
guardedStrcpy(char **p, const char *const from, const char *const end)
260
{
261
const char *fromCursor = from;
262
263
while ((*p < end) && (0 != ((**p) = *fromCursor))) {
264
(*p)++;
265
fromCursor++;
266
}
267
}
268
269
/*
270
* Formats a human readable version of a call pattern (as created by buildCallPattern).
271
*
272
* @param p [in] Pointer to buffer to hold the call pattern
273
* @param end [in] Pointer to end of buffer (we will not write past it)
274
* @param pattern [in] The pattern to format
275
*/
276
static void
277
formatCallPattern(char *p, char *const end, const UDATA pattern)
278
{
279
IDATA args = 0;
280
IDATA shift = 3 * 8;
281
282
for (; shift >= 0; shift -= 8) {
283
UDATA thisPattern = (pattern >> shift) & 0xFF;
284
const char *humanReadablePattern = "unknown";
285
286
switch (thisPattern) {
287
case (0) :
288
continue;
289
case (JWORD) :
290
humanReadablePattern = "word(byte/short/int)";
291
break;
292
case (JDOUBLEWORD) :
293
humanReadablePattern = "doubleword(long)";
294
break;
295
case (JOBJECT) :
296
humanReadablePattern = "object";
297
break;
298
case (JPOINTER) :
299
humanReadablePattern = "pointer(object/doubleword)";
300
break;
301
case (JFLOATPOINT) :
302
humanReadablePattern = "float/double";
303
break;
304
case (JCHAR) :
305
humanReadablePattern = "char";
306
break;
307
case (JSTRING) :
308
humanReadablePattern = "string";
309
break;
310
default:
311
/*Should be impossible*/
312
assert(0);
313
break;
314
}
315
316
if (end <= p) {
317
/* no space left */
318
break;
319
}
320
321
if (args != 0) {
322
/* a comma separator from the previous pattern */
323
*p = ',';
324
p++;
325
}
326
327
guardedStrcpy(&p, humanReadablePattern, end);
328
args += 1;
329
}
330
331
/* nul-terminate the string */
332
*p = '\0';
333
}
334
335
/**
336
* State type for printf parsing (see buildCallPattern).
337
*/
338
enum PatternParseState { FINDING_PERCENT, SKIPPING_PRECISION, READING_MODIFIER, READING_TYPE };
339
340
/*
341
* Reads a printf-style template (of up to 4 placeholders) and stores a value
342
* representing the argument sequence to *result.
343
*
344
* @param templateString [in] printf template string
345
* @param result [out] Pointer to output word
346
*/
347
static void
348
buildCallPattern(const char *const templateString, UDATA *const result)
349
{
350
int longModifierCount = 0;
351
const char *p = templateString;
352
enum PatternParseState state = FINDING_PERCENT;
353
354
*result = 0;
355
356
while (0 != *p) {
357
switch (state) {
358
case FINDING_PERCENT:
359
if ('%' == *p) {
360
longModifierCount = 0;
361
state = SKIPPING_PRECISION;
362
}
363
break;
364
case SKIPPING_PRECISION:
365
/*In this state we skip any 0-9 or .*/
366
if ('l' == *p) {
367
/*Reparse this letter in the READING_MODIFIER state*/
368
state = READING_MODIFIER;
369
continue;
370
} else if (('.' != *p) && !isdigit(*p)) {
371
state = READING_TYPE;
372
continue;
373
}
374
break;
375
case READING_MODIFIER:
376
if ('l' == *p) {
377
longModifierCount++;
378
} else {
379
state = READING_TYPE;
380
continue;
381
}
382
break;
383
case READING_TYPE:
384
{
385
unsigned char typeCode = 0;
386
switch (tolower(*p)) {
387
case 'c':
388
typeCode = JCHAR;
389
break;
390
case 'd':
391
case 'x':
392
case 'i':
393
case 'u':
394
if (longModifierCount > 1) {
395
typeCode = JDOUBLEWORD;
396
} else {
397
typeCode = JWORD;
398
}
399
break;
400
case 'p':
401
typeCode = JPOINTER;
402
break;
403
case 's':
404
typeCode = JSTRING;
405
break;
406
case 'f':
407
case 'g':
408
case 'e':
409
typeCode = JFLOATPOINT;
410
break;
411
default:
412
/*Unknown placeholder. Ignored by printf*/
413
break;
414
}
415
416
if (0 != typeCode) {
417
*result = (*result << 8) | typeCode;
418
}
419
420
state = FINDING_PERCENT;
421
break;
422
}
423
default:
424
/*This should be impossible*/
425
assert(0);
426
break;
427
}
428
429
p++;
430
}
431
}
432
433
/*
434
* Checks whether a character is a valid type character (one of ENTRY, EXIT, EVENT, EXCEPTION, EXIT_EXCEPTION)
435
*/
436
static BOOLEAN
437
isValidTypeChar(char character)
438
{
439
return ('0' == character)
440
|| ('1' == character)
441
|| ('2' == character)
442
|| ('3' == character)
443
|| ('4' == character)
444
|| ('5' == character);
445
}
446
447
/**
448
* Processes the template strings provided to registerApplication()
449
*
450
* @param *env [in] JNI environment
451
* @param templates [in] Array containing templates
452
* @param formatStringsArray [out] Pointer to array of strings. Assigned by this method and populated with the UTF version of templates
453
* @param callPatternsArray [out] Pointer to array of UDATA. Assigned by this method and populated with the call patterns for the templates.
454
* @param tracePointCount [out] Pointer to UDATA to be set to number of trace points (size of templates array)
455
*/
456
static UDATA
457
extractAndProcessFormatStrings(JNIEnv *env, jarray templates, char ***const formatStringsArray, UDATA **const callPatternsArray, UDATA *const tracePointCount)
458
{
459
UDATA i = 0;
460
UDATA rc = 0;
461
J9InternalVMFunctions *vmFuncs = ((J9VMThread *)env)->javaVM->internalVMFunctions;
462
463
PORT_ACCESS_FROM_ENV(env);
464
465
*tracePointCount = (*env)->GetArrayLength(env, templates);
466
467
if (NULL != (*env)->ExceptionOccurred(env)) {
468
return 1;
469
}
470
471
/*Allocate the two arrays. The formatStringsArray is passed to the trace engine which expects an extra NULL field at the end*/
472
*formatStringsArray = (char **)j9mem_allocate_memory(sizeof(char *) * (*tracePointCount + 1), J9MEM_CATEGORY_VM_JCL);
473
474
if (NULL == *formatStringsArray) {
475
vmFuncs->throwNativeOOMError(env, 0, 0);
476
rc = 2;
477
goto fail;
478
}
479
480
memset(*formatStringsArray, 0, sizeof(char *) * (*tracePointCount + 1));
481
482
*callPatternsArray = (UDATA *) j9mem_allocate_memory(sizeof(UDATA) * *tracePointCount, J9MEM_CATEGORY_VM_JCL);
483
484
if (NULL == *callPatternsArray) {
485
vmFuncs->throwNativeOOMError(env, 0, 0);
486
rc = 2;
487
goto fail;
488
}
489
490
memset(*callPatternsArray, 0, sizeof(UDATA) * *tracePointCount);
491
492
for (i = 0; i < *tracePointCount; i++) {
493
jobject thisString = (*env)->GetObjectArrayElement(env, templates, (jsize)i);
494
const char *jniStringCharacters = NULL;
495
496
if (NULL != (*env)->ExceptionOccurred(env)) {
497
rc = 3;
498
goto fail;
499
}
500
501
if (NULL == thisString) {
502
throwIllegalArgumentException(env, "Null string passed as trace template");
503
rc = 4;
504
goto fail;
505
}
506
507
jniStringCharacters = (*env)->GetStringUTFChars(env, thisString, NULL);
508
509
if (NULL == jniStringCharacters) {
510
rc = 5;
511
goto fail;
512
}
513
514
if (!isValidTypeChar(jniStringCharacters[0])) {
515
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
516
517
memset(messageBuffer, 0, sizeof(messageBuffer));
518
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Error: template %d does not have a valid trace prefix. Trace templates should start with one of Trace.EVENT, Trace.EXIT, Trace.ENTRY, Trace.EXCEPTION or Trace.EXCEPTION_EXIT", i);
519
throwIllegalArgumentException(env, messageBuffer);
520
}
521
522
/*Dupe the string into the array*/
523
(*formatStringsArray)[i] = (char *)j9mem_allocate_memory(strlen(jniStringCharacters) + 1, J9MEM_CATEGORY_VM_JCL);
524
525
if (NULL == (*formatStringsArray)[i]) {
526
vmFuncs->throwNativeOOMError(env, 0, 0);
527
(*env)->ReleaseStringUTFChars(env, thisString, jniStringCharacters);
528
rc = 6;
529
goto fail;
530
}
531
532
strcpy((*formatStringsArray)[i], jniStringCharacters);
533
534
buildCallPattern((*formatStringsArray)[i], &((*callPatternsArray)[i]));
535
536
(*env)->ReleaseStringUTFChars(env, thisString, jniStringCharacters);
537
(*env)->DeleteLocalRef(env, thisString);
538
}
539
540
return 0;
541
542
fail:
543
544
if (NULL != *formatStringsArray) {
545
for (i = 0; i < *tracePointCount; i++) {
546
char *formatString = (*formatStringsArray)[i];
547
548
if (NULL != formatString) {
549
j9mem_free_memory(formatString);
550
}
551
}
552
553
j9mem_free_memory(*formatStringsArray);
554
}
555
556
if (NULL != *callPatternsArray) {
557
j9mem_free_memory(*callPatternsArray);
558
}
559
560
return rc;
561
}
562
563
/*
564
* Frees a modinfo structure.
565
*/
566
static void
567
freeModInfo(JNIEnv *const env, UtModuleInfo *toFree)
568
{
569
PORT_ACCESS_FROM_ENV(env);
570
571
if (NULL == toFree) {
572
return;
573
}
574
575
if (NULL != toFree->name) {
576
j9mem_free_memory(toFree->name);
577
}
578
579
if (NULL != toFree->active) {
580
j9mem_free_memory(toFree->active);
581
}
582
583
if (NULL != toFree->traceVersionInfo) {
584
j9mem_free_memory(toFree->traceVersionInfo);
585
}
586
587
if (NULL != toFree->levels) {
588
j9mem_free_memory(toFree->levels);
589
}
590
591
j9mem_free_memory(toFree);
592
}
593
594
/**
595
* Builds and populates the UtModuleInfo structure to register with the trace engine.
596
*
597
* @param env [in] JNI environment
598
* @param japplicationName [in] UTF version of application name, from GetStringUTFChars
599
* @param tracePointCount [in] Number of trace points
600
* @return Populated UTModuleInfo structure or NULL if there was a problem.
601
*/
602
static UtModuleInfo *
603
buildModInfo(JNIEnv *const env, const char *const applicationName, const UDATA tracePointCount)
604
{
605
UtModuleInfo *toReturn = NULL;
606
UDATA arraySize = sizeof(unsigned char) * tracePointCount;
607
J9InternalVMFunctions *vmFuncs = ((J9VMThread *)env)->javaVM->internalVMFunctions;
608
609
PORT_ACCESS_FROM_ENV(env);
610
611
toReturn = (UtModuleInfo*) j9mem_allocate_memory( sizeof(UtModuleInfo), J9MEM_CATEGORY_VM_JCL);
612
if (NULL == toReturn) {
613
goto error;
614
}
615
616
memset(toReturn, 0, sizeof(UtModuleInfo));
617
618
/*Duplicate the application name*/
619
toReturn->namelength = (I_32)strlen(applicationName);
620
toReturn->name = j9mem_allocate_memory( toReturn->namelength + 1, J9MEM_CATEGORY_VM_JCL);
621
if (NULL == toReturn->name) {
622
vmFuncs->throwNativeOOMError(env, 0, 0);
623
goto error;
624
}
625
strcpy(toReturn->name, applicationName);
626
627
toReturn->count = (I_32)tracePointCount;
628
629
toReturn->moduleId = UT_APPLICATION_TRACE_MODULE;
630
631
toReturn->active = (unsigned char *)j9mem_allocate_memory( arraySize, J9MEM_CATEGORY_VM_JCL);
632
if (NULL == toReturn->active) {
633
vmFuncs->throwNativeOOMError(env, 0, 0);
634
goto error;
635
}
636
637
memset(toReturn->active, 0, arraySize);
638
639
toReturn->traceVersionInfo = (UtTraceVersionInfo *)j9mem_allocate_memory( sizeof(UtTraceVersionInfo), J9MEM_CATEGORY_VM_JCL);
640
if (NULL == toReturn->traceVersionInfo) {
641
vmFuncs->throwNativeOOMError(env, 0, 0);
642
goto error;
643
}
644
645
toReturn->traceVersionInfo->traceVersion = UT_TRACE_VERSION;
646
647
toReturn->levels = (unsigned char *)j9mem_allocate_memory( arraySize, J9MEM_CATEGORY_VM_JCL);
648
if (NULL == toReturn->levels) {
649
vmFuncs->throwNativeOOMError(env, 0, 0);
650
goto error;
651
}
652
memset(toReturn->levels, 3, arraySize);
653
654
return toReturn;
655
656
error:
657
658
if (NULL != toReturn) {
659
freeModInfo(env, toReturn);
660
}
661
662
return NULL;
663
}
664
665
/**************************************************************************
666
* name - Java_com_ibm_jvm_Trace_registerApplication
667
* description - Set trace options
668
* parameters - JNIEnv, this, trace configuration command
669
* returns - return code
670
*************************************************************************/
671
int JNICALL
672
Java_com_ibm_jvm_Trace_registerApplicationImpl(JNIEnv *env, jobject this, jobject name, jarray templates)
673
{
674
const char *applicationName = NULL;
675
char **formatStringsArray = NULL;
676
UDATA *callPatternsArray = NULL;
677
UDATA tracePointCount = 0;
678
int toReturn = JNI_ERR;
679
int err = 0;
680
int index = 0;
681
int tempIndex = 0;
682
UtModuleInfo *modInfo = NULL;
683
684
PORT_ACCESS_FROM_ENV(env);
685
686
/* If we don't have the trace engine, we have to exit. Pass back a valid handle so
687
* application trace becomes a silent no-op.
688
*/
689
if (NULL == TRACEDOTCGLOBAL(utIntf)) {
690
toReturn = 0;
691
goto error;
692
}
693
694
err = (int)processAndCheckNameString(env, name, &applicationName);
695
696
if (0 != err) {
697
/*An exception will have been thrown - we just need to free resources and return*/
698
toReturn = JNI_ERR;
699
goto error;
700
}
701
702
err = (int)extractAndProcessFormatStrings(env, templates, &formatStringsArray, &callPatternsArray, &tracePointCount);
703
704
if (0 != err) {
705
/*Exception will have been thrown*/
706
toReturn = JNI_ERR;
707
goto error;
708
}
709
710
modInfo = buildModInfo(env, applicationName, tracePointCount);
711
712
if (NULL == modInfo) {
713
toReturn = JNI_ERR;
714
goto error;
715
}
716
717
/*Register the application with the trace engine*/
718
err = TRACEDOTCGLOBAL(utIntf)->server->AddComponent(modInfo, (const char **)formatStringsArray);
719
720
if (0 != err) {
721
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
722
723
memset(messageBuffer, 0, sizeof(messageBuffer));
724
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Failed to register application with trace engine: %d", err);
725
throwRuntimeException(env, messageBuffer);
726
toReturn = JNI_ERR;
727
goto error;
728
}
729
730
/*Get an index and store the modinfo and callPatternsArray to use later*/
731
do {
732
tempIndex = TRACEDOTCGLOBAL(numberOfAppTraceApplications);
733
index = tempIndex + 1;
734
} while (! CompareAndSwap32(&TRACEDOTCGLOBAL(numberOfAppTraceApplications), tempIndex, index));
735
736
toReturn = index;
737
738
err = (int)arrayListPut(env, TRACEDOTCGLOBAL(modInfoList), index, (void*)modInfo);
739
740
if (0 != err) {
741
/*Exception will have been thrown*/
742
toReturn = JNI_ERR;
743
goto error;
744
}
745
746
err = (int)arrayListPut(env, TRACEDOTCGLOBAL(argumentStructureList), index, (void*)callPatternsArray);
747
748
if (0 != err) {
749
/*Exception will have been thrown*/
750
toReturn = JNI_ERR;
751
goto error;
752
}
753
754
error:
755
756
if (0 != err) {
757
if (NULL != formatStringsArray) {
758
UDATA i = 0;
759
760
for (i = 0; i < tracePointCount; i++) {
761
if (NULL != formatStringsArray[i]) {
762
j9mem_free_memory(formatStringsArray[i]);
763
}
764
}
765
766
j9mem_free_memory(formatStringsArray);
767
}
768
769
if (NULL != callPatternsArray) {
770
j9mem_free_memory(callPatternsArray);
771
}
772
773
if (NULL != modInfo) {
774
freeModInfo(env, modInfo);
775
}
776
}
777
778
779
if (NULL != applicationName) {
780
(*env)->ReleaseStringUTFChars(env, name, applicationName);
781
}
782
783
return toReturn;
784
}
785
786
/**
787
* Counts the number of arguments in a callPattern
788
* @param pattern [in] Call pattern
789
* @return Number of arguments
790
*/
791
static UDATA
792
countArguments(const UDATA pattern)
793
{
794
return (((pattern >> (3 * 8)) & 0xFF) != 0) ? 4
795
: (((pattern >> (2 * 8)) & 0xFF) != 0) ? 3
796
: (((pattern >> (1 * 8)) & 0xFF) != 0) ? 2
797
: (((pattern >> (0 * 8)) & 0xFF) != 0) ? 1
798
: 0;
799
}
800
801
/**
802
* Trace method that all other com.ibm.jvm.Trace.trace() methods call through.
803
*
804
* @param env JNI environment
805
* @param handle Application trace handle (returned from registerApplication)
806
* @param traceId Id of trace point to trace
807
* @param methodSignature the signature of the method that supplied the arguments
808
*
809
* Trace arguments are passed by varargs
810
*/
811
static void
812
trace(JNIEnv *const env, const jint handle, const jint traceId, const UDATA methodSignature, ...)
813
{
814
UtModuleInfo *modInfo = NULL;
815
UDATA *callPatternsArray = NULL;
816
va_list args;
817
UDATA numberOfArgumentsExpected = 0;
818
UDATA numberOfArgumentsSupplied = 0;
819
820
/*If trace is disabled, bail out*/
821
if (NULL == TRACEDOTCGLOBAL(utIntf)) {
822
return;
823
}
824
825
/*Is the handle valid?*/
826
if (handle <= 0 || (U_32)handle > TRACEDOTCGLOBAL(numberOfAppTraceApplications)) {
827
throwIllegalArgumentException(env, "Invalid application trace handle. Check return code from registerApplication().");
828
return;
829
}
830
831
modInfo = (UtModuleInfo *) arrayListGet(env, TRACEDOTCGLOBAL(modInfoList), handle);
832
assert(NULL != modInfo);
833
834
callPatternsArray = (UDATA *) arrayListGet(env, TRACEDOTCGLOBAL(argumentStructureList), handle);
835
assert(NULL != callPatternsArray);
836
837
/*Is the trace id in the right range?*/
838
if (traceId < 0 || traceId >= modInfo->count) {
839
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
840
PORT_ACCESS_FROM_ENV(env);
841
842
memset(messageBuffer, 0, sizeof(messageBuffer));
843
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Specified tracepoint: %d outside of valid range 0<=x<%d\n", traceId, modInfo->count);
844
throwIllegalArgumentException(env, messageBuffer);
845
return;
846
}
847
848
/*Do we have the expected number of arguments?*/
849
numberOfArgumentsExpected = countArguments(callPatternsArray[traceId]);
850
numberOfArgumentsSupplied = countArguments(methodSignature);
851
852
if (numberOfArgumentsExpected != numberOfArgumentsSupplied) {
853
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
854
PORT_ACCESS_FROM_ENV(env);
855
856
memset(messageBuffer, 0, sizeof(messageBuffer));
857
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Wrong number of arguments passed to tracepoint %s.%d expected %d received %d.", modInfo->name, traceId, numberOfArgumentsExpected, numberOfArgumentsSupplied);
858
throwIllegalArgumentException(env, messageBuffer);
859
return;
860
}
861
862
/*Do the arguments match the trace point?*/
863
if ((methodSignature & callPatternsArray[traceId]) != methodSignature) {
864
char messageBuffer[ERROR_MESSAGE_BUFFER_LENGTH + 1];
865
char *p = NULL;
866
char *const end = messageBuffer + ERROR_MESSAGE_BUFFER_LENGTH;
867
PORT_ACCESS_FROM_ENV(env);
868
869
memset(messageBuffer, 0, sizeof(messageBuffer));
870
j9str_printf(PORTLIB, messageBuffer, ERROR_MESSAGE_BUFFER_LENGTH, "Invalid arguments passed to tracepoint %s.%d. Tracepoint expects: ", modInfo->name, traceId);
871
872
p = messageBuffer + strlen(messageBuffer);
873
formatCallPattern(p, end, callPatternsArray[traceId]);
874
875
strncat(messageBuffer, " received: ", ERROR_MESSAGE_BUFFER_LENGTH - strlen(messageBuffer));
876
877
p = messageBuffer + strlen(messageBuffer);
878
formatCallPattern(p, end, methodSignature);
879
880
strncat(messageBuffer, ".", ERROR_MESSAGE_BUFFER_LENGTH - strlen(messageBuffer));
881
882
throwIllegalArgumentException(env, messageBuffer);
883
return;
884
}
885
886
va_start(args, methodSignature);
887
888
TRACEDOTCGLOBAL(utIntf)->server->TraceVNoThread(modInfo, (traceId << 8) | modInfo->active[traceId], "", args);
889
890
va_end(args);
891
}
892
893
/**************************************************************************
894
* name - Java_com_ibm_jvm_Trace_traceImpl
895
* description - Make tracepoint
896
* parameters - JNIEnv, this, handle, tracepoint id, optional trace data
897
* returns - Nothing
898
*************************************************************************/
899
void JNICALL
900
Java_com_ibm_jvm_Trace_traceImpl__II(JNIEnv *env, jclass this, jint handle, jint traceId)
901
{
902
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR());
903
}
904
905
void JNICALL
906
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2(JNIEnv *env,
907
jclass this, jint handle, jint traceId, jstring s1)
908
{
909
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
910
911
if (NULL == utfS1) {
912
return;
913
}
914
915
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JSTRING), utfS1);
916
917
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
918
}
919
920
void JNICALL
921
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2Ljava_lang_String_2(JNIEnv *env,
922
jclass this, jint handle, jint traceId, jstring s1, jstring s2)
923
{
924
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
925
const char *utfS2 = NULL;
926
927
if (NULL == utfS1) {
928
goto end;
929
}
930
931
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
932
933
if (NULL == utfS2) {
934
goto end;
935
}
936
937
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JSTRING), utfS1, utfS2);
938
939
end:
940
if (NULL != utfS1) {
941
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
942
}
943
944
if (NULL != utfS2) {
945
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
946
}
947
}
948
949
void JNICALL
950
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv *env,
951
jclass this, jint handle, jint traceId, jstring s1, jstring s2, jstring s3)
952
{
953
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
954
const char *utfS2 = NULL;
955
const char *utfS3 = NULL;
956
957
if (NULL == utfS1) {
958
goto end;
959
}
960
961
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
962
963
if (NULL == utfS2) {
964
goto end;
965
}
966
967
utfS3 = (*env)->GetStringUTFChars(env, s3, NULL);
968
969
if (NULL == utfS3) {
970
goto end;
971
}
972
973
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JSTRING, JSTRING), utfS1, utfS2, utfS3);
974
975
end:
976
if (NULL != utfS1) {
977
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
978
}
979
980
if (NULL != utfS2) {
981
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
982
}
983
984
if (NULL != utfS3) {
985
(*env)->ReleaseStringUTFChars(env, s3, utfS3);
986
}
987
}
988
989
void JNICALL
990
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2Ljava_lang_Object_2(JNIEnv *env,
991
jclass this, jint handle, jint traceId, jstring s1, jobject o1)
992
{
993
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
994
995
if (NULL == utfS1) {
996
return;
997
}
998
999
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JOBJECT), utfS1, o1);
1000
1001
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1002
}
1003
1004
void JNICALL
1005
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_Object_2Ljava_lang_String_2(JNIEnv *env,
1006
jclass this, jint handle, jint traceId, jobject o1, jstring s1)
1007
{
1008
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1009
1010
if (NULL == utfS1) {
1011
return;
1012
}
1013
1014
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JOBJECT, JSTRING), o1, utfS1);
1015
1016
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1017
}
1018
1019
void JNICALL
1020
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2I(JNIEnv *env,
1021
jclass this, jint handle, jint traceId, jstring s1, jint i1)
1022
{
1023
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1024
1025
if (NULL == utfS1) {
1026
return;
1027
}
1028
1029
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JWORD), utfS1, i1);
1030
1031
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1032
}
1033
1034
void JNICALL
1035
Java_com_ibm_jvm_Trace_traceImpl__IIILjava_lang_String_2(JNIEnv *env,
1036
jclass this, jint handle, jint traceId, jint i1, jstring s1)
1037
{
1038
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1039
1040
if (NULL == utfS1) {
1041
return;
1042
}
1043
1044
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JWORD, JSTRING), i1, utfS1);
1045
1046
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1047
}
1048
1049
void JNICALL
1050
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2J(JNIEnv *env,
1051
jclass this, jint handle, jint traceId, jstring s1, jlong l1)
1052
{
1053
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1054
1055
if (NULL == utfS1) {
1056
return;
1057
}
1058
1059
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JDOUBLEWORD), utfS1, l1);
1060
1061
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1062
}
1063
void JNICALL
1064
Java_com_ibm_jvm_Trace_traceImpl__IIJLjava_lang_String_2(JNIEnv *env,
1065
jclass this, jint handle, jint traceId, jlong l1, jstring s1)
1066
{
1067
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1068
1069
if (NULL == utfS1) {
1070
return;
1071
}
1072
1073
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JDOUBLEWORD, JSTRING), l1, utfS1);
1074
1075
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1076
}
1077
void JNICALL
1078
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2B(JNIEnv *env,
1079
jclass this, jint handle, jint traceId, jstring s1, jbyte b1)
1080
{
1081
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1082
1083
if (NULL == utfS1) {
1084
return;
1085
}
1086
1087
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JWORD), utfS1, b1);
1088
1089
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1090
}
1091
1092
void JNICALL
1093
Java_com_ibm_jvm_Trace_traceImpl__IIBLjava_lang_String_2(JNIEnv *env,
1094
jclass this, jint handle, jint traceId, jbyte b1, jstring s1)
1095
{
1096
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1097
1098
if (NULL == utfS1) {
1099
return;
1100
}
1101
1102
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JWORD, JSTRING), b1, utfS1);
1103
1104
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1105
}
1106
1107
void JNICALL
1108
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2C(JNIEnv *env,
1109
jclass this, jint handle, jint traceId, jstring s1, jchar c1)
1110
{
1111
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1112
1113
if (NULL == utfS1) {
1114
return;
1115
}
1116
1117
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JCHAR), utfS1, c1);
1118
1119
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1120
}
1121
1122
void JNICALL
1123
Java_com_ibm_jvm_Trace_traceImpl__IICLjava_lang_String_2(JNIEnv *env,
1124
jclass this, jint handle, jint traceId, jchar c1, jstring s1)
1125
{
1126
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1127
1128
if (NULL == utfS1) {
1129
return;
1130
}
1131
1132
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JCHAR, JSTRING), c1, utfS1);
1133
1134
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1135
}
1136
1137
void JNICALL
1138
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2F(JNIEnv *env,
1139
jclass this, jint handle, jint traceId, jstring s1, jfloat f1)
1140
{
1141
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1142
1143
if (NULL == utfS1) {
1144
return;
1145
}
1146
1147
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JFLOATPOINT), utfS1, f1);
1148
1149
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1150
}
1151
1152
void JNICALL
1153
Java_com_ibm_jvm_Trace_traceImpl__IIFLjava_lang_String_2(JNIEnv *env,
1154
jclass this, jint handle, jint traceId, jfloat f1, jstring s1)
1155
{
1156
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1157
1158
if (NULL == utfS1) {
1159
return;
1160
}
1161
1162
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JFLOATPOINT, JSTRING), f1, utfS1);
1163
1164
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1165
}
1166
1167
void JNICALL
1168
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2D(JNIEnv *env,
1169
jclass this, jint handle, jint traceId, jstring s1, jdouble d1)
1170
{
1171
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1172
1173
if (NULL == utfS1) {
1174
return;
1175
}
1176
1177
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JSTRING, JFLOATPOINT), utfS1, d1);
1178
1179
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1180
}
1181
1182
void JNICALL
1183
Java_com_ibm_jvm_Trace_traceImpl__IIDLjava_lang_String_2(JNIEnv *env,
1184
jclass this, jint handle, jint traceId, jdouble d1, jstring s1)
1185
{
1186
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1187
1188
if (NULL == utfS1) {
1189
return;
1190
}
1191
1192
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JFLOATPOINT, JSTRING), d1, utfS1);
1193
1194
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1195
}
1196
1197
void JNICALL
1198
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_Object_2(JNIEnv *env,
1199
jclass this, jint handle, jint traceId, jobject o1)
1200
{
1201
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JOBJECT), o1);
1202
}
1203
1204
void JNICALL
1205
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_Object_2Ljava_lang_Object_2(JNIEnv *env,
1206
jclass this, jint handle, jint traceId, jobject o1, jobject o2)
1207
{
1208
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JOBJECT, JOBJECT), o1, o2);
1209
}
1210
1211
void JNICALL
1212
Java_com_ibm_jvm_Trace_traceImpl__III(JNIEnv *env,
1213
jclass this, jint handle, jint traceId, jint i1)
1214
{
1215
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JWORD), i1);
1216
}
1217
1218
void JNICALL
1219
Java_com_ibm_jvm_Trace_traceImpl__IIII(JNIEnv *env,
1220
jclass this, jint handle, jint traceId, jint i1 , jint i2)
1221
{
1222
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JWORD, JWORD), i1, i2);
1223
}
1224
1225
void JNICALL
1226
Java_com_ibm_jvm_Trace_traceImpl__IIIII(JNIEnv *env,
1227
jclass this, jint handle, jint traceId, jint i1, jint i2, jint i3)
1228
{
1229
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JWORD, JWORD, JWORD), i1, i2, i3);
1230
}
1231
1232
void JNICALL
1233
Java_com_ibm_jvm_Trace_traceImpl__IIJ(JNIEnv *env,
1234
jclass this, jint handle, jint traceId, jlong l1)
1235
{
1236
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JDOUBLEWORD), l1);
1237
}
1238
1239
void JNICALL
1240
Java_com_ibm_jvm_Trace_traceImpl__IIJJ(JNIEnv *env,
1241
jclass this, jint handle, jint traceId, jlong l1, jlong l2)
1242
{
1243
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JDOUBLEWORD, JDOUBLEWORD), l1, l2);
1244
}
1245
1246
void JNICALL
1247
Java_com_ibm_jvm_Trace_traceImpl__IIJJJ(JNIEnv *env,
1248
jclass this, jint handle, jint traceId, jlong l1, jlong l2, jlong l3)
1249
{
1250
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JDOUBLEWORD, JDOUBLEWORD, JDOUBLEWORD), l1, l2, l3);
1251
}
1252
1253
void JNICALL
1254
Java_com_ibm_jvm_Trace_traceImpl__IIB(JNIEnv *env,
1255
jclass this, jint handle, jint traceId, jbyte b1)
1256
{
1257
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JWORD), b1);
1258
}
1259
1260
void JNICALL
1261
Java_com_ibm_jvm_Trace_traceImpl__IIBB(JNIEnv *env,
1262
jclass this, jint handle, jint traceId, jbyte b1, jbyte b2)
1263
{
1264
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JWORD, JWORD), b1, b2);
1265
}
1266
1267
void JNICALL
1268
Java_com_ibm_jvm_Trace_traceImpl__IIBBB(JNIEnv *env,
1269
jclass this, jint handle, jint traceId, jbyte b1, jbyte b2, jbyte b3)
1270
{
1271
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JWORD, JWORD, JWORD), b1, b2, b3);
1272
}
1273
1274
void JNICALL
1275
Java_com_ibm_jvm_Trace_traceImpl__IIC(JNIEnv *env,
1276
jclass this, jint handle, jint traceId, jchar c1)
1277
{
1278
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JCHAR), c1);
1279
}
1280
1281
void JNICALL
1282
Java_com_ibm_jvm_Trace_traceImpl__IICC(JNIEnv *env,
1283
jclass this, jint handle, jint traceId, jchar c1, jchar c2)
1284
{
1285
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JCHAR, JCHAR), c1, c2);
1286
}
1287
1288
void JNICALL
1289
Java_com_ibm_jvm_Trace_traceImpl__IICCC(JNIEnv *env,
1290
jclass this, jint handle, jint traceId, jchar c1, jchar c2, jchar c3)
1291
{
1292
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JCHAR, JCHAR, JCHAR), c1, c2, c3);
1293
}
1294
1295
void JNICALL
1296
Java_com_ibm_jvm_Trace_traceImpl__IIF(JNIEnv *env,
1297
jclass this, jint handle, jint traceId, jfloat f1)
1298
{
1299
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JFLOATPOINT), f1);
1300
}
1301
1302
void JNICALL
1303
Java_com_ibm_jvm_Trace_traceImpl__IIFF(JNIEnv *env,
1304
jclass this, jint handle, jint traceId, jfloat f1, jfloat f2)
1305
{
1306
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JFLOATPOINT, JFLOATPOINT), f1, f2);
1307
}
1308
1309
void JNICALL
1310
Java_com_ibm_jvm_Trace_traceImpl__IIFFF(JNIEnv *env,
1311
jclass this, jint handle, jint traceId, jfloat f1, jfloat f2, jfloat f3)
1312
{
1313
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JFLOATPOINT, JFLOATPOINT, JFLOATPOINT), f1, f2, f3);
1314
}
1315
1316
void JNICALL
1317
Java_com_ibm_jvm_Trace_traceImpl__IID(JNIEnv *env,
1318
jclass this, jint handle, jint traceId, jdouble d1)
1319
{
1320
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_1(JFLOATPOINT), d1);
1321
}
1322
1323
void JNICALL
1324
Java_com_ibm_jvm_Trace_traceImpl__IIDD(JNIEnv *env,
1325
jclass this, jint handle, jint traceId, jdouble d1, jdouble d2)
1326
{
1327
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_2(JFLOATPOINT, JFLOATPOINT), d1, d2);
1328
}
1329
1330
void JNICALL
1331
Java_com_ibm_jvm_Trace_traceImpl__IIDDD(JNIEnv *env,
1332
jclass this, jint handle, jint traceId, jdouble d1, jdouble d2, jdouble d3)
1333
{
1334
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JFLOATPOINT, JFLOATPOINT, JFLOATPOINT), d1, d2, d3);
1335
}
1336
1337
void JNICALL
1338
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2Ljava_lang_Object_2Ljava_lang_String_2(JNIEnv *env,
1339
jclass this, jint handle, jint traceId, jstring s1, jobject o1, jstring s2)
1340
{
1341
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1342
const char *utfS2 = NULL;
1343
1344
if (NULL == utfS1) {
1345
goto end;
1346
}
1347
1348
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1349
1350
if (NULL == utfS2) {
1351
goto end;
1352
}
1353
1354
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JOBJECT, JSTRING), utfS1, o1, utfS2);
1355
1356
end:
1357
if (NULL != utfS1) {
1358
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1359
}
1360
1361
if (NULL != utfS2) {
1362
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1363
}
1364
}
1365
1366
void JNICALL
1367
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_Object_2Ljava_lang_String_2Ljava_lang_Object_2(JNIEnv *env,
1368
jclass this, jint handle, jint traceId, jobject o1, jstring s1, jobject o2)
1369
{
1370
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1371
1372
if (NULL == utfS1) {
1373
return;
1374
}
1375
1376
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JOBJECT, JSTRING, JOBJECT), o1, utfS1, o2);
1377
1378
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1379
}
1380
1381
void JNICALL
1382
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2ILjava_lang_String_2(JNIEnv *env,
1383
jclass this, jint handle, jint traceId, jstring s1, jint i1, jstring s2)
1384
{
1385
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1386
const char *utfS2 = NULL;
1387
1388
if (NULL == utfS1) {
1389
goto end;
1390
}
1391
1392
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1393
1394
if (NULL == utfS2) {
1395
goto end;
1396
}
1397
1398
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JWORD, JSTRING), utfS1, i1, utfS2);
1399
1400
end:
1401
if (NULL != utfS1) {
1402
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1403
}
1404
1405
if (NULL != utfS2) {
1406
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1407
}
1408
}
1409
1410
void JNICALL
1411
Java_com_ibm_jvm_Trace_traceImpl__IIILjava_lang_String_2I(JNIEnv *env,
1412
jclass this, jint handle, jint traceId, jint i1, jstring s1, jint i2)
1413
{
1414
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1415
1416
if (NULL == utfS1) {
1417
return;
1418
}
1419
1420
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JWORD, JSTRING, JWORD), i1, utfS1, i2);
1421
1422
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1423
}
1424
1425
void JNICALL
1426
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2JLjava_lang_String_2(JNIEnv *env,
1427
jclass this, jint handle, jint traceId, jstring s1, jlong l1, jstring s2)
1428
{
1429
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1430
const char *utfS2 = NULL;
1431
1432
if (NULL == utfS1) {
1433
goto end;
1434
}
1435
1436
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1437
1438
if (NULL == utfS2) {
1439
goto end;
1440
}
1441
1442
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JDOUBLEWORD, JSTRING), utfS1, l1, utfS2);
1443
1444
end:
1445
if (NULL != utfS1) {
1446
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1447
}
1448
1449
if (NULL != utfS2) {
1450
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1451
}
1452
}
1453
1454
void JNICALL
1455
Java_com_ibm_jvm_Trace_traceImpl__IIJLjava_lang_String_2J(JNIEnv *env,
1456
jclass this, jint handle, jint traceId, jlong l1, jstring s1, jlong l2)
1457
{
1458
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1459
1460
if (NULL == utfS1) {
1461
return;
1462
}
1463
1464
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JDOUBLEWORD, JSTRING, JDOUBLEWORD), l1, utfS1, l2);
1465
1466
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1467
}
1468
1469
void JNICALL
1470
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2BLjava_lang_String_2(JNIEnv *env,
1471
jclass this, jint handle, jint traceId, jstring s1, jbyte b1, jstring s2)
1472
{
1473
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1474
const char *utfS2 = NULL;
1475
1476
if (NULL == utfS1) {
1477
goto end;
1478
}
1479
1480
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1481
1482
if (NULL == utfS2) {
1483
goto end;
1484
}
1485
1486
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JWORD, JSTRING), utfS1, b1, utfS2);
1487
1488
end:
1489
if (NULL != utfS1) {
1490
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1491
}
1492
1493
if (NULL != utfS2) {
1494
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1495
}
1496
}
1497
1498
void JNICALL
1499
Java_com_ibm_jvm_Trace_traceImpl__IIBLjava_lang_String_2B(JNIEnv *env,
1500
jclass this, jint handle, jint traceId, jbyte b1, jstring s1, jbyte b2)
1501
{
1502
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1503
1504
if (NULL == utfS1) {
1505
return;
1506
}
1507
1508
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JWORD, JSTRING, JWORD), b1, utfS1, b2);
1509
1510
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1511
}
1512
1513
void JNICALL
1514
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2CLjava_lang_String_2(JNIEnv *env,
1515
jclass this, jint handle, jint traceId, jstring s1, jchar c1, jstring s2)
1516
{
1517
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1518
const char *utfS2 = NULL;
1519
1520
if (NULL == utfS1) {
1521
goto end;
1522
}
1523
1524
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1525
1526
if (NULL == utfS2) {
1527
goto end;
1528
}
1529
1530
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JCHAR, JSTRING), utfS1, c1, utfS2);
1531
1532
end:
1533
if (NULL != utfS1) {
1534
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1535
}
1536
1537
if (NULL != utfS2) {
1538
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1539
}
1540
}
1541
1542
void JNICALL
1543
Java_com_ibm_jvm_Trace_traceImpl__IICLjava_lang_String_2C(JNIEnv *env,
1544
jclass this, jint handle, jint traceId, jchar c1, jstring s1, jchar c2)
1545
{
1546
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1547
1548
if (NULL == utfS1) {
1549
return;
1550
}
1551
1552
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JCHAR, JSTRING, JCHAR), c1, utfS1, c2);
1553
1554
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1555
}
1556
1557
void JNICALL
1558
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2FLjava_lang_String_2(JNIEnv *env,
1559
jclass this, jint handle, jint traceId, jstring s1, jfloat f1, jstring s2)
1560
{
1561
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1562
const char *utfS2 = NULL;
1563
1564
if (NULL == utfS1) {
1565
goto end;
1566
}
1567
1568
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1569
1570
if (NULL == utfS2) {
1571
goto end;
1572
}
1573
1574
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JFLOATPOINT, JSTRING), utfS1, f1, utfS2);
1575
1576
end:
1577
if (NULL != utfS1) {
1578
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1579
}
1580
1581
if (NULL != utfS2) {
1582
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1583
}
1584
}
1585
1586
void JNICALL
1587
Java_com_ibm_jvm_Trace_traceImpl__IIFLjava_lang_String_2F(JNIEnv *env,
1588
jclass this, jint handle, jint traceId, jfloat f1, jstring s1, jfloat f2)
1589
{
1590
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1591
1592
if (NULL == utfS1) {
1593
return;
1594
}
1595
1596
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JFLOATPOINT, JSTRING, JFLOATPOINT), f1, utfS1, f2);
1597
1598
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1599
}
1600
1601
void JNICALL
1602
Java_com_ibm_jvm_Trace_traceImpl__IILjava_lang_String_2DLjava_lang_String_2(JNIEnv *env,
1603
jclass this, jint handle, jint traceId, jstring s1, jdouble d1, jstring s2)
1604
{
1605
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1606
const char *utfS2 = NULL;
1607
1608
if (NULL == utfS1) {
1609
goto end;
1610
}
1611
1612
utfS2 = (*env)->GetStringUTFChars(env, s2, NULL);
1613
1614
if (NULL == utfS2) {
1615
goto end;
1616
}
1617
1618
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JSTRING, JFLOATPOINT, JSTRING), utfS1, d1, utfS2);
1619
1620
end:
1621
if (NULL != utfS1) {
1622
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1623
}
1624
1625
if (NULL != utfS2) {
1626
(*env)->ReleaseStringUTFChars(env, s2, utfS2);
1627
}
1628
}
1629
1630
void JNICALL
1631
Java_com_ibm_jvm_Trace_traceImpl__IIDLjava_lang_String_2D(JNIEnv *env,
1632
jclass this, jint handle, jint traceId, jdouble d1, jstring s1, jdouble d2)
1633
{
1634
const char *utfS1 = (*env)->GetStringUTFChars(env, s1, NULL);
1635
1636
if (NULL == utfS1) {
1637
return;
1638
}
1639
1640
trace(env, handle, traceId, ARGUMENT_DESCRIPTOR_3(JFLOATPOINT, JSTRING, JFLOATPOINT), d1, utfS1, d2);
1641
1642
(*env)->ReleaseStringUTFChars(env, s1, utfS1);
1643
}
1644
1645
/**************************************************************************
1646
* name - Java_com_ibm_jvm_Trace_set
1647
* description - Set trace options
1648
* parameters - JNIEnv, this, trace configuration command
1649
* returns - return code
1650
*************************************************************************/
1651
int JNICALL
1652
Java_com_ibm_jvm_Trace_setImpl(JNIEnv *env, jobject this, jstring jcmd)
1653
{
1654
const char *cmd = NULL;
1655
int ret = JNI_ERR;
1656
1657
/*
1658
* Check that interface is available
1659
*/
1660
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1661
return ret;
1662
}
1663
1664
if (NULL == jcmd) {
1665
return JNI_EINVAL;
1666
}
1667
1668
cmd = (*env)->GetStringUTFChars(env, jcmd, JNI_FALSE);
1669
1670
if (NULL != cmd) {
1671
ret = TRACEDOTCGLOBAL(rasIntf)->TraceSet(env, cmd);
1672
1673
(*env)->ReleaseStringUTFChars(env, jcmd, cmd);
1674
}
1675
1676
return ret;
1677
}
1678
1679
/**************************************************************************
1680
* name - Java_com_ibm_jvm_Trace_snap
1681
* description - Snap internal trace buffers
1682
* parameters - JNIEnv, this.
1683
* returns - none
1684
*************************************************************************/
1685
void JNICALL
1686
Java_com_ibm_jvm_Trace_snapImpl(JNIEnv *env, jobject this)
1687
{
1688
/*
1689
* Check that interface is available
1690
*/
1691
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1692
return;
1693
}
1694
1695
TRACEDOTCGLOBAL(rasIntf)->TraceSnap(env, NULL);
1696
}
1697
1698
/**************************************************************************
1699
* name - Java_com_ibm_jvm_Trace_suspend
1700
* description - Suspend tracing activity
1701
* parameters - JNIEnv, this.
1702
* returns - none
1703
*************************************************************************/
1704
void JNICALL
1705
Java_com_ibm_jvm_Trace_suspendImpl(JNIEnv *env, jobject this)
1706
{
1707
/*
1708
* Check that interface is available
1709
*/
1710
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1711
return;
1712
}
1713
1714
TRACEDOTCGLOBAL(rasIntf)->TraceSuspend(env);
1715
}
1716
1717
/**************************************************************************
1718
* name - Java_com_ibm_jvm_Trace_resume
1719
* description - Resume tracing activity
1720
* parameters - JNIEnv, this.
1721
* returns - none
1722
*************************************************************************/
1723
void JNICALL
1724
Java_com_ibm_jvm_Trace_resumeImpl(JNIEnv *env, jobject this)
1725
{
1726
/*
1727
* Check that interface is available
1728
*/
1729
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1730
return;
1731
}
1732
1733
TRACEDOTCGLOBAL(rasIntf)->TraceResume(env);
1734
}
1735
1736
/**************************************************************************
1737
* name - Java_com_ibm_jvm_Trace_suspendThis
1738
* description - Suspend tracing activity for this thread
1739
* parameters - JNIEnv, this.
1740
* returns - none
1741
*
1742
*************************************************************************/
1743
void JNICALL
1744
Java_com_ibm_jvm_Trace_suspendThisImpl(JNIEnv *env, jobject this)
1745
{
1746
/*
1747
* Check that interface is available
1748
*/
1749
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1750
return;
1751
}
1752
1753
TRACEDOTCGLOBAL(rasIntf)->TraceSuspendThis(env);
1754
}
1755
1756
/**************************************************************************
1757
* name - Java_com_ibm_jvm_Trace_resumeThis
1758
* description - resume tracing activity for this thread
1759
* parameters - JNIEnv, this.
1760
* returns - none
1761
*
1762
*************************************************************************/
1763
void JNICALL
1764
Java_com_ibm_jvm_Trace_resumeThisImpl(JNIEnv *env, jobject this)
1765
{
1766
/*
1767
* Check that interface is available
1768
*/
1769
if (NULL == TRACEDOTCGLOBAL(rasIntf)) {
1770
return;
1771
}
1772
1773
TRACEDOTCGLOBAL(rasIntf)->TraceResumeThis(env);
1774
}
1775
1776
/**************************************************************************
1777
* name - Java_com_ibm_jvm_Trace_getMicros
1778
* description - Return the microsecond clock time
1779
* parameters - JNIEnv, this.
1780
* returns - A long containing the microsecond time
1781
* initial version for 6.0 - a better version might return the actual time
1782
* in microseconds.
1783
*************************************************************************/
1784
jlong JNICALL
1785
Java_com_ibm_jvm_Trace_getMicros(JNIEnv *env, jobject this)
1786
{
1787
PORT_ACCESS_FROM_ENV(env);
1788
/* Use j9time_hires_delta instead of deprecated j9time_usec_clock */
1789
return (jlong)j9time_hires_delta(0, j9time_hires_clock(), J9PORT_TIME_DELTA_IN_MICROSECONDS);
1790
}
1791
1792
/*Array list code*/
1793
1794
static struct ArrayList *
1795
allocArrayList(JNIEnv *const env, const UDATA slabSize)
1796
{
1797
PORT_ACCESS_FROM_ENV(env);
1798
1799
struct ArrayList *toReturn = j9mem_allocate_memory(sizeof(struct ArrayList), J9MEM_CATEGORY_VM_JCL);
1800
1801
if (NULL == toReturn) {
1802
/*Malloc failure*/
1803
((J9VMThread *)env)->javaVM->internalVMFunctions->throwNativeOOMError(env, 0, 0);
1804
return NULL;
1805
}
1806
1807
toReturn->slabSize = slabSize;
1808
toReturn->header = NULL;
1809
1810
return toReturn;
1811
}
1812
1813
static void **
1814
arrayListAllocateSlab(JNIEnv *const env, const struct ArrayList *const list)
1815
{
1816
PORT_ACCESS_FROM_ENV(env);
1817
1818
/*We allocate an extra slot in the slab for the pointer to the next slab*/
1819
UDATA allocSize = sizeof(void *) * (list->slabSize + 1);
1820
void **toReturn = j9mem_allocate_memory(allocSize, J9MEM_CATEGORY_VM_JCL);
1821
1822
if (NULL == toReturn) {
1823
((J9VMThread *)env)->javaVM->internalVMFunctions->throwNativeOOMError(env, 0, 0);
1824
return NULL;
1825
}
1826
1827
memset(toReturn, 0, allocSize);
1828
1829
return toReturn;
1830
}
1831
1832
static void **
1833
arrayListGetSlab(JNIEnv *const env, const struct ArrayList *const list, const UDATA index, const BOOLEAN allocate)
1834
{
1835
const int targetSlabNumber = (const int)(index / list->slabSize);
1836
int currentSlabNumber = 0;
1837
void **currentSlab;
1838
PORT_ACCESS_FROM_ENV(env);
1839
1840
/*The first time this is called the list header slab won't have been created.*/
1841
if (NULL == list->header) {
1842
void **newSlab = arrayListAllocateSlab(env, list);
1843
1844
if (NULL == newSlab) {
1845
/*Malloc failed*/
1846
return NULL;
1847
}
1848
1849
if (! CompareAndSwapPtr((UDATA*)&(list->header), (UDATA)NULL, (UDATA)newSlab)) {
1850
/*Header is no longer NULL - someone else did the allocation. Free our newSlab and keep going*/
1851
j9mem_free_memory(newSlab);
1852
}
1853
}
1854
1855
currentSlab = list->header;
1856
1857
while (currentSlabNumber < targetSlabNumber) {
1858
/*The last element in the array is the pointer to the next slab*/
1859
if (currentSlab[list->slabSize]) {
1860
currentSlab = (void**)currentSlab[list->slabSize];
1861
currentSlabNumber++;
1862
} else {
1863
/*We've hit the end of the chain. At this point we can either allocate the space we need or give up*/
1864
if (allocate) {
1865
void **newSlab = arrayListAllocateSlab(env, list);
1866
1867
if (NULL == newSlab) {
1868
/*Malloc failed*/
1869
return NULL;
1870
}
1871
1872
/*Atomically swap in the new slab*/
1873
if (CompareAndSwapPtr((UDATA*)&(currentSlab[list->slabSize]), (UDATA)NULL, (UDATA)newSlab)) {
1874
currentSlab = newSlab;
1875
currentSlabNumber++;
1876
} else {
1877
/* The compare and swap didn't work - which means another thread must have already allocated and assigned
1878
* the slab. Free the memory this thread allocated and go round the loop again to re-evaluate the current slab.
1879
*/
1880
j9mem_free_memory(newSlab);
1881
continue;
1882
}
1883
} else {
1884
/*We don't want to allocate the space for the slot, so we just return*/
1885
return NULL;
1886
}
1887
}
1888
}
1889
1890
return currentSlab;
1891
}
1892
1893
static IDATA
1894
arrayListPut(JNIEnv *const env, const struct ArrayList *const list, const UDATA index, void *const value)
1895
{
1896
void **const slab = arrayListGetSlab(env, list, index, TRUE);
1897
void *oldValue;
1898
const UDATA slabIndex = index % list->slabSize;
1899
1900
if (NULL == slab) {
1901
return 1;
1902
}
1903
1904
do {
1905
oldValue = slab[slabIndex];
1906
} while (!CompareAndSwapPtr((UDATA*)&(slab[slabIndex]), (UDATA)oldValue, (UDATA)value));
1907
1908
return 0;
1909
}
1910
1911
static void *
1912
arrayListGet(JNIEnv *const env, const struct ArrayList *const list, const UDATA index)
1913
{
1914
void **const slab = arrayListGetSlab(env, list, index, FALSE);
1915
UDATA slabIndex = index % list->slabSize;
1916
1917
if (NULL == slab) {
1918
return NULL;
1919
}
1920
1921
return slab[slabIndex];
1922
}
1923
1924
static I_32
1925
CompareAndSwap32(volatile U_32 *target, U_32 old, U_32 new32)
1926
{
1927
return ( compareAndSwapU32((U_32*)target, old, new32) == old ) ? TRUE : FALSE;
1928
}
1929
1930
static I_32
1931
CompareAndSwapPtr(volatile UDATA *target, UDATA old, UDATA newptr)
1932
{
1933
return ( compareAndSwapUDATA((UDATA*)target, old, newptr) == old ) ? TRUE : FALSE;
1934
}
1935
1936
/*END OF FILE*/
1937
1938