Skip to content

Commit

Permalink
Merge pull request #20759 from ThanHenderson/snapshothidden
Browse files Browse the repository at this point in the history
Add hiddenInstanceFields to the VM snapshot
  • Loading branch information
babsingh authored Dec 5, 2024
2 parents 70dd02e + f4e685d commit ef98195
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 5 deletions.
1 change: 1 addition & 0 deletions runtime/oti/SnapshotFileFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ typedef struct SavedJ9JavaVMStructures {
J9ClassLoader *systemClassLoader;
J9ClassLoader *extensionClassLoader;
J9ClassLoader *applicationClassLoader;
J9HiddenInstanceField *hiddenInstanceFields;
} SavedJ9JavaVMStructures;

/*
Expand Down
27 changes: 27 additions & 0 deletions runtime/vm/VMSnapshotImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,19 @@ VMSnapshotImpl::isImmortalClassLoader(J9ClassLoader *classLoader)
return isImmortal;
}

void
VMSnapshotImpl::saveHiddenInstanceFields()
{
_snapshotHeader->savedJavaVMStructs.hiddenInstanceFields = _vm->hiddenInstanceFields;
}

void
VMSnapshotImpl::restoreHiddenInstanceFields()
{
_vm->hiddenInstanceFields = _snapshotHeader->savedJavaVMStructs.hiddenInstanceFields;
}


void
printAllSegments(J9MemorySegmentList *segmentList, J9JavaVM *_vm)
{
Expand Down Expand Up @@ -806,6 +819,7 @@ VMSnapshotImpl::saveJ9JavaVMStructures()
saveClassLoaderBlocks();
saveMemorySegments();
savePrimitiveAndArrayClasses();
saveHiddenInstanceFields();
_snapshotHeader->vm = _vm;
}

Expand All @@ -821,6 +835,7 @@ VMSnapshotImpl::restoreJ9JavaVMStructures()
restoreClassLoaderBlocks();
restoreMemorySegments();
restorePrimitiveAndArrayClasses();
restoreHiddenInstanceFields();

if (omrthread_monitor_init_with_name(&_vm->classMemorySegments->segmentMutex, 0, "VM class mem segment list")) {
success = false;
Expand All @@ -833,6 +848,17 @@ VMSnapshotImpl::restoreJ9JavaVMStructures()
return success;
}

/**
* Some data written to the snapshot cannot be freed at their usual points during VM shutdown.
* This function handles those data to ensure that they are freed after they are written to
* the snapshot.
*/
void
VMSnapshotImpl::freeJ9JavaVMStructures()
{
freeHiddenInstanceFieldsList(_vm);
}

bool
VMSnapshotImpl::writeSnapshotToFile()
{
Expand Down Expand Up @@ -1083,6 +1109,7 @@ teardownVMSnapshotImpl(J9JavaVM *javaVM)
} else {
vmSnapshotImpl->saveMemorySegments();
}
vmSnapshotImpl->freeJ9JavaVMStructures();
}

extern "C" void
Expand Down
3 changes: 3 additions & 0 deletions runtime/vm/VMSnapshotImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class VMSnapshotImpl
bool restoreJ9JavaVMStructures();
void savePrimitiveAndArrayClasses();
bool isImmortalClassLoader(J9ClassLoader *classLoader);
void saveHiddenInstanceFields();
void restoreHiddenInstanceFields();
J9MemorySegmentList *copyUnPersistedMemorySegmentsToNewList(J9MemorySegmentList *oldMemorySegmentList);

protected:
Expand All @@ -118,6 +120,7 @@ class VMSnapshotImpl
void fixupJITVtable(J9Class *ramClass);
void fixupVMStructures();
void writeSnapshot();
void freeJ9JavaVMStructures();

void *subAllocateMemory(uintptr_t byteAmount, bool sub4G);
void *reallocateMemory(void *address, uintptr_t byteAmount, bool sub4G);
Expand Down
4 changes: 3 additions & 1 deletion runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,9 @@ freeJavaVM(J9JavaVM * vm)
#endif /* J9VM_INTERP_ATOMIC_FREE_JNI_USES_FLUSH */

freeNativeMethodBindTable(vm);
freeHiddenInstanceFieldsList(vm);
if (!IS_SNAPSHOTTING_ENABLED(vm)) {
freeHiddenInstanceFieldsList(vm);
}
cleanupLockwordConfig(vm);
cleanupEnsureHashedConfig(vm);

Expand Down
67 changes: 63 additions & 4 deletions runtime/vm/resolvefield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ static J9ROMFieldShape* findFieldInTable(J9VMThread *vmThread, J9Class *clazz, U
static J9ROMFieldShape * findFieldInClass (J9VMThread *vmStruct, J9Class *clazz, U_8 *fieldName, UDATA fieldNameLength, U_8 *signature, UDATA signatureLength, UDATA *offsetOrAddress, J9Class **definingClass);
static J9ROMFieldShape* findFieldAndCheckVisibility (J9VMThread *vmStruct, J9Class *clazz, U_8 *fieldName, UDATA fieldNameLength, U_8 *signature, UDATA signatureLength, J9Class **definingClass, UDATA *offsetOrAddress, UDATA options, J9Class *sourceClass);
static J9ROMFieldShape* findField (J9VMThread *vmStruct, J9Class *clazz, U_8 *fieldName, UDATA fieldNameLength, U_8 *signature, UDATA signatureLength, J9Class **definingClass, UDATA *offsetOrAddress, UDATA options);
#if defined(J9VM_OPT_SNAPSHOTS)
static UDATA findHiddenInstanceFieldOffset(J9JavaVM *javaVM, const char *className, const char *fieldName, const char *signature);
#endif /* defined(J9VM_OPT_SNAPSHOTS) */
VMINLINE static UDATA calculateJ9UTFSize(UDATA stringLength);
VMINLINE static UDATA calculateFakeJ9ROMFieldShapeSize(UDATA nameLength, UDATA signatureLength);
static void initFakeJ9ROMFieldShape(J9ROMFieldShape *shape, U_16 nameLength, U_8 *nameData, U_16 signatureLength, U_8 *signatureData);
Expand Down Expand Up @@ -238,7 +241,42 @@ findFieldInClass(J9VMThread *vmStruct, J9Class *clazz, U_8 *fieldName, UDATA fie
return shape;
}

#if defined(J9VM_OPT_SNAPSHOTS)
static UDATA
findHiddenInstanceFieldOffset(J9JavaVM *javaVM, const char *className, const char *fieldName, const char *signature)
{
J9HiddenInstanceField *field = javaVM->hiddenInstanceFields;
UDATA offset = UDATA_MAX;
const UDATA classNameLength = strlen(className);
const UDATA fieldNameLength = strlen(fieldName);
const UDATA signatureLength = strlen(signature);

while (NULL != field) {
J9UTF8 *currentClassName = field->className;
J9UTF8 *currentFieldName = J9ROMFIELDSHAPE_NAME(field->shape);
J9UTF8 *currentFieldSig = J9ROMFIELDSHAPE_SIGNATURE(field->shape);
const UDATA currentClassNameLength = J9UTF8_LENGTH(currentClassName);
const UDATA currentFieldNameLength = J9UTF8_LENGTH(currentFieldName);
const UDATA currentSignatureLength = J9UTF8_LENGTH(currentFieldSig);

if ((classNameLength == currentClassNameLength)
&& (fieldNameLength == currentFieldNameLength)
&& (signatureLength == currentSignatureLength)
) {
if (J9UTF8_DATA_EQUALS(J9UTF8_DATA(currentClassName), currentClassNameLength, className, classNameLength)
&& J9UTF8_DATA_EQUALS(J9UTF8_DATA(currentFieldName), currentFieldNameLength, fieldName, fieldNameLength)
&& J9UTF8_DATA_EQUALS(J9UTF8_DATA(currentFieldSig), currentSignatureLength, signature, signatureLength)
) {
offset = field->fieldOffset;
break;
}
}
field = field->next;
}

return offset;
}
#endif /* defined(J9VM_OPT_SNAPSHOTS) */

IDATA
instanceFieldOffset(J9VMThread *vmStruct, J9Class *clazz, U_8 *fieldName, UDATA fieldNameLength, U_8 *signature, UDATA signatureLength, J9Class **definingClass, UDATA *instanceField, UDATA options)
Expand Down Expand Up @@ -488,7 +526,9 @@ initializeHiddenInstanceFieldsList(J9JavaVM *vm)
goto destroyMutexAndCleanup;
}

vm->hiddenInstanceFields = NULL;
if (!IS_RESTORE_RUN(vm)) {
vm->hiddenInstanceFields = NULL;
}

exit:
return rc;
Expand Down Expand Up @@ -516,7 +556,15 @@ freeHiddenInstanceFieldsList(J9JavaVM *vm)
while (NULL != field) {
J9HiddenInstanceField *next = field->next;

j9mem_free_memory(field);
#if defined(J9VM_OPT_SNAPSHOTS)
if (IS_SNAPSHOT_RUN(vm)) {
VMSNAPSHOTIMPLPORT_ACCESS_FROM_JAVAVM(vm);
vmsnapshot_free_memory(field);
} else if (!IS_RESTORE_RUN(vm))
#endif /* defined(J9VM_OPT_SNAPSHOTS) */
{
j9mem_free_memory(field);
}
field = next;
}
vm->hiddenInstanceFields = NULL;
Expand Down Expand Up @@ -579,10 +627,13 @@ addHiddenInstanceField(J9JavaVM *vm, const char *className, const char *fieldNam
if ((NULL != vm->systemClassLoader)
&& (NULL != hashClassTableAt(vm->systemClassLoader, (U_8*)className, classNameLength))
) {
/* By this point during a restore run, the hidden field is already added. */
#if defined(J9VM_OPT_SNAPSHOTS)
/* By this point during a restore run, the hidden field is already added. Just fill in the offset. */
if (IS_RESTORE_RUN(vm)) {
*offsetReturn = findHiddenInstanceFieldOffset(vm, className, fieldName, fieldSignature);
return 0;
}
#endif /* defined(J9VM_OPT_SNAPSHOTS) */
return 2;
}

Expand All @@ -604,7 +655,15 @@ addHiddenInstanceField(J9JavaVM *vm, const char *className, const char *fieldNam
}

/* All is good - proceed to add the entry to the start of the list. */
field = (J9HiddenInstanceField *) j9mem_allocate_memory(neededSize, OMRMEM_CATEGORY_VM);
#if defined(J9VM_OPT_SNAPSHOTS)
if (IS_SNAPSHOT_RUN(vm)) {
VMSNAPSHOTIMPLPORT_ACCESS_FROM_JAVAVM(vm);
field = (J9HiddenInstanceField *)vmsnapshot_allocate_memory(neededSize, OMRMEM_CATEGORY_VM);
} else
#endif /* defined(J9VM_OPT_SNAPSHOTS) */
{
field = (J9HiddenInstanceField *)j9mem_allocate_memory(neededSize, OMRMEM_CATEGORY_VM);
}
if (NULL == field) {
omrthread_monitor_exit(vm->hiddenInstanceFieldsMutex);
return 4;
Expand Down

0 comments on commit ef98195

Please sign in to comment.