int32_t GCConfigTest::attachChildEntry(ObjectEntry *parentEntry, ObjectEntry *childEntry) { int32_t rc = 0; MM_GCExtensionsBase *extensions = (MM_GCExtensionsBase *)exampleVM->_omrVM->_gcOmrVMExtensions; uintptr_t size = extensions->objectModel.getConsumedSizeInBytesWithHeader(parentEntry->objPtr); fomrobject_t *firstSlot = (fomrobject_t *)parentEntry->objPtr + 1; fomrobject_t *endSlot = (fomrobject_t *)((uint8_t *)parentEntry->objPtr + size); uintptr_t slotCount = endSlot - firstSlot; OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); if ((uint32_t)parentEntry->numOfRef < slotCount) { fomrobject_t *childSlot = firstSlot + parentEntry->numOfRef; #if defined(OMR_GC_MODRON_SCAVENGER) cli->generationalWriteBarrierStore(exampleVM->_omrVMThread, parentEntry->objPtr, childSlot, childEntry->objPtr); #endif /* OMR_GC_MODRON_SCAVENGER */ #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd child %s(%p[0x%llx]) to parent %s(%p[0x%llx]) slot %p[%llx].\n", childEntry->name, childEntry->objPtr, *(childEntry->objPtr), parentEntry->name, parentEntry->objPtr, *(parentEntry->objPtr), childSlot, (uintptr_t)*childSlot); #endif parentEntry->numOfRef += 1; } else { omrtty_printf("%s:%d Invalid XML input: numOfFields %d defined for %s(%p[0x%llx]) is not enough to hold child reference for %s(%p[0x%llx]).\n", __FILE__, __LINE__, parentEntry->numOfRef, parentEntry->name, parentEntry->objPtr, *(parentEntry->objPtr), childEntry->name, childEntry->objPtr, *(childEntry->objPtr)); rc = 1; } return rc; }
int32_t GCConfigTest::triggerOperation(pugi::xml_node node) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; for (; node; node = node.next_sibling()) { if (0 == strcmp(node.name(), "systemCollect")) { const char *gcCodeStr = node.attribute("gcCode").value(); if (0 == strcmp(gcCodeStr, "")) { /* gcCode defaults to J9MMCONSTANT_IMPLICIT_GC_DEFAULT */ gcCodeStr = "0"; } uint32_t gcCode = (uint32_t)atoi(gcCodeStr); omrtty_printf("Invoking gc system collect with gcCode %d...\n", gcCode); rt = (int32_t)OMR_GC_SystemCollect(exampleVM->_omrVMThread, gcCode); if (OMR_ERROR_NONE != rt) { omrtty_printf("%s:%d Failed to perform OMR_GC_SystemCollect with error code %d.\n", __FILE__, __LINE__, rt); goto done; } OMRGCTEST_CHECK_RT(rt); verboseManager->getWriterChain()->endOfCycle(env); } } done: return rt; }
ObjectEntry * GCConfigTest::createObject(const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); ObjectEntry *objEntry = NULL; char *objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM); if (NULL == objName) { omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow); objEntry = find(objName); if (NULL != objEntry) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("Found object %s in object table.\n", objEntry->name); #endif omrmem_free_memory(objName); } else { objEntry = allocateHelper(objName, size); if (NULL != objEntry) { /* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */ if ((ROOT == objType) || (NORMAL == objType)) { gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(objEntry->objPtr); } } else { omrmem_free_memory(objName); } } done: return objEntry; }
int32_t GCConfigTest::removeObjectFromRootTable(const char *name) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 0; RootEntry searchEntry; RootEntry *rEntryPtr = NULL; searchEntry.name = name; rEntryPtr = (RootEntry *)hashTableFind(exampleVM->rootTable, &searchEntry); if (NULL == rEntryPtr) { rt = 1; omrtty_printf("%s:%d Failed to find root object %s in root table.\n", __FILE__, __LINE__, name); goto done; } if (0 != hashTableRemove(exampleVM->rootTable, rEntryPtr)) { rt = 1; omrtty_printf("%s:%d Failed to remove root object %s from root table!\n", __FILE__, __LINE__, name); goto done; } #if defined(OMRGCTEST_DEBUG) omrtty_printf("Remove object(%s) from root table.\n", name); #endif done: return rt; }
int32_t GCConfigTest::removeObjectFromParentSlot(const char *name, omrobjectptr_t parentPtr) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 1; GC_ObjectIterator objectIterator(exampleVM->_omrVM, parentPtr); GC_SlotObject *slotObject = NULL; ObjectEntry *objEntry; rt = objectTable.find(&objEntry, name); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, name); goto done; } while (NULL != (slotObject = objectIterator.nextSlot())) { if (objEntry->objPtr == slotObject->readReferenceFromSlot()) { slotObject->writeReferenceToSlot(NULL); rt = 0; break; } } if (0 != rt) { omrtty_printf("%s:%d Failed to find object %s from its parent's slot.\n", __FILE__, __LINE__, name); goto done; } #if defined(OMRGCTEST_DEBUG) omrtty_printf("Remove object %s from its parent's slot.\n", name); #endif done: return rt; }
void OMR_MethodDictionary::print() { OMRPORT_ACCESS_FROM_OMRVM(_vm); omrtty_printf("OMR Method Dictionary\n"); omrtty_printf("=====================\n"); omrtty_printf("%016s %032s %032s %032s %10s\n", "key", "methodName", "className", "fileName", "lineNumber"); hashTableForEachDo(_hashTable, OMR_MethodDictionary::printEntry, this); }
void printFile(const char *name) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); intptr_t fileDescriptor = omrfile_open(name, EsOpenRead, 0444); char readBuf[2048]; while (readBuf == omrfile_read_text(fileDescriptor, readBuf, 2048)) { omrtty_printf("%s", readBuf); } omrfile_close(fileDescriptor); omrtty_printf("\n"); }
uintptr_t OMR_MethodDictionary::printEntry(void *entry, void *userData) { OMR_MethodDictionary *md = (OMR_MethodDictionary *)userData; OMR_MethodDictionaryEntry *mdEntry = (OMR_MethodDictionaryEntry *)entry; OMRPORT_ACCESS_FROM_OMRVM(md->_vm); omrtty_printf("%016p", mdEntry->key); for (size_t i = 0; i < md->_numProperties; ++i) { if (mdEntry->propertyValues[i]) { omrtty_printf(" %s", mdEntry->propertyValues[i]); } } omrtty_printf("\n"); return FALSE; /* don't remove the entry */ }
static void testDispatch(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, uintptr_t event, uintptr_t expectedResult) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); uintptr_t count = 0; switch (event) { case TESTHOOK_EVENT1: TRIGGER_TESTHOOK_EVENT1(sampleHookInterface, count, -1); break; case TESTHOOK_EVENT2: TRIGGER_TESTHOOK_EVENT2(sampleHookInterface, 1, count, -1); break; case TESTHOOK_EVENT3: TRIGGER_TESTHOOK_EVENT3(sampleHookInterface, 2, 3, count, -1); break; case TESTHOOK_EVENT4: TRIGGER_TESTHOOK_EVENT4(sampleHookInterface, 4, 5, 6, count, -1); break; } if (count == expectedResult) { (*passCount)++; } else { omrtty_printf("Incorrect number of listeners responded for 0x%zx. Got %d, expected %d\n", event, count, expectedResult); (*failCount)++; } }
int32_t GCConfigTest::parseGarbagePolicy(pugi::xml_node node) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; gp.namePrefix = NULL; gp.percentage = 0.0f; gp.frequency = "none"; gp.structure = NULL; gp.accumulatedSize = 0; if (!node.empty()) { gp.namePrefix = node.attribute("namePrefix").value(); if (0 == strcmp(gp.namePrefix, "")) { gp.namePrefix = "GARBAGE"; } const char* percentageStr = node.attribute("percentage").value(); if (0 == strcmp(percentageStr, "")) { percentageStr = "100"; } gp.percentage = (float)atof(percentageStr); gp.frequency = node.attribute("frequency").value(); if (0 == strcmp(gp.frequency, "")) { gp.frequency = "perRootStruct"; } if ((0 != strcmp(gp.frequency, "perObject")) && (0 != strcmp(gp.frequency, "perRootStruct"))){ rt = 1; omrtty_printf("%s:%d Invalid XML input: the valid value of attribute \"frequency\" is \"perObject\" or \"perRootStruct\".\n", __FILE__, __LINE__); goto done; } gp.structure = node.attribute("structure").value(); if (0 == strcmp(gp.structure, "")) { gp.structure = "node"; } if ((0 != strcmp(gp.structure, "node")) && (0 != strcmp(gp.structure, "tree"))){ rt = 1; omrtty_printf("%s:%d Invalid XML input: the valid value of attribute \"structure\" is \"node\" or \"tree\".\n", __FILE__, __LINE__); goto done; } } done: return rt; }
/** * Initialize a new lock object. * A lock must be initialized before it may be used. * * @param env * @param options * @param name Lock name * @return TRUE on success * @note Creates a store barrier. */ bool MM_LightweightNonReentrantLock::initialize(MM_EnvironmentBase *env, ModronLnrlOptions *options, const char * name) { OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary()); /* initialize variables in case constructor was not called */ _initialized = false; _tracing = NULL; _extensions = env->getExtensions(); if (NULL != _extensions) { J9Pool* tracingPool = _extensions->_lightweightNonReentrantLockPool; if (NULL != tracingPool) { omrthread_monitor_enter(_extensions->_lightweightNonReentrantLockPoolMutex); _tracing = (J9ThreadMonitorTracing *)pool_newElement(tracingPool); omrthread_monitor_exit(_extensions->_lightweightNonReentrantLockPoolMutex); if (NULL == _tracing) { goto error_no_memory; } _tracing->monitor_name = NULL; if (NULL != name) { uintptr_t length = omrstr_printf(NULL, 0, "[%p] %s", this, name) + 1; if (length > MAX_LWNR_LOCK_NAME_SIZE) { goto error_no_memory; } _tracing->monitor_name = _nameBuf; if (NULL == _tracing->monitor_name) { goto error_no_memory; } omrstr_printf(_tracing->monitor_name, length, "[%p] %s", this, name); } } } #if defined(OMR_ENV_DATA64) if(0 != (((uintptr_t)this) % sizeof(uintptr_t))) { omrtty_printf("GC FATAL: LWNRL misaligned.\n"); abort(); } #endif #if defined(J9MODRON_USE_CUSTOM_SPINLOCKS) _initialized = omrgc_spinlock_init(&_spinlock) ? false : true; _spinlock.spinCount1 = options->spinCount1; _spinlock.spinCount2 = options->spinCount2; _spinlock.spinCount3 = options->spinCount3; #else /* J9MODRON_USE_CUSTOM_SPINLOCKS */ _initialized = MUTEX_INIT(_mutex) ? true : false; #endif /* J9MODRON_USE_CUSTOM_SPINLOCKS */ return _initialized; error_no_memory: return false; }
int32_t GCConfigTest::allocateHelper(omrobjectptr_t *obj, char *objName, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; uintptr_t actualSize = 0; MM_ObjectAllocationInterface *allocationInterface = env->_objectAllocationInterface; MM_GCExtensionsBase *extensions = env->getExtensions(); uintptr_t allocatedFlags = 0; uintptr_t sizeAdjusted = extensions->objectModel.adjustSizeInBytes(size); MM_AllocateDescription mm_allocdescription(sizeAdjusted, allocatedFlags, true, true); *obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), false); if (NULL == *obj) { omrtty_printf("No free memory to allocate %s, GC start.\n", objName); *obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), true); env->unwindExclusiveVMAccessForGC(); if (NULL == *obj) { rt = 1; omrtty_printf("%s:%d No free memory after a GC. Failed to allocate object %s.\n", __FILE__, __LINE__, objName); goto done; } verboseManager->getWriterChain()->endOfCycle(env); } actualSize = mm_allocdescription.getBytesRequested(); if (NULL != *obj) { memset(*obj, 0, actualSize); } /* set size in header */ extensions->objectModel.setObjectSize(*obj, actualSize); #if defined(OMRGCTEST_DEBUG) omrtty_printf("Allocate object name: %s; size: %dB; objPtr: %llu\n", objName, actualSize, *obj); #endif done: return rt; }
int32_t GCConfigTest::parseAttribute(AttributeElem **root, const char *attrStr) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; const char DELIM = ','; char *copyOfAttrStr = (char *)omrmem_allocate_memory(strlen(attrStr) + 1, OMRMEM_CATEGORY_MM); char *attrStart = NULL; char *attrEnd = NULL; if (NULL == copyOfAttrStr) { rt = 1; omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } strcpy(copyOfAttrStr, attrStr); attrStart = copyOfAttrStr; attrEnd = attrStart; while (NULL != attrEnd) { attrEnd = strchr(attrStart, DELIM); int32_t attr = 0; if (NULL != attrEnd) { *attrEnd = '\0'; attr = atoi(attrStart); attrStart = attrEnd + 1; } else { attr = atoi(attrStart); } AttributeElem *attrNode = (AttributeElem *)omrmem_allocate_memory(sizeof(AttributeElem), OMRMEM_CATEGORY_MM); if (NULL == attrNode) { rt = 1; omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } attrNode->value = attr; J9_LINKED_LIST_ADD_LAST(*root, attrNode); } omrmem_free_memory(copyOfAttrStr); done: return rt; }
static omr_error_t testTraceAgentGetMemorySize(OMR_VMThread *vmThread, OMR_TI const *ti) { OMRPORT_ACCESS_FROM_OMRVMTHREAD(vmThread); omr_error_t rc = OMR_ERROR_NONE; omr_error_t testRc = OMR_ERROR_NONE; uint64_t memorySize = 0; #if defined(LINUX) || defined(AIXPPC) || defined(OMR_OS_WINDOWS) || defined(OSX) if (OMR_ERROR_NONE == testRc) { rc = OMRTEST_PRINT_ERROR(ti->GetFreePhysicalMemorySize(vmThread, &memorySize)); if (OMR_ERROR_NONE != rc) { omrtty_printf("%s:%d GetFreePhysicalMemorySize() failed !\n", __FILE__, __LINE__); testRc = OMR_ERROR_INTERNAL; } else { omrtty_printf("%s:%d Free physical memory size (in bytes): %llu, rc = %d (%s), the function call is successful !\n", __FILE__, __LINE__, memorySize, rc, omrErrorToString(rc)); } } #if defined(LINUX) || defined(OMR_OS_WINDOWS) || defined(OSX) if (OMR_ERROR_NONE == testRc) { rc = OMRTEST_PRINT_ERROR(ti->GetProcessVirtualMemorySize(vmThread, &memorySize)); if (OMR_ERROR_NONE != rc) { omrtty_printf("%s:%d GetProcessVirtualMemorySize() failed !\n", __FILE__, __LINE__); testRc = OMR_ERROR_INTERNAL; } else { omrtty_printf("%s:%d Process virtual memory size (in bytes): %llu, rc = %d (%s), the function call is successful !\n", __FILE__, __LINE__, memorySize, rc, omrErrorToString(rc)); } } if (OMR_ERROR_NONE == testRc) { rc = OMRTEST_PRINT_ERROR(ti->GetProcessPhysicalMemorySize(vmThread, &memorySize)); if (OMR_ERROR_NONE != rc) { omrtty_printf("%s:%d GetProcessPhysicalMemorySize() failed !\n", __FILE__, __LINE__); testRc = OMR_ERROR_INTERNAL; } else { omrtty_printf("%s:%d Process physical memory size (in bytes): %llu, rc = %d (%s), the function call is successful !\n", __FILE__, __LINE__, memorySize, rc, omrErrorToString(rc)); } } #endif /* defined(LINUX) || defined(OMR_OS_WINDOWS) || defined(OSX) */ #if defined(LINUX) || defined(AIXPPC)|| defined(OMR_OS_WINDOWS) if (OMR_ERROR_NONE == testRc) { rc = OMRTEST_PRINT_ERROR(ti->GetProcessPrivateMemorySize(vmThread, &memorySize)); if (OMR_ERROR_NONE != rc) { omrtty_printf("%s:%d GetProcessPrivateMemorySize() failed !\n", __FILE__, __LINE__); testRc = OMR_ERROR_INTERNAL; } else { omrtty_printf("%s:%d Process private memory size (in bytes): %llu, rc = %d (%s), the function call is successful !\n", __FILE__, __LINE__, memorySize, rc, omrErrorToString(rc)); } } #endif /* defined(LINUX) || defined(AIXPPC) || defined(OMR_OS_WINDOWS) */ #endif /* defined(LINUX) || defined(AIXPPC) || defined(OMR_OS_WINDOWS) || defined(OSX) */ return testRc; }
static omr_error_t startTestChildThread(OMRTestVM *testVM, OMR_VMThread *curVMThread, omrthread_t *childThread, TestChildThreadData **childData) { omr_error_t rc = OMR_ERROR_NONE; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); TestChildThreadData *newChildData = (TestChildThreadData *)omrmem_allocate_memory(sizeof(*newChildData), OMRMEM_CATEGORY_VM); if (NULL == newChildData) { rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY; omrtty_printf("%s:%d ERROR: Failed to alloc newChildData\n", __FILE__, __LINE__); } if (OMR_ERROR_NONE == rc) { if (0 != omrthread_monitor_init_with_name(&newChildData->shutdownCond, 0, "traceTestChildShutdown")) { rc = OMR_ERROR_FAILED_TO_ALLOCATE_MONITOR; omrtty_printf("%s:%d ERROR: Failed to init shutdownCond monitor\n", __FILE__, __LINE__); omrmem_free_memory(newChildData); } else { newChildData->testVM = testVM; newChildData->isDead = FALSE; newChildData->childRc = OMR_ERROR_NONE; } } if (OMR_ERROR_NONE == rc) { if (0 != omrthread_create_ex( NULL, /* handle */ J9THREAD_ATTR_DEFAULT, /* attr */ FALSE, /* suspend */ childThreadMain, /* entrypoint */ newChildData) /* entryarg */ ) { rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY; omrtty_printf("%s:%d ERROR: Failed to init shutdownCond monitor\n", __FILE__, __LINE__); omrthread_monitor_destroy(newChildData->shutdownCond); omrmem_free_memory(newChildData); } else { *childData = newChildData; } } return rc; }
static void testRegisterWithAgent(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, J9HookInterface **hookInterface, uintptr_t event, uintptr_t agentID, uintptr_t userData, uintptr_t expectedResult) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); if (((*hookInterface)->J9HookRegisterWithCallSite(hookInterface, event | J9HOOK_TAG_AGENT_ID, hookOrderedEvent, OMR_GET_CALLSITE(), (void *)userData, agentID) == 0) == (expectedResult == 0)) { (*passCount)++; } else { omrtty_printf("J9HookRegisterWithCallSite for 0x%zx %s. It should have %s.\n", event, (expectedResult ? "succeeded" : "failed"), (expectedResult ? "failed" : "succeeded")); (*failCount)++; } }
static void testRegister(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, J9HookInterface **hookInterface, uintptr_t event, uintptr_t expectedResult) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); if (((*hookInterface)->J9HookRegisterWithCallSite(hookInterface, event, hookNormalEvent, OMR_GET_CALLSITE(), NULL) == 0) == (expectedResult == 0)) { (*passCount)++; } else { omrtty_printf("J9HookRegisterWithCallSite for 0x%zx %s. It should have %s.\n", event, (expectedResult ? "succeeded" : "failed"), (expectedResult ? "failed" : "succeeded")); (*failCount)++; } }
static void testReserve(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, J9HookInterface **hookInterface, uintptr_t event, uintptr_t expectedResult) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); if (((*hookInterface)->J9HookReserve(hookInterface, event) == 0) == (expectedResult == 0)) { (*passCount)++; } else { omrtty_printf("J9HookReserve for 0x%zx %s. It should have %s.\n", event, (expectedResult ? "succeeded" : "failed"), (expectedResult ? "failed" : "succeeded")); (*failCount)++; } }
static void testEnabled(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, J9HookInterface **hookInterface, uintptr_t event, uintptr_t expectedResult) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); if (((*hookInterface)->J9HookIsEnabled(hookInterface, event) == 0) == (expectedResult == 0)) { (*passCount)++; } else { omrtty_printf("Hook 0x%zx is %s. It should be %s.\n", event, (expectedResult ? "disabled" : "enabled"), (expectedResult ? "enabled" : "disabled")); (*failCount)++; } }
/* * Debug routine to dump details of the current state of the freelist */ void MM_MemoryPoolSplitAddressOrderedListBase::printCurrentFreeList(MM_EnvironmentBase* env, const char* area) { OMRPORT_ACCESS_FROM_ENVIRONMENT(env); omrtty_printf("Analysis of %s freelist: \n", area); for (uintptr_t i = 0; i < _heapFreeListCountExtended; ++i) { MM_HeapLinkedFreeHeader* currentFreeEntry = _heapFreeLists[i]._freeList; while (currentFreeEntry) { const char * msg = "Free chunk %p -> %p (%i) \n"; if (_heapFreeListCount == i) { msg = "Reserved chunk %p -> %p (%i) \n"; } omrtty_printf(msg, currentFreeEntry, currentFreeEntry->afterEnd(), currentFreeEntry->getSize()); currentFreeEntry = currentFreeEntry->getNext(); } } }
ObjectEntry * GCConfigTest::allocateHelper(const char *objName, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); MM_ObjectAllocationInterface *allocationInterface = env->_objectAllocationInterface; MM_GCExtensionsBase *extensions = env->getExtensions(); uintptr_t allocatedFlags = 0; uintptr_t sizeAdjusted = extensions->objectModel.adjustSizeInBytes(size); MM_AllocateDescription mm_allocdescription(sizeAdjusted, allocatedFlags, true, true); ObjectEntry objEntry; objEntry.name = objName; objEntry.objPtr = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), false); objEntry.numOfRef = 0; ObjectEntry *hashedEntry = NULL; if (NULL == objEntry.objPtr) { omrtty_printf("No free memory to allocate %s of size 0x%llx, GC start.\n", objName, size); objEntry.objPtr = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), true); env->unwindExclusiveVMAccessForGC(); if (NULL == objEntry.objPtr) { omrtty_printf("%s:%d No free memory after a GC. Failed to allocate object %s of size 0x%llx.\n", __FILE__, __LINE__, objName, size); goto done; } verboseManager->getWriterChain()->endOfCycle(env); } if (NULL != objEntry.objPtr) { /* set size in header */ uintptr_t actualSize = mm_allocdescription.getBytesRequested(); memset(objEntry.objPtr, 0, actualSize); extensions->objectModel.setObjectSize(objEntry.objPtr, actualSize); #if defined(OMRGCTEST_DEBUG) omrtty_printf("Allocate object name: %s(%p[0x%llx])\n", objEntry.name, objEntry.objPtr, actualSize); #endif hashedEntry = add(&objEntry); } done: return hashedEntry; }
TEST_P(GCConfigTest, test) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; pugi::xml_node configNode = doc.select_node("/gc-config").node().first_child(); if (0 == strcmp(configNode.name(), "option")) { configNode = configNode.next_sibling(); } for (; configNode; configNode = configNode.next_sibling()) { if (0 == strcmp(configNode.name(), "allocation")) { omrtty_printf("\n+++++++++++++++++++++++++++Allocation+++++++++++++++++++++++++++\n"); rt = parseGarbagePolicy(configNode.child("garbagePolicy")); ASSERT_EQ(0, rt) << "Failed to parse garbage policy."; pugi::xpath_node_set objects = configNode.select_nodes("object"); int64_t startTime = omrtime_current_time_millis(); for (pugi::xpath_node_set::const_iterator it = objects.begin(); it != objects.end(); ++it) { rt = allocationWalker(it->node()); ASSERT_EQ(0, rt) << "Failed to perform allocation."; } omrtty_printf("Time elapsed in allocation: %lld ms\n", (omrtime_current_time_millis() - startTime)); } else if (0 == strcmp(configNode.name(), "verification")) { omrtty_printf("\n++++++++++++++++++++++++++Verification++++++++++++++++++++++++++\n"); /* verboseGC verification */ pugi::xpath_node_set verboseGCs = configNode.select_nodes("verboseGC"); rt = verifyVerboseGC(verboseGCs); ASSERT_EQ(0, rt) << "Failed in verbose GC verification."; omrtty_printf("[ Verification Successful ]\n\n"); } else if (0 == strcmp(configNode.name(), "operation")) { omrtty_printf("\n++++++++++++++++++++++++++++Operation+++++++++++++++++++++++++++\n"); rt = triggerOperation(configNode.first_child()); ASSERT_EQ(0, rt) << "Failed to perform gc operation."; } else if (0 == strcmp(configNode.name(), "mutation")) { /*TODO*/ } else { FAIL() << "Invalid XML input: unrecognized XML node \"" << configNode.name() << "\" in configuration file."; } } }
int32_t GCConfigTest::removeObjectFromObjectTable(const char *name) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 1; ObjectEntry *foundEntry = find(name); if (NULL == foundEntry) { omrtty_printf("%s:%d Failed to find object %s in object table.\n", __FILE__, __LINE__, name); goto done; } if (0 != hashTableRemove(exampleVM->objectTable, foundEntry)) { omrtty_printf("%s:%d Failed to remove object %s from object table!\n", __FILE__, __LINE__, name); goto done; } #if defined(OMRGCTEST_DEBUG) omrtty_printf("Remove object %s(%p[0x%llx]) from object table.\n", name, foundEntry->objPtr, *(foundEntry->objPtr)); #endif rt = 0; done: return rt; }
OMRGCObjectType GCConfigTest::parseObjectType(pugi::xml_node node) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); const char *namePrefixStr = node.attribute("namePrefix").value(); const char *typeStr = node.attribute("type").value(); const char *parentStr = node.parent().name(); const char *parentTypeStr = node.parent().attribute("type").value(); OMRGCObjectType objType = INVALID; if (0 == strcmp(typeStr, "root")) { if (0 == strcmp(parentStr, "allocation")) { objType = ROOT; } else { omrtty_printf("%s:%d Invalid XML input: root object %s can not be child of other object!\n", __FILE__, __LINE__, namePrefixStr); } } else if (0 == strcmp(typeStr, "normal")) { if ((0 == strcmp(parentTypeStr, "root")) || (0 == strcmp(parentTypeStr, "normal"))) { objType = NORMAL; } else { omrtty_printf("%s:%d Invalid XML input: normal object %s has to be child of root or normal object!\n", __FILE__, __LINE__, namePrefixStr); } } else if (0 == strcmp(typeStr, "garbage")) { if (0 == strcmp(parentStr, "allocation")) { objType = GARBAGE_ROOT; } else if ((0 == strcmp(parentTypeStr, "normal")) || (0 == strcmp(parentTypeStr, "root"))){ objType = GARBAGE_TOP; } else if (0 == strcmp(parentTypeStr, "garbage")) { objType = GARBAGE_CHILD; } else { omrtty_printf("%s:%d Invalid XML input: garbage object %s has to be child of root, normal or allocation node!\n", __FILE__, __LINE__, namePrefixStr); } } else { omrtty_printf("%s:%d Invalid XML input: object %s type should be root, normal or garbage .\n", __FILE__, __LINE__, namePrefixStr); } return objType; }
int32_t verifyHookable(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount) { int32_t rc = 0; J9HookInterface **hookInterface = J9_HOOK_INTERFACE(sampleHookInterface); OMRPORT_ACCESS_FROM_OMRPORT(portLib); omrtty_printf("Testing hookable interface...\n"); if (J9HookInitializeInterface(hookInterface, portLib, sizeof(sampleHookInterface))) { (*failCount)++; rc = -1; } else { (*passCount)++; rc = testHookInterface(portLib, passCount, failCount, hookInterface); (*hookInterface)->J9HookShutdownInterface(hookInterface); } omrtty_printf("Finished testing hookable interface.\n"); return rc; }
int main(void) { int32_t totalFiles = 0; intptr_t rc = 0; char resultBuffer[128]; uintptr_t rcFile; uintptr_t handle; OMRPortLibrary portLibrary; rc = omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT); if (0 != rc) { fprintf(stderr, "omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT) failed, rc=%d\n", (int)rc); return -1; } rc = omrport_init_library(&portLibrary, sizeof(OMRPortLibrary)); if (0 != rc) { fprintf(stderr, "omrport_init_library(&portLibrary, sizeof(OMRPortLibrary)), rc=%d\n", (int)rc); return -1; } OMRPORT_ACCESS_FROM_OMRPORT(&portLibrary); rcFile = handle = omrfile_findfirst(SRC_DIR, resultBuffer); if(rcFile == (uintptr_t)-1) { fprintf(stderr, "omrfile_findfirst(SRC_DIR, resultBuffer), return code=%d\n", (int)rcFile); return -1; } while ((uintptr_t)-1 != rcFile) { if (strncmp(resultBuffer, VERBOSE_GC_FILE_PREFIX, strlen(VERBOSE_GC_FILE_PREFIX)) == 0) { analyze(resultBuffer, portLibrary); totalFiles++; /* Clean up verbose log file */ omrfile_unlink(resultBuffer); } rcFile = omrfile_findnext(handle, resultBuffer); } if (handle != (uintptr_t)-1) { omrfile_findclose(handle); } if(totalFiles < 1) { omrtty_printf("Failed to find any verbose GC file to process!\n\n"); } portLibrary.port_shutdown_library(&portLibrary); omrthread_detach(NULL); }
int32_t GCConfigTest::removeObjectFromParentSlot(const char *name, ObjectEntry *parentEntry) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); MM_GCExtensionsBase *extensions = (MM_GCExtensionsBase *)exampleVM->_omrVM->_gcOmrVMExtensions; uintptr_t size = extensions->objectModel.getConsumedSizeInBytesWithHeader(parentEntry->objPtr); fomrobject_t *currentSlot = (fomrobject_t *)parentEntry->objPtr + 1; fomrobject_t *endSlot = (fomrobject_t *)((uint8_t *)parentEntry->objPtr + size); int32_t rt = 1; ObjectEntry *objEntry = find(name); if (NULL == objEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, name); goto done; } while (currentSlot < endSlot) { GC_SlotObject slotObject(exampleVM->_omrVM, currentSlot); if (objEntry->objPtr == slotObject.readReferenceFromSlot()) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("Remove object %s(%p[0x%llx]) from parent %s(%p[0x%llx]) slot %p.\n", name, objEntry->objPtr, *(objEntry->objPtr), parentEntry->name, parentEntry->objPtr, *(parentEntry->objPtr), slotObject.readAddressFromSlot()); #endif slotObject.writeReferenceToSlot(NULL); rt = 0; break; } currentSlot += 1; } if (0 != rt) { omrtty_printf("%s:%d Failed to remove object %s from its parent's slot.\n", __FILE__, __LINE__, name); goto done; } done: return rt; }
int32_t GCConfigTest::createObject(omrobjectptr_t *obj, char **objName, const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; ObjectEntry *objEntry = NULL; *objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM); if (NULL == *objName) { rt = 1; omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } omrstr_printf(*objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow); if (0 == objectTable.find(&objEntry, *objName)) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("Find object %s in hash table.\n", *objName); #endif *obj = objEntry->objPtr; } else { rt = allocateHelper(obj, *objName, size); OMRGCTEST_CHECK_RT(rt); /* keep object in table */ rt = objectTable.add(*objName, *obj, 0); OMRGCTEST_CHECK_RT(rt) /* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */ if ((ROOT == objType) || (NORMAL == objType)) { gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(*obj); } } done: return rt; }
static uintptr_t testAllocateAgentID(OMRPortLibrary *portLib, uintptr_t *passCount, uintptr_t *failCount, J9HookInterface **hookInterface) { uintptr_t agentID = (*hookInterface)->J9HookAllocateAgentID(hookInterface); if (agentID != 0) { (*passCount)++; } else { OMRPORT_ACCESS_FROM_OMRPORT(portLib); omrtty_printf("J9HookAllocateAgentID failed.\n"); (*failCount)++; } return agentID; }
int32_t GCConfigTest::insertGarbage() { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 0; char fullNamePrefix[MAX_NAME_LENGTH]; omrstr_printf(fullNamePrefix, sizeof(fullNamePrefix), "%s_%d", gp.namePrefix, gp.garbageSeq++); int32_t breadth = 2; uintptr_t totalSize = (uintptr_t)(gp.accumulatedSize * gp.percentage) / 100; uintptr_t objSize = 0; if (0 == strcmp(gp.structure, "node")) { objSize = totalSize; } else if (0 == strcmp(gp.structure, "tree")) { objSize = 64; } #if defined(OMRGCTEST_DEBUG) omrtty_printf("Inserting garbage %s of %dB (%f%% of previous object/tree size %dB) ...\n", fullNamePrefix, totalSize, gp.percentage, gp.accumulatedSize); #endif omrobjectptr_t rootObj = NULL; rt = createFixedSizeTree(&rootObj, fullNamePrefix, GARBAGE_ROOT, totalSize, objSize, breadth); OMRGCTEST_CHECK_RT(rt); /* remove garbage root object from the root set */ if (NULL != rootObj) { char rootObjName[MAX_NAME_LENGTH]; omrstr_printf(rootObjName, MAX_NAME_LENGTH, "%s_%d_%d", fullNamePrefix, 0, 0); rt = removeObjectFromRootTable(rootObjName); OMRGCTEST_CHECK_RT(rt); } /* reset accumulatedSize */ gp.accumulatedSize = 0; done: return rt; }