Example #1
0
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;
}