Skip to content

Commit a9f63c3

Browse files
committed
Strict static field support fixes
- support fields set through the ConstantValue attribute - exclude 8th bit representing null restricted static field from type calculations - verbose messages for IllegalStateException - save unset strict field flags for final fields Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
1 parent 626eb53 commit a9f63c3

File tree

16 files changed

+163
-40
lines changed

16 files changed

+163
-40
lines changed

debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/tools/ddrinteractive/LinearDumper.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -599,19 +599,23 @@ private static Object getRegionDetailString(J9ClassRegion region)
599599
flags += "J9StaticFieldRefDouble, ";
600600
}
601601
} else {
602-
if (J9JavaAccessFlags.J9StaticFieldRefTypeObject == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
602+
long refType = (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal);
603+
if (refType == J9JavaAccessFlags.J9StaticFieldIsNullRestricted) {
604+
refType = J9JavaAccessFlags.J9StaticFieldRefTypeObject;
605+
}
606+
if (J9JavaAccessFlags.J9StaticFieldRefTypeObject == refType) {
603607
flags += "J9StaticFieldRefTypeObject, ";
604-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeBoolean == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
608+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeBoolean == refType) {
605609
flags += "J9StaticFieldRefTypeBoolean, ";
606-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeByte == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
610+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeByte == refType) {
607611
flags += "J9StaticFieldRefTypeByte, ";
608-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeChar == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
612+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeChar == refType) {
609613
flags += "J9StaticFieldRefTypeChar, ";
610-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeShort == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
614+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeShort == refType) {
611615
flags += "J9StaticFieldRefTypeShort, ";
612-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeIntFloat == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
616+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeIntFloat == refType) {
613617
flags += "J9StaticFieldRefTypeIntFloat, ";
614-
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeLongDouble == (J9JavaAccessFlags.J9StaticFieldRefTypeMask & slotAddressOriginal)) {
618+
} else if (J9JavaAccessFlags.J9StaticFieldRefTypeLongDouble == refType) {
615619
flags += "J9StaticFieldRefTypeLongDouble, ";
616620
}
617621
}

runtime/codert_vm/cnathelp.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,11 @@ old_slow_jitResolveStaticFieldImpl(J9VMThread *currentThread, UDATA parmCount, J
21582158
method = walkState->method;
21592159
resolveFlags |= J9_RESOLVE_FLAG_FIELD_SETTER;
21602160
}
2161-
UDATA field = (UDATA)vm->internalVMFunctions->resolveStaticFieldRef(currentThread, method, ramConstantPool, cpIndex, resolveFlags, NULL);
2161+
UDATA field = (UDATA)vm->internalVMFunctions->resolveStaticFieldRef(currentThread, method, ramConstantPool, cpIndex, resolveFlags, NULL
2162+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
2163+
, 0
2164+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
2165+
);
21622166
if ((UDATA)-1 == field) {
21632167
/* fetch result from floatTemp - stashed there in clinit case */
21642168
J9RAMStaticFieldRef *fakeRef = (J9RAMStaticFieldRef*)&currentThread->floatTemp1;

runtime/compiler/runtime/SymbolValidationManager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,11 @@ TR::SymbolValidationManager::validateStaticClassFromCPRecord(uint16_t classID, u
13161316
// This relocation may be early enough that the referenced class is
13171317
// loaded but not yet resolved at this index. Try to resolve the field
13181318
// and get the class again.
1319-
_vmThread->javaVM->internalVMFunctions->resolveStaticFieldRef(_fej9->vmThread(), NULL, beholderCP, cpIndex, J9_RESOLVE_FLAG_JIT_COMPILE_TIME, NULL);
1319+
_vmThread->javaVM->internalVMFunctions->resolveStaticFieldRef(_fej9->vmThread(), NULL, beholderCP, cpIndex, J9_RESOLVE_FLAG_JIT_COMPILE_TIME, NULL
1320+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
1321+
, 0
1322+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
1323+
);
13201324
clazz = TR_ResolvedJ9Method::getClassOfStaticFromCP(_fej9, beholderCP, cpIndex);
13211325
}
13221326
}

runtime/jcl/common/jclcinit.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,11 @@ initializeStaticField(J9JavaVM* vm, UDATA offset, UDATA resolveFlags)
213213
U_32 * cpShapeDescription = J9ROMCLASS_CPSHAPEDESCRIPTION(jclROMClass);
214214

215215
if (J9CPTYPE_FIELD == J9_CP_TYPE(cpShapeDescription, offset)) {
216-
if (NULL == vm->internalVMFunctions->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, offset, resolveFlags, NULL)) {
216+
if (NULL == vm->internalVMFunctions->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, offset, resolveFlags, NULL
217+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
218+
, 0
219+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
220+
)) {
217221
if (NULL == J9VMCONSTANTPOOL_CLASSREF_AT(vm, romFieldConstantPool[offset].classRefCPIndex)->value) {
218222
Trc_JCL_initializeKnownClasses_ClassRefNotResolvedForStaticFieldRef(vm->mainThread, romFieldConstantPool[offset].classRefCPIndex, offset);
219223
} else {
@@ -256,7 +260,11 @@ jint initializeKnownClasses(J9JavaVM* vm, U_32 runtimeFlags)
256260
Trc_JCL_initializeKnownClasses_SkippingResolve(vm->mainThread, i, romClassRef, romClassRef->runtimeFlags, runtimeFlags);
257261
} else {
258262
/* Try resolving as a static fieldref, then as an instance fieldref. */
259-
if (NULL != vmFuncs->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL)) {
263+
if (NULL != vmFuncs->resolveStaticFieldRef(vm->mainThread, NULL, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL
264+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
265+
, 0
266+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
267+
)) {
260268
Trc_JCL_initializeKnownClasses_ResolvedStaticFieldRef(vm->mainThread, i, J9RAMSTATICFIELDREF_VALUEADDRESS(staticFieldConstantPool + i));
261269
} else if (-1 != vmFuncs->resolveInstanceFieldRef(vm->mainThread, NULL, jclConstantPool, i, J9_RESOLVE_FLAG_NO_THROW_ON_FAIL, NULL)) {
262270
Trc_JCL_initializeKnownClasses_ResolvedInstanceFieldRef(vm->mainThread, i, instanceFieldConstantPool[i].valueOffset);

runtime/nls/j9vm/j9vm.nls

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,3 +2514,17 @@ J9NLS_VM_UNSUPPORTED_OPTION.explanation=Option provided is not supported.
25142514
J9NLS_VM_UNSUPPORTED_OPTION.system_action=The JVM will not start.
25152515
J9NLS_VM_UNSUPPORTED_OPTION.user_response=Remove the unsupported option.
25162516
# END NON-TRANSLATABLE
2517+
2518+
J9NLS_VM_GET_STRICT_STATIC_NOT_SET=Strict static field is unset before first read.
2519+
# START NON-TRANSLATABLE
2520+
J9NLS_VM_GET_STRICT_STATIC_NOT_SET.explanation=Strict static fields must be set to an initial value before being read.
2521+
J9NLS_VM_GET_STRICT_STATIC_NOT_SET.system_action=The JVM will throw an IllegalStateException.
2522+
J9NLS_VM_GET_STRICT_STATIC_NOT_SET.user_response=Contact the provider of the classfile for a corrected version.
2523+
# END NON-TRANSLATABLE
2524+
2525+
J9NLS_VM_PUT_FINAL_STRICT_STATIC_AFTER_READ=Final strict static field is set after read.
2526+
# START NON-TRANSLATABLE
2527+
J9NLS_VM_PUT_FINAL_STRICT_STATIC_AFTER_READ.explanation=The value of a final strict static field cannot change once it has been read.
2528+
J9NLS_VM_PUT_FINAL_STRICT_STATIC_AFTER_READ.system_action=The JVM will throw an IllegalStateException.
2529+
J9NLS_VM_PUT_FINAL_STRICT_STATIC_AFTER_READ.user_response=Contact the provider of the classfile for a corrected version.
2530+
# END NON-TRANSLATABLE

runtime/oti/VMHelpers.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,12 @@ class VM_VMHelpers
12781278
* that we do not use a stale flagsAndClass with non-zero value, as doing so may cause the
12791279
* the StaticFieldRefDouble bit check to succeed when it shouldn't.
12801280
*/
1281-
return ((UDATA)-1 != valueOffset) && (flagsAndClass > 0);
1281+
return ((UDATA)-1 != valueOffset) &&
1282+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
1283+
((flagsAndClass & ~J9StaticFieldRefStrictInitFlagsAndClassMask) > 0);
1284+
#else /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
1285+
(flagsAndClass > 0);
1286+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
12821287
}
12831288

12841289
/**

runtime/oti/j9.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ typedef struct J9ClassLoaderWalkState {
224224
#define J9_ARRAY_DIMENSION_LIMIT 255
225225

226226
#define J9FLAGSANDCLASS_FROM_CLASSANDFLAGS(classAndFlags) (((classAndFlags) >> J9_REQUIRED_CLASS_SHIFT) | ((classAndFlags) << (sizeof(UDATA) * 8 - J9_REQUIRED_CLASS_SHIFT)))
227-
#define J9CLASSANDFLAGS_FROM_FLAGSANDCLASS(flagsAndClass) (((flagsAndClass) >> (8 * sizeof(UDATA) - J9_REQUIRED_CLASS_SHIFT)) | ((flagsAndClass) << J9_REQUIRED_CLASS_SHIFT))
227+
#define J9CLASSANDFLAGS_FROM_FLAGSANDCLASS(flagsAndClass) ((J9StaticFieldRefFlagBits & ((flagsAndClass) >> (8 * sizeof(UDATA) - J9_REQUIRED_CLASS_SHIFT))) | ((flagsAndClass) << J9_REQUIRED_CLASS_SHIFT))
228228
#define J9RAMSTATICFIELDREF_CLASS(base) ((J9Class *) ((base)->flagsAndClass << J9_REQUIRED_CLASS_SHIFT))
229229
/* In a resolved J9RAMStaticFieldRef, the high bit of valueOffset is set, so it must be masked when adding valueOffset to the ramStatics address.
230230
* Note that ~IDATA_MIN has all but the high bit set. */

runtime/oti/j9javaaccessflags.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,13 @@
153153
/* Inform DDR that the static field ref constants support proper narrowing */
154154
#define J9PutfieldNarrowing 1
155155

156-
/* static field flags (low 8 bits of flagsAndClass) - low 3 bits are the field type for primitive types */
156+
/* static field flags (low 7 bits of flagsAndClass) - low 3 bits are the field type for primitive types */
157+
#if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES)
158+
#define J9_STATIC_FIELD_REF_TYPE(classAndFlags) \
159+
(J9StaticFieldIsNullRestricted == (classAndFlags & J9StaticFieldRefTypeMask)) ? 0x0 : (classAndFlags & J9StaticFieldRefTypeMask)
160+
#else /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */
161+
#define J9_STATIC_FIELD_REF_TYPE(classAndFlags) (classAndFlags & J9StaticFieldRefTypeMask)
162+
#endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */
157163
#define J9StaticFieldRefFlagBits 0xFF
158164
#define J9StaticFieldRefTypeMask 0x7
159165
#define J9StaticFieldRefTypeObject 0x0
@@ -185,6 +191,8 @@
185191
#define J9StaticFieldRefStrictInitWritten 0x80
186192
#define J9StaticFieldRefStrictInitUnset 0xC0
187193
#define J9StaticFieldRefStrictInitMask 0xC0
194+
#define J9StaticFieldRefStrictInitFlagsAndClassMask \
195+
((UDATA)J9StaticFieldRefStrictInitMask << (sizeof(UDATA) * 8 - J9_REQUIRED_CLASS_SHIFT))
188196
#define J9_STATIC_FIELD_STRICT_INIT_IS_UNSET(classAndFlags) \
189197
(J9StaticFieldRefStrictInitUnset == ((classAndFlags) & J9StaticFieldRefStrictInitMask))
190198
#define J9_STATIC_FIELD_STRICT_INIT_WAS_WRITTEN_AND_READ(classAndFlags) \

runtime/oti/j9nonbuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5117,7 +5117,11 @@ typedef struct J9InternalVMFunctions {
51175117
struct J9Method* ( *resolveStaticSplitMethodRef)(struct J9VMThread *vmStruct, J9ConstantPool *ramCP, UDATA splitTableIndex, UDATA resolveFlags) ;
51185118
struct J9Method* ( *resolveSpecialMethodRef)(struct J9VMThread *vmStruct, J9ConstantPool *constantPool, UDATA cpIndex, UDATA resolveFlags) ;
51195119
struct J9Method* ( *resolveSpecialSplitMethodRef)(struct J9VMThread *vmStruct, J9ConstantPool *constantPool, UDATA splitTableIndex, UDATA resolveFlags) ;
5120+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
5121+
void* ( *resolveStaticFieldRef)(struct J9VMThread *vmStruct, J9Method *method, J9ConstantPool *constantPool, UDATA fieldIndex, UDATA resolveFlags, struct J9ROMFieldShape **resolvedField, UDATA strictInitFlags) ;
5122+
#else /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
51205123
void* ( *resolveStaticFieldRef)(struct J9VMThread *vmStruct, J9Method *method, J9ConstantPool *constantPool, UDATA fieldIndex, UDATA resolveFlags, struct J9ROMFieldShape **resolvedField) ;
5124+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
51215125
IDATA ( *resolveInstanceFieldRef)(struct J9VMThread *vmStruct, J9Method *method, J9ConstantPool *constantPool, UDATA fieldIndex, UDATA resolveFlags, struct J9ROMFieldShape **resolvedField) ;
51225126
struct J9ClassLoader* ( *allocateClassLoader)(struct J9JavaVM* javaVM) ;
51235127
void (JNICALL *internalSendExceptionConstructor)(struct J9VMThread *vmContext, struct J9Class *exceptionClass, j9object_t exception, j9object_t detailMessage, UDATA constructorIndex) ;

runtime/oti/vm_api.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3187,11 +3187,15 @@ resolveStaticFieldRefInto(J9VMThread *vmStruct, J9Method *method, J9ConstantPool
31873187
* @param cpIndex
31883188
* @param resolveFlags
31893189
* @param **resolvedField
3190+
* @param strictInitFlags strict field initialization state
31903191
* @return void *
31913192
*/
31923193
void *
3193-
resolveStaticFieldRef(J9VMThread *vmStruct, J9Method *method, J9ConstantPool *ramCP, UDATA cpIndex, UDATA resolveFlags, J9ROMFieldShape **resolvedField);
3194-
3194+
resolveStaticFieldRef(J9VMThread *vmStruct, J9Method *method, J9ConstantPool *ramCP, UDATA cpIndex, UDATA resolveFlags, J9ROMFieldShape **resolvedField
3195+
#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS)
3196+
, UDATA strictInitFlags
3197+
#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */
3198+
);
31953199

31963200
/**
31973201
* @brief

0 commit comments

Comments
 (0)