void eliminateItem(int key, int value) { struct LRUItem * tailItem = mTailItem; if (key != tailItem->key) { // Remove a key hashTableRemove(tailItem->key); // Add a key hashTableAdd(key, tailItem); tailItem->key = key; } tailItem->value = value; struct LRUItem * newTailItem = tailItem->prev; if (newTailItem) { newTailItem->next = NULL; // Record the last used item mTailItem = newTailItem; } tailItem->prev = NULL; // To avoid their own point to themselves. if (tailItem != mHeadItem) { tailItem->next = mHeadItem; // Record the recent used item mHeadItem->prev = tailItem; mHeadItem = tailItem; } else tailItem->next = NULL; }
void valgrindMempoolAlloc(MM_GCExtensionsBase *extensions, uintptr_t baseAddress, uintptr_t size) { #if defined(VALGRIND_REQUEST_LOGS) VALGRIND_PRINTF_BACKTRACE("Allocating an object at 0x%lx of size %lu\n", baseAddress, size); #endif /* defined(VALGRIND_REQUEST_LOGS) */ /* Allocate object in Valgrind memory pool. */ VALGRIND_MEMPOOL_ALLOC(extensions->valgrindMempoolAddr, baseAddress, size); MUTEX_ENTER(extensions->memcheckHashTableMutex); hashTableAdd(extensions->memcheckHashTable, &baseAddress); MUTEX_EXIT(extensions->memcheckHashTableMutex); }
omr_error_t OMR_MethodDictionary::insert(OMR_MethodDictionaryEntry *entry) { omr_error_t rc = OMR_ERROR_NONE; omrthread_t self = NULL; if (0 == omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT)) { if (0 == omrthread_monitor_enter_using_threadId(_lock, self)) { OMR_MethodDictionaryEntry *newEntry = (OMR_MethodDictionaryEntry *)hashTableAdd(_hashTable, entry); if (NULL == newEntry) { rc = OMR_ERROR_OUT_OF_NATIVE_MEMORY; } else { bool reusedEntry = false; if (!entryValueEquals(newEntry, entry)) { /* There was an existing hash table entry with the same key. * Overwrite its contents. */ traceInsertEntryReplace(newEntry); cleanupEntryStrings(newEntry, this); reusedEntry = true; } /* copy the entry strings */ rc = dupEntryStrings(newEntry, entry); if (OMR_ERROR_NONE == rc) { traceInsertEntrySuccess(newEntry); if (!reusedEntry) { _currentBytes += _sizeofEntry; } _currentBytes += countEntryNameBytesNeeded(newEntry); if (_currentBytes > _maxBytes) { _maxBytes = _currentBytes; _maxEntries = hashTableGetCount(_hashTable); } } } omrthread_monitor_exit_using_threadId(_lock, self); } else { rc = OMR_ERROR_INTERNAL; } omrthread_detach(self); } else { rc = OMR_ERROR_FAILED_TO_ATTACH_NATIVE_THREAD; } if (OMR_ERROR_NONE != rc) { traceInsertEntryFailed(rc, entry); } return rc; }
void appendItem(int key, int value) { struct LRUItem * newItem = mCacheListLast; mCacheListLast++; mCacheSize++; newItem->key = key; newItem->value = value; newItem->prev = NULL; newItem->next = mHeadItem; // Add a key hashTableAdd(key, newItem); if (mHeadItem != NULL) { // Record the recent used item. mHeadItem->prev = newItem; mHeadItem = newItem; } else { // Record the recent used item and the last used item. mHeadItem = mTailItem = newItem; } }
int testMain(int argc, char ** argv, char **envp) { /* Start up */ OMR_VM_Example exampleVM; OMR_VMThread *omrVMThread = NULL; omrthread_t self = NULL; exampleVM._omrVM = NULL; exampleVM.rootTable = NULL; /* Initialize the VM */ omr_error_t rc = OMR_Initialize(&exampleVM, &exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); /* Recursive omrthread_attach() (i.e. re-attaching a thread that is already attached) is cheaper and less fragile * than non-recursive. If performing a sequence of function calls that are likely to attach & detach internally, * it is more efficient to call omrthread_attach() before the entire block. */ int j9rc = (int) omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT); Assert_MM_true(0 == j9rc); /* Initialize root table */ exampleVM.rootTable = hashTableNew( exampleVM._omrVM->_runtime->_portLibrary, OMR_GET_CALLSITE(), 0, sizeof(RootEntry), 0, 0, OMRMEM_CATEGORY_MM, rootTableHashFn, rootTableHashEqualFn, NULL, NULL); /* Initialize heap and collector */ { /* This has to be done in local scope because MM_StartupManager has a destructor that references the OMR VM */ MM_StartupManagerImpl startupManager(exampleVM._omrVM); rc = OMR_GC_IntializeHeapAndCollector(exampleVM._omrVM, &startupManager); } Assert_MM_true(OMR_ERROR_NONE == rc); /* Attach current thread to the VM */ rc = OMR_Thread_Init(exampleVM._omrVM, NULL, &omrVMThread, "GCTestMailThread"); Assert_MM_true(OMR_ERROR_NONE == rc); /* Kick off the dispatcher therads */ rc = OMR_GC_InitializeDispatcherThreads(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); OMRPORT_ACCESS_FROM_OMRVM(exampleVM._omrVM); omrtty_printf("VM/GC INITIALIZED\n"); /* Do stuff */ MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(omrVMThread); MM_ObjectAllocationInterface *allocationInterface = env->_objectAllocationInterface; MM_GCExtensionsBase *extensions = env->getExtensions(); omrtty_printf("configuration is %s\n", extensions->configuration->getBaseVirtualTypeId()); omrtty_printf("collector interface is %s\n", env->getExtensions()->collectorLanguageInterface->getBaseVirtualTypeId()); omrtty_printf("garbage collector is %s\n", env->getExtensions()->getGlobalCollector()->getBaseVirtualTypeId()); omrtty_printf("allocation interface is %s\n", allocationInterface->getBaseVirtualTypeId()); /* Allocate objects without collection until heap exhausted */ uintptr_t allocatedFlags = 0; uintptr_t size = extensions->objectModel.adjustSizeInBytes(24); MM_AllocateDescription mm_allocdescription(size, allocatedFlags, true, true); uintptr_t allocatedCount = 0; while (true) { omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), false); if (NULL != obj) { extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested()); RootEntry rEntry = {"root1", obj}; RootEntry *entryInTable = (RootEntry *)hashTableAdd(exampleVM.rootTable, &rEntry); if (NULL == entryInTable) { omrtty_printf("failed to add new root to root table!\n"); } /* update entry if it already exists in table */ entryInTable->rootPtr = obj; allocatedCount++; } else { break; } } /* Print/verify thread allocation stats before GC */ MM_AllocationStats *allocationStats = allocationInterface->getAllocationStats(); omrtty_printf("thread allocated %d tlh bytes, %d non-tlh bytes, from %d allocations before NULL\n", allocationStats->tlhBytesAllocated(), allocationStats->nontlhBytesAllocated(), allocatedCount); uintptr_t allocationTotalBytes = allocationStats->tlhBytesAllocated() + allocationStats->nontlhBytesAllocated(); uintptr_t allocatedTotalBytes = size * allocatedCount; Assert_MM_true(allocatedTotalBytes == allocationTotalBytes); /* Force GC to print verbose system allocation stats -- should match thread allocation stats from before GC */ omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), true); env->unwindExclusiveVMAccessForGC(); Assert_MM_false(NULL == obj); extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested()); omrtty_printf("ALL TESTS PASSED\n"); /* Shut down */ /* Shut down the dispatcher therads */ rc = OMR_GC_ShutdownDispatcherThreads(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Shut down collector */ rc = OMR_GC_ShutdownCollector(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Detach from VM */ rc = OMR_Thread_Free(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Shut down heap */ rc = OMR_GC_ShutdownHeap(exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); /* Free root hash table */ hashTableFree(exampleVM.rootTable); /* Balance the omrthread_attach_ex() issued above */ omrthread_detach(self); /* Shut down VM * This destroys the port library and the omrthread library. * Don't use any port library or omrthread functions after this. * * (This also shuts down trace functionality, so the trace assertion * macros might not work after this.) */ rc = OMR_Shutdown(exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); return rc; }
int32_t GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; OMR_VM *omrVMPtr = exampleVM->_omrVM; int32_t numOfParents = 0; /* Create objects and store them in the root table or the slot object based on objType. */ if ((ROOT == objType) || (GARBAGE_ROOT == objType)) { for (int32_t i = 0; i < breadthElem->value; i++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = objName; rEntry.rootPtr = obj; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { rt = 1; omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* insert garbage per node */ if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } } else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t i = 0; i < breadthElem->value; i++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to slot of parent(%llu) %d\n", parent, parentEntry->numOfRef + i); #endif /* Add object to parent's slot. If it's the top of the garbage tree, temporarily keep it in the slot until * the rest of the tree is allocated. */ slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } parentEntry->numOfRef += breadthElem->value; } else { rt = 1; goto done; } /* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } numOfParents = breadthElem->value; breadthElem = breadthElem->linkNext; for (int32_t i = 1; i < depth; i++) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t k = 0; k < breadthElem->value; k++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, i, nthInRow, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; nthInRow += 1; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k); #endif slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } parentEntry->numOfRef += breadthElem->value; } numOfParents = nthInRow; breadthElem = breadthElem->linkNext; } done: return rt; }
int32_t GCConfigTest::createFixedSizeTree(omrobjectptr_t *rootObj, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; OMR_VM *omrVMPtr = exampleVM->_omrVM; int32_t depth = 1; int32_t numOfParents = 1; uintptr_t bytesLeft = totalSize; if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { return rt; } } /* allocate the root object */ char *rootObjName = NULL; rt = createObject(rootObj, &rootObjName, namePrefixStr, objType, 0, 0, objSize); OMRGCTEST_CHECK_RT(rt); bytesLeft -= objSize; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = rootObjName; rEntry.rootPtr = *rootObj; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { rt = 1; omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* create the rest of the tree */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } while (bytesLeft > 0) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t k = 0; k < breadth; k++) { if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { goto done; } } omrobjectptr_t obj; char *objName = NULL; rt = createObject(&obj, &objName, namePrefixStr, objType, depth, nthInRow, objSize); OMRGCTEST_CHECK_RT(rt); bytesLeft -= objSize; nthInRow += 1; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k); #endif slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } } parentEntry->numOfRef += breadth; } numOfParents = nthInRow; depth += 1; } done: return rt; }
int32_t GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 1; int32_t numOfParents = 0; /* Create objects and store them in the root table or the slot object based on objType. */ if ((ROOT == objType) || (GARBAGE_ROOT == objType)) { for (int32_t i = 0; i < breadthElem->value; i++) { uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); ObjectEntry *objectEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated); if (NULL == objectEntry) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = objectEntry->name; rEntry.rootPtr = objectEntry->objPtr; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* insert garbage per node */ if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); for (int32_t i = 0; i < breadthElem->value; i++) { uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); ObjectEntry *childEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated); if (NULL == childEntry) { goto done; } ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } else { goto done; } /* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } numOfParents = breadthElem->value; breadthElem = breadthElem->linkNext; for (int32_t i = 1; i < depth; i++) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j); for (int32_t k = 0; k < breadthElem->value; k++) { uintptr_t sizeCalculated = sizeof(omrobjectptr_t) + numOfFieldsElem->value * sizeof(fomrobject_t); ObjectEntry *childEntry = createObject(namePrefixStr, objType, i, nthInRow, sizeCalculated); if (NULL == childEntry) { goto done; } ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; nthInRow += 1; /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } numOfParents = nthInRow; breadthElem = breadthElem->linkNext; } rt = 0; done: return rt; }
int32_t GCConfigTest::createFixedSizeTree(ObjectEntry **rootEntryIndirectPtr, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); *rootEntryIndirectPtr = NULL; int32_t rt = 0; uintptr_t bytesLeft = totalSize; if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { return rt; } } bytesLeft -= objSize; rt = 1; int32_t depth = 1; int32_t numOfParents = 1; /* allocate the root object and add it to the object table */ *rootEntryIndirectPtr = createObject(namePrefixStr, objType, 0, 0, objSize); if (NULL == *rootEntryIndirectPtr) { goto done; } /* add it to the root table */ RootEntry rootEntry; rootEntry.name = (*rootEntryIndirectPtr)->name; rootEntry.rootPtr = (*rootEntryIndirectPtr)->objPtr; if (NULL == hashTableAdd(exampleVM->rootTable, &rootEntry)) { omrtty_printf("%s:%d Failed to add new root entry %s to root table!\n", __FILE__, __LINE__, rootEntry.name); goto done; } /* create the rest of the tree */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } while (bytesLeft > 0) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j); ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } for (int32_t k = 0; k < breadth; k++) { if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { rt = 0; goto done; } } ObjectEntry *childEntry = createObject(namePrefixStr, objType, depth, nthInRow, objSize); if (NULL == childEntry) { goto done; } parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } bytesLeft -= objSize; nthInRow += 1; } parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } } numOfParents = nthInRow; depth += 1; } *rootEntryIndirectPtr = find(rootEntry.name); if (NULL == *rootEntryIndirectPtr) { omrtty_printf("%s:%d Could not find root of fixed-size tree %s in object table.\n", __FILE__, __LINE__, rootEntry.name); goto done; } rt = 0; done: return rt; }