omrobjectptr_t static inline allocHelper(OMR_VMThread * omrVMThread, size_t sizeInBytes, uintptr_t flags, bool collectOnFailure) { MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(omrVMThread->_vm); MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(omrVMThread); uintptr_t vmState = env->pushVMstate(J9VMSTATE_GC_ALLOCATE_OBJECT); #if defined(OMR_GC_THREAD_LOCAL_HEAP) if (!env->_envLanguageInterface->isInlineTLHAllocateEnabled()) { /* For duration of call restore TLH allocate fields; * we will hide real heapAlloc again on exit to fool JIT/Interpreter * into thinking TLH is full if needed */ env->_envLanguageInterface->enableInlineTLHAllocate(); } #endif /* OMR_GC_THREAD_LOCAL_HEAP */ uintptr_t allocatedFlags = 0; uintptr_t sizeAdjusted = extensions->objectModel.adjustSizeInBytes(sizeInBytes); bool threadAtSafePoint = J9_ARE_ALL_BITS_SET(flags, OMR_GC_THREAD_AT_SAFEPOINT); MM_AllocateDescription allocdescription(sizeAdjusted, allocatedFlags, collectOnFailure, threadAtSafePoint); /* OMRTODO: Under what conditions could this assert fail? */ assert(omrVMThread->memorySpace == env->getMemorySpace()); omrobjectptr_t heapBytes = (omrobjectptr_t)env->_objectAllocationInterface->allocateObject(env, &allocdescription, env->getMemorySpace(), collectOnFailure); /* OMRTODO: Should we use zero TLH instead of memset? */ if (NULL != heapBytes) { if (J9_ARE_ALL_BITS_SET(flags, OMR_GC_ALLOCATE_ZERO_MEMORY)) { uintptr_t size = allocdescription.getBytesRequested(); memset(heapBytes, 0, size); } } allocdescription.setAllocationSucceeded(NULL != heapBytes); /* Issue Allocation Failure Report if required */ env->allocationFailureEndReportIfRequired(&allocdescription); if (collectOnFailure) { /* Done allocation - successful or not */ /* OMRTODO: We are releasing exclusive before writing any of the object header, meaning * it may not be walkable in the event of another GC or heap traversal. Is this * the right place to release or should the caller be responsible? */ env->unwindExclusiveVMAccessForGC(); } env->popVMstate(vmState); #if defined(OMR_GC_THREAD_LOCAL_HEAP) if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold) { env->_envLanguageInterface->disableInlineTLHAllocate(); } #endif /* OMR_GC_THREAD_LOCAL_HEAP */ return heapBytes; }