Skip to content

Commit f36e298

Browse files
committed
Convert static initialization into a single loop
The code needs to loop over the static fields and initialize any of them that have a constant value (J9FieldFlagConstant). Original code use three loops - one to process objects, one to process single slot statics, one to process double slot statics - which meant iterating over the romClass fields 3 times. The new algorithm uses the counts in the J9ROMClass to figure out the starting area for each of the 3 kinds of static fields. This saves two iterations over the fields (an expensive operation!) while still maintaining the same layout of object/singles/doubles. A further optimization to only do this operation if a class has a static field tagged with J9FieldFlagConstant is possible. Signed-off-by: Dan Heidinga <daniel_heidinga@ca.ibm.com>
1 parent 8ecd118 commit f36e298

File tree

1 file changed

+39
-46
lines changed

1 file changed

+39
-46
lines changed

runtime/vm/ClassInitialization.cpp

+39-46
Original file line numberDiff line numberDiff line change
@@ -186,64 +186,57 @@ performVerification(J9VMThread *currentThread, J9Class *clazz)
186186
/* Prepare the class - the event is sent after the class init status has been updated */
187187
Trc_VM_performVerification_prepareClass(currentThread);
188188
romClass = clazz->romClass;
189-
UDATA *staticAddress = clazz->ramStatics;
189+
UDATA *objectStaticAddress = clazz->ramStatics;
190+
UDATA *singleStaticAddress = objectStaticAddress + romClass->objectStaticCount;
191+
U_64 *doubleStaticAddress = (U_64*)(singleStaticAddress + romClass->singleScalarStaticCount);
192+
193+
#if !defined(J9VM_ENV_DATA64)
194+
if (0 != ((UDATA)doubleStaticAddress & (sizeof(U_64) - 1))) {
195+
doubleStaticAddress += 1;
196+
}
197+
#endif
198+
190199
/* initialize object slots first */
191200
J9ROMFieldWalkState fieldWalkState;
192201
J9ROMFieldShape *field = romFieldsStartDo(romClass, &fieldWalkState);
193202
while (field != NULL) {
194203
U_32 modifiers = field->modifiers;
195-
if (J9_ARE_ALL_BITS_SET(modifiers, (J9AccStatic | J9FieldFlagObject))) {
196-
if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagConstant)) {
197-
U_32 index = *(U_32*)romFieldInitialValueAddress(field);
198-
J9ConstantPool *ramConstantPool = J9_CP_FROM_CLASS(clazz);
199-
J9RAMStringRef *ramCPEntry = ((J9RAMStringRef*)ramConstantPool) + index;
200-
j9object_t stringObject = ramCPEntry->stringObject;
201-
if (NULL == stringObject) {
202-
resolveStringRef(currentThread, ramConstantPool, index, J9_RESOLVE_FLAG_RUNTIME_RESOLVE);
203-
clazz = VM_VMHelpers::currentClass(clazz);
204-
if (VM_VMHelpers::exceptionPending(currentThread)) {
205-
goto done;
204+
if (J9_ARE_ALL_BITS_SET(modifiers, J9AccStatic)) {
205+
const bool hasConstantValue = J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagConstant);
206+
207+
if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagObject)) {
208+
if (hasConstantValue) {
209+
U_32 index = *(U_32*)romFieldInitialValueAddress(field);
210+
J9ConstantPool *ramConstantPool = J9_CP_FROM_CLASS(clazz);
211+
J9RAMStringRef *ramCPEntry = ((J9RAMStringRef*)ramConstantPool) + index;
212+
j9object_t stringObject = ramCPEntry->stringObject;
213+
if (NULL == stringObject) {
214+
resolveStringRef(currentThread, ramConstantPool, index, J9_RESOLVE_FLAG_RUNTIME_RESOLVE);
215+
clazz = VM_VMHelpers::currentClass(clazz);
216+
if (VM_VMHelpers::exceptionPending(currentThread)) {
217+
goto done;
218+
}
219+
stringObject = ramCPEntry->stringObject;
206220
}
207-
stringObject = ramCPEntry->stringObject;
221+
J9STATIC_OBJECT_STORE(currentThread, clazz, (j9object_t*)objectStaticAddress, stringObject);
222+
/* Overwriting NULL with a string that is in immortal, so no exception can occur */
208223
}
209-
J9STATIC_OBJECT_STORE(currentThread, clazz, (j9object_t*)staticAddress, stringObject);
210-
/* Overwriting NULL with a string that is in immortal, so no exception can occur */
211-
}
212-
staticAddress += 1;
213-
}
214-
field = romFieldsNextDo(&fieldWalkState);
215-
}
216-
/* initialize single scalar slots next */
217-
field = romFieldsStartDo(romClass, &fieldWalkState);
218-
while (field != NULL) {
219-
U_32 modifiers = field->modifiers;
220-
if (J9AccStatic == (modifiers & (J9AccStatic | J9FieldFlagObject | J9FieldSizeDouble))) {
221-
if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagConstant)) {
222-
*(U_32*)staticAddress = *(U_32*)romFieldInitialValueAddress(field);
223-
}
224-
staticAddress += 1;
225-
}
226-
field = romFieldsNextDo(&fieldWalkState);
227-
}
228-
/* initialize double scalar slots last - 8-align the storage before starting */
229-
#if !defined(J9VM_ENV_DATA64)
230-
if (0 != ((UDATA)staticAddress & (sizeof(U_64) - 1))) {
231-
staticAddress += 1;
232-
}
233-
#endif
234-
{
235-
U_64 *doubleStaticAddress = (U_64*)staticAddress;
236-
field = romFieldsStartDo(romClass, &fieldWalkState);
237-
while (field != NULL) {
238-
U_32 modifiers = field->modifiers;
239-
if (J9_ARE_ALL_BITS_SET(modifiers, (J9AccStatic | J9FieldSizeDouble))) {
240-
if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldFlagConstant)) {
224+
objectStaticAddress += 1;
225+
} else if (0 == (modifiers & (J9FieldFlagObject | J9FieldSizeDouble))) {
226+
if (hasConstantValue) {
227+
*(U_32*)singleStaticAddress = *(U_32*)romFieldInitialValueAddress(field);
228+
}
229+
singleStaticAddress += 1;
230+
} else if (J9_ARE_ALL_BITS_SET(modifiers, J9FieldSizeDouble)) {
231+
if (hasConstantValue) {
241232
*doubleStaticAddress = *(U_64*)romFieldInitialValueAddress(field);
242233
}
243234
doubleStaticAddress += 1;
235+
} else {
236+
// Can't happen now - maybe in the future with valuetypes?
244237
}
245-
field = romFieldsNextDo(&fieldWalkState);
246238
}
239+
field = romFieldsNextDo(&fieldWalkState);
247240
}
248241
}
249242
done:

0 commit comments

Comments
 (0)