Skip to content

Commit 4e8d679

Browse files
authored
Merge pull request #19773 from ThanHenderson/fix-init
Fix LocalJ9UTF8Buffer initialization
2 parents 92b291d + 3fceaf0 commit 4e8d679

File tree

1 file changed

+73
-58
lines changed

1 file changed

+73
-58
lines changed

runtime/jcl/common/java_lang_invoke_MethodHandleNatives.cpp

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,16 @@ initImpl(J9VMThread *currentThread, j9object_t membernameObject, j9object_t refO
291291
}
292292
}
293293

294-
typedef struct LocalJ9UTF8Buffer {
294+
struct LocalJ9UTF8Buffer {
295295
/**
296296
* Constructs an empty LocalJ9UTF8Buffer.
297297
*/
298-
LocalJ9UTF8Buffer() = default;
298+
LocalJ9UTF8Buffer()
299+
: utf8(nullptr)
300+
, capacity(0)
301+
, cursor(nullptr)
302+
{
303+
}
299304

300305
/**
301306
* Constructs a LocalJ9UTF8Buffer object from a J9UTF8 object pointer
@@ -304,22 +309,12 @@ typedef struct LocalJ9UTF8Buffer {
304309
* @param[in] length Length of the entire J9UTF8 buffer in bytes
305310
*/
306311
LocalJ9UTF8Buffer(J9UTF8 *buffer, size_t length)
312+
: utf8(buffer)
313+
, capacity(length - offsetof(J9UTF8, data))
314+
, cursor(J9UTF8_DATA(buffer))
307315
{
308-
utf8 = buffer;
309-
cursor = J9UTF8_DATA(buffer);
310-
capacity = length - sizeof(J9UTF8::length);
311316
}
312317

313-
/**
314-
* Delegating constructor to create a LocalJ9UTF8Buffer object
315-
* from a pointer to a character buffer and its length.
316-
* @param[in] buffer Pointer to the character buffer
317-
* @param[in] length Length of the character buffer in bytes
318-
*/
319-
LocalJ9UTF8Buffer(char *buffer, size_t length)
320-
: LocalJ9UTF8Buffer(reinterpret_cast<J9UTF8 *>(buffer), length)
321-
{}
322-
323318
/**
324319
* Calculate the remaining slots in the buffer.
325320
* @return number of remaining slots in the buffer
@@ -333,23 +328,23 @@ typedef struct LocalJ9UTF8Buffer {
333328
* Put a character into the buffer at the cursor, then advance the cursor.
334329
* @param[in] c The character to put into the buffer
335330
*/
336-
void putCharAtCursor(const char c)
331+
void putCharAtCursor(char c)
337332
{
338333
*cursor = c;
339334
cursor += 1;
340335
}
341336

342337
/**
343-
* Advance the cursor N slots.
344-
* @param[in] N The number of slots to advance the cursor by
338+
* Advance the cursor n slots.
339+
* @param[in] n The number of slots to advance the cursor by
345340
*/
346341
void advanceN(size_t n)
347342
{
348343
cursor += n;
349344
}
350345

351346
/**
352-
* Null-terminates the data, and sets the J9UTF8 length from a cursor-position calcuation.
347+
* Null-terminates the data, and sets the J9UTF8 length from a cursor-position calculation.
353348
*/
354349
void commitLength()
355350
{
@@ -360,7 +355,7 @@ typedef struct LocalJ9UTF8Buffer {
360355
J9UTF8 *utf8; /**< Pointer to the J9UTF8 struct */
361356
size_t capacity; /**< Capacity of the J9UTF8 data buffer */
362357
U_8 *cursor; /**< Pointer to current position in J9UTF8 data buffer */
363-
} LocalJ9UTF8Buffer;
358+
};
364359

365360
/**
366361
* Returns a character corresponding to a primitive-type class.
@@ -417,25 +412,32 @@ getClassSignatureLength(J9VMThread *currentThread, J9Class *clazz)
417412
/* +2 so that we can fit 'L' and ';' around the class name. */
418413
signatureLength = vm->internalVMFunctions->getStringUTF8Length(currentThread, sigString) + 2;
419414
} else {
420-
U_32 numDims = 0;
421-
422415
J9Class *myClass = clazz;
423-
while (J9ROMCLASS_IS_ARRAY(myClass->romClass)) {
424-
J9Class *componentClass = reinterpret_cast<J9Class *>(reinterpret_cast<J9ArrayClass *>(myClass)->componentType);
425-
if (J9ROMCLASS_IS_PRIMITIVE_TYPE(componentClass->romClass)) {
426-
break;
416+
UDATA numDims = 0;
417+
bool isPrimitive = false;
418+
if (J9CLASS_IS_ARRAY(myClass)) {
419+
J9ArrayClass *arrayClazz = reinterpret_cast<J9ArrayClass *>(myClass);
420+
numDims = arrayClazz->arity;
421+
422+
J9Class *leafComponentType = arrayClazz->leafComponentType;
423+
isPrimitive = J9ROMCLASS_IS_PRIMITIVE_TYPE(leafComponentType->romClass);
424+
if (isPrimitive) {
425+
/* -1 to account for the '[' already prepended to the primitive array class' name.
426+
* Result guaranteed to be >= 0 because the minimum arity for a J9ArrayClass is 1.
427+
*/
428+
numDims -= 1;
429+
myClass = leafComponentType->arrayClass;
430+
} else {
431+
myClass = leafComponentType;
427432
}
428-
numDims += 1;
429-
myClass = componentClass;
430433
}
431-
432-
J9UTF8 *romName = J9ROMCLASS_CLASSNAME(myClass->romClass);
433-
U_32 nameLength = J9UTF8_LENGTH(romName);
434-
const char *name = reinterpret_cast<const char *>(J9UTF8_DATA(romName));
435-
signatureLength = nameLength + numDims;
436-
if ('[' != name[0]) {
434+
if (!isPrimitive) {
435+
/* +2 so that we can fit 'L' and ';' around the class name. */
437436
signatureLength += 2;
438437
}
438+
J9UTF8 *romName = J9ROMCLASS_CLASSNAME(myClass->romClass);
439+
U_32 nameLength = J9UTF8_LENGTH(romName);
440+
signatureLength += nameLength + numDims;
439441
}
440442
}
441443

@@ -488,40 +490,50 @@ getClassSignatureInout(J9VMThread *currentThread, J9Class *clazz, LocalJ9UTF8Buf
488490
result = true;
489491
}
490492
} else {
491-
U_32 numDims = 0;
492-
493493
J9Class *myClass = clazz;
494-
while (J9ROMCLASS_IS_ARRAY(myClass->romClass)) {
495-
J9Class *componentClass = reinterpret_cast<J9Class *>(reinterpret_cast<J9ArrayClass *>(myClass)->componentType);
496-
if (J9ROMCLASS_IS_PRIMITIVE_TYPE(componentClass->romClass)) {
497-
break;
494+
UDATA numDims = 0;
495+
bool isPrimitive = false;
496+
if (J9CLASS_IS_ARRAY(myClass)) {
497+
J9ArrayClass *arrayClazz = reinterpret_cast<J9ArrayClass *>(myClass);
498+
numDims = arrayClazz->arity;
499+
500+
J9Class *leafComponentType = arrayClazz->leafComponentType;
501+
isPrimitive = J9ROMCLASS_IS_PRIMITIVE_TYPE(leafComponentType->romClass);
502+
if (isPrimitive) {
503+
/* -1 to account for the '[' already prepended to the primitive array class' name.
504+
* Result guaranteed to be >= 0 because the minimum arity for a J9ArrayClass is 1.
505+
*/
506+
numDims -= 1;
507+
myClass = leafComponentType->arrayClass;
508+
} else {
509+
myClass = leafComponentType;
498510
}
499-
numDims += 1;
500-
myClass = componentClass;
501511
}
502-
512+
/* +1 to ensure we can add a null-terminator. */
513+
U_32 sigLength = 1;
514+
if (!isPrimitive) {
515+
/* +2 so that we can fit 'L' and ';' around the class name. */
516+
sigLength += 2;
517+
}
503518
J9UTF8 *romName = J9ROMCLASS_CLASSNAME(myClass->romClass);
504519
U_32 nameLength = J9UTF8_LENGTH(romName);
505520
const char *name = reinterpret_cast<const char *>(J9UTF8_DATA(romName));
506-
U_32 sigLength = nameLength + numDims;
507-
if ('[' != name[0]) {
508-
sigLength += 2;
509-
}
521+
sigLength += nameLength + numDims;
510522

511523
if (sigLength <= stringBuffer->remaining()) {
512524
for (U_32 i = 0; i < numDims; i++) {
513525
stringBuffer->putCharAtCursor('[');
514526
}
515527

516-
if ('[' != name[0]) {
528+
if (!isPrimitive) {
517529
stringBuffer->putCharAtCursor('L');
518530
}
519531

520532
memcpy(stringBuffer->cursor, name, nameLength);
521533
/* Adjust cursor to account for the memcpy. */
522534
stringBuffer->advanceN(nameLength);
523535

524-
if ('[' != name[0]) {
536+
if (!isPrimitive) {
525537
stringBuffer->putCharAtCursor(';');
526538
}
527539
result = true;
@@ -544,7 +556,6 @@ getJ9UTF8SignatureFromMethodTypeWithMemAlloc(J9VMThread *currentThread, j9object
544556
J9JavaVM *vm = currentThread->javaVM;
545557
j9object_t ptypes = J9VMJAVALANGINVOKEMETHODTYPE_PTYPES(currentThread, typeObject);
546558
U_32 numArgs = J9INDEXABLEOBJECT_SIZE(currentThread, ptypes);
547-
J9UTF8 *result = NULL;
548559
UDATA signatureLength = 2; /* space for '(', ')' */
549560
PORT_ACCESS_FROM_JAVAVM(vm);
550561

@@ -559,9 +570,9 @@ getJ9UTF8SignatureFromMethodTypeWithMemAlloc(J9VMThread *currentThread, j9object
559570
signatureLength += getClassSignatureLength(currentThread, rclass);
560571

561572
UDATA signatureUtf8Size = signatureLength + sizeof(J9UTF8) + 1; /* +1 for a null-terminator */
562-
result = reinterpret_cast<J9UTF8 *>(j9mem_allocate_memory(signatureUtf8Size, OMRMEM_CATEGORY_VM));
573+
J9UTF8 *result = reinterpret_cast<J9UTF8 *>(j9mem_allocate_memory(signatureUtf8Size, OMRMEM_CATEGORY_VM));
563574
if (NULL != result) {
564-
LocalJ9UTF8Buffer stringBuffer = LocalJ9UTF8Buffer(result, signatureUtf8Size);
575+
LocalJ9UTF8Buffer stringBuffer(result, signatureUtf8Size);
565576

566577
stringBuffer.putCharAtCursor('(');
567578
for (U_32 i = 0; i < numArgs; i++) {
@@ -973,9 +984,11 @@ Java_java_lang_invoke_MethodHandleNatives_resolve(
973984
const J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
974985
jobject result = NULL;
975986
J9UTF8 *name = NULL;
976-
char nameBuffer[256] = {0};
987+
char nameBuffer[256];
988+
nameBuffer[0] = 0;
977989
J9UTF8 *signature = NULL;
978-
char signatureBuffer[256] = {0};
990+
char signatureBuffer[256];
991+
signatureBuffer[0] = 0;
979992
PORT_ACCESS_FROM_JAVAVM(vm);
980993
vmFuncs->internalEnterVMFromJNI(currentThread);
981994

@@ -1021,7 +1034,7 @@ Java_java_lang_invoke_MethodHandleNatives_resolve(
10211034
if (NULL != sigString) {
10221035
signature = vmFuncs->copyStringToJ9UTF8WithMemAlloc(currentThread, sigString, J9_STR_XLAT, "", 0, signatureBuffer, sizeof(signatureBuffer));
10231036
} else {
1024-
LocalJ9UTF8Buffer stringBuffer = LocalJ9UTF8Buffer(signatureBuffer, sizeof(signatureBuffer));
1037+
LocalJ9UTF8Buffer stringBuffer(reinterpret_cast<J9UTF8 *>(signatureBuffer), sizeof(signatureBuffer));
10251038
signature = getJ9UTF8SignatureFromMethodType(currentThread, typeObject, &stringBuffer);
10261039
}
10271040
} else if (J9VMJAVALANGSTRING_OR_NULL(vm) == typeClass) {
@@ -1031,7 +1044,7 @@ Java_java_lang_invoke_MethodHandleNatives_resolve(
10311044
UDATA signatureLength = getClassSignatureLength(currentThread, rclass) + sizeof(J9UTF8) + 1 /* null-terminator */;
10321045
LocalJ9UTF8Buffer stringBuffer;
10331046
if (signatureLength <= sizeof(signatureBuffer)) {
1034-
stringBuffer = LocalJ9UTF8Buffer(signatureBuffer, sizeof(signatureBuffer));
1047+
stringBuffer = LocalJ9UTF8Buffer(reinterpret_cast<J9UTF8 *>(signatureBuffer), sizeof(signatureBuffer));
10351048
} else {
10361049
signature = reinterpret_cast<J9UTF8 *>(j9mem_allocate_memory(signatureLength, OMRMEM_CATEGORY_VM));
10371050
if (NULL == signature) {
@@ -1403,9 +1416,11 @@ Java_java_lang_invoke_MethodHandleNatives_getMembers(
14031416
vmFuncs->internalEnterVMFromJNI(currentThread);
14041417
jint result = 0;
14051418
J9UTF8 *name = NULL;
1406-
char nameBuffer[256] = {0};
1419+
char nameBuffer[256];
1420+
nameBuffer[0] = 0;
14071421
J9UTF8 *signature = NULL;
1408-
char signatureBuffer[256] = {0};
1422+
char signatureBuffer[256];
1423+
signatureBuffer[0] = 0;
14091424
j9object_t callerObject = ((NULL == caller) ? NULL : J9_JNI_UNWRAP_REFERENCE(caller));
14101425

14111426
PORT_ACCESS_FROM_JAVAVM(vm);

0 commit comments

Comments
 (0)