/*-------------------------------------------------------------------------
 * Vulkan CTS Framework
 * --------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Memory allocation callback utilities.
 *//*--------------------------------------------------------------------*/

#include "vkAllocationCallbackUtil.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuTestLog.hpp"
#include "deSTLUtil.hpp"
#include "deMemory.h"

#include <map>

namespace vk
{

// System default allocator

static VKAPI_ATTR void* VKAPI_CALL systemAllocate (void*, size_t size, size_t alignment, VkSystemAllocationScope)
{
	if (size > 0)
		return deAlignedMalloc(size, (deUint32)alignment);
	else
		return DE_NULL;
}

static VKAPI_ATTR void VKAPI_CALL systemFree (void*, void* pMem)
{
	deAlignedFree(pMem);
}

static VKAPI_ATTR void* VKAPI_CALL systemReallocate (void*, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope)
{
	return deAlignedRealloc(pOriginal, size, alignment);
}

static VKAPI_ATTR void VKAPI_CALL systemInternalAllocationNotification (void*, size_t, VkInternalAllocationType, VkSystemAllocationScope)
{
}

static VKAPI_ATTR void VKAPI_CALL systemInternalFreeNotification (void*, size_t, VkInternalAllocationType, VkSystemAllocationScope)
{
}

static const VkAllocationCallbacks s_systemAllocator =
{
	DE_NULL,		// pUserData
	systemAllocate,
	systemReallocate,
	systemFree,
	systemInternalAllocationNotification,
	systemInternalFreeNotification,
};

const VkAllocationCallbacks* getSystemAllocator (void)
{
	return &s_systemAllocator;
}

// AllocationCallbacks

static VKAPI_ATTR void* VKAPI_CALL allocationCallback (void* pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	return reinterpret_cast<AllocationCallbacks*>(pUserData)->allocate(size, alignment, allocationScope);
}

static VKAPI_ATTR void* VKAPI_CALL reallocationCallback (void* pUserData, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	return reinterpret_cast<AllocationCallbacks*>(pUserData)->reallocate(pOriginal, size, alignment, allocationScope);
}

static VKAPI_ATTR void VKAPI_CALL freeCallback (void* pUserData, void* pMem)
{
	reinterpret_cast<AllocationCallbacks*>(pUserData)->free(pMem);
}

static VKAPI_ATTR void VKAPI_CALL internalAllocationNotificationCallback (void* pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	reinterpret_cast<AllocationCallbacks*>(pUserData)->notifyInternalAllocation(size, allocationType, allocationScope);
}

static VKAPI_ATTR void VKAPI_CALL internalFreeNotificationCallback (void* pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	reinterpret_cast<AllocationCallbacks*>(pUserData)->notifyInternalFree(size, allocationType, allocationScope);
}

static VkAllocationCallbacks makeCallbacks (AllocationCallbacks* object)
{
	const VkAllocationCallbacks callbacks =
	{
		reinterpret_cast<void*>(object),
		allocationCallback,
		reallocationCallback,
		freeCallback,
		internalAllocationNotificationCallback,
		internalFreeNotificationCallback
	};
	return callbacks;
}

AllocationCallbacks::AllocationCallbacks (void)
	: m_callbacks(makeCallbacks(this))
{
}

AllocationCallbacks::~AllocationCallbacks (void)
{
}

// AllocationCallbackRecord

AllocationCallbackRecord AllocationCallbackRecord::allocation (size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr)
{
	AllocationCallbackRecord record;

	record.type							= TYPE_ALLOCATION;
	record.data.allocation.size			= size;
	record.data.allocation.alignment	= alignment;
	record.data.allocation.scope		= scope;
	record.data.allocation.returnedPtr	= returnedPtr;

	return record;
}

AllocationCallbackRecord AllocationCallbackRecord::reallocation (void* original, size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr)
{
	AllocationCallbackRecord record;

	record.type								= TYPE_REALLOCATION;
	record.data.reallocation.original		= original;
	record.data.reallocation.size			= size;
	record.data.reallocation.alignment		= alignment;
	record.data.reallocation.scope			= scope;
	record.data.reallocation.returnedPtr	= returnedPtr;

	return record;
}

AllocationCallbackRecord AllocationCallbackRecord::free (void* mem)
{
	AllocationCallbackRecord record;

	record.type				= TYPE_FREE;
	record.data.free.mem	= mem;

	return record;
}

AllocationCallbackRecord AllocationCallbackRecord::internalAllocation (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope)
{
	AllocationCallbackRecord record;

	record.type								= TYPE_INTERNAL_ALLOCATION;
	record.data.internalAllocation.size		= size;
	record.data.internalAllocation.type		= type;
	record.data.internalAllocation.scope	= scope;

	return record;
}

AllocationCallbackRecord AllocationCallbackRecord::internalFree (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope)
{
	AllocationCallbackRecord record;

	record.type								= TYPE_INTERNAL_FREE;
	record.data.internalAllocation.size		= size;
	record.data.internalAllocation.type		= type;
	record.data.internalAllocation.scope	= scope;

	return record;
}

// ChainedAllocator

ChainedAllocator::ChainedAllocator (const VkAllocationCallbacks* nextAllocator)
	: m_nextAllocator(nextAllocator)
{
}

ChainedAllocator::~ChainedAllocator (void)
{
}

void* ChainedAllocator::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	return m_nextAllocator->pfnAllocation(m_nextAllocator->pUserData, size, alignment, allocationScope);
}

void* ChainedAllocator::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	return m_nextAllocator->pfnReallocation(m_nextAllocator->pUserData, original, size, alignment, allocationScope);
}

void ChainedAllocator::free (void* mem)
{
	m_nextAllocator->pfnFree(m_nextAllocator->pUserData, mem);
}

void ChainedAllocator::notifyInternalAllocation (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	m_nextAllocator->pfnInternalAllocation(m_nextAllocator->pUserData, size, allocationType, allocationScope);
}

void ChainedAllocator::notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	m_nextAllocator->pfnInternalFree(m_nextAllocator->pUserData, size, allocationType, allocationScope);
}

// AllocationCallbackRecorder

AllocationCallbackRecorder::AllocationCallbackRecorder (const VkAllocationCallbacks* allocator, deUint32 callCountHint)
	: ChainedAllocator	(allocator)
	, m_records			(callCountHint)
{
}

AllocationCallbackRecorder::~AllocationCallbackRecorder (void)
{
}

void* AllocationCallbackRecorder::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	void* const	ptr	= ChainedAllocator::allocate(size, alignment, allocationScope);

	m_records.append(AllocationCallbackRecord::allocation(size, alignment, allocationScope, ptr));

	return ptr;
}

void* AllocationCallbackRecorder::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	void* const	ptr	= ChainedAllocator::reallocate(original, size, alignment, allocationScope);

	m_records.append(AllocationCallbackRecord::reallocation(original, size, alignment, allocationScope, ptr));

	return ptr;
}

void AllocationCallbackRecorder::free (void* mem)
{
	ChainedAllocator::free(mem);

	m_records.append(AllocationCallbackRecord::free(mem));
}

void AllocationCallbackRecorder::notifyInternalAllocation (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	ChainedAllocator::notifyInternalAllocation(size, allocationType, allocationScope);

	m_records.append(AllocationCallbackRecord::internalAllocation(size, allocationType, allocationScope));
}

void AllocationCallbackRecorder::notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
	ChainedAllocator::notifyInternalFree(size, allocationType, allocationScope);

	m_records.append(AllocationCallbackRecord::internalFree(size, allocationType, allocationScope));
}

// DeterministicFailAllocator

DeterministicFailAllocator::DeterministicFailAllocator (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs, Mode initialMode)
	: ChainedAllocator	(allocator)
	, m_numPassingAllocs(numPassingAllocs)
	, m_mode			(initialMode)
	, m_allocationNdx	(0)
{
}

DeterministicFailAllocator::~DeterministicFailAllocator (void)
{
}

void DeterministicFailAllocator::setMode (Mode mode)
{
	m_mode = mode;
}

void* DeterministicFailAllocator::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	if ((m_mode == MODE_DO_NOT_COUNT) ||
		(deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs))
		return ChainedAllocator::allocate(size, alignment, allocationScope);
	else
		return DE_NULL;
}

void* DeterministicFailAllocator::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	if ((m_mode == MODE_DO_NOT_COUNT) ||
		(deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs))
		return ChainedAllocator::reallocate(original, size, alignment, allocationScope);
	else
		return DE_NULL;
}

// Utils

AllocationCallbackValidationResults::AllocationCallbackValidationResults (void)
{
	deMemset(internalAllocationTotal, 0, sizeof(internalAllocationTotal));
}

void AllocationCallbackValidationResults::clear (void)
{
	liveAllocations.clear();
	violations.clear();
	deMemset(internalAllocationTotal, 0, sizeof(internalAllocationTotal));
}

namespace
{

struct AllocationSlot
{
	AllocationCallbackRecord	record;
	bool						isLive;

	AllocationSlot (void)
		: isLive	(false)
	{}

	AllocationSlot (const AllocationCallbackRecord& record_, bool isLive_)
		: record	(record_)
		, isLive	(isLive_)
	{}
};

size_t getAlignment (const AllocationCallbackRecord& record)
{
	if (record.type == AllocationCallbackRecord::TYPE_ALLOCATION)
		return record.data.allocation.alignment;
	else if (record.type == AllocationCallbackRecord::TYPE_REALLOCATION)
		return record.data.reallocation.alignment;
	else
	{
		DE_ASSERT(false);
		return 0;
	}
}

} // anonymous

void validateAllocationCallbacks (const AllocationCallbackRecorder& recorder, AllocationCallbackValidationResults* results)
{
	std::vector<AllocationSlot>		allocations;
	std::map<void*, size_t>			ptrToSlotIndex;

	DE_ASSERT(results->liveAllocations.empty() && results->violations.empty());

	for (AllocationCallbackRecorder::RecordIterator callbackIter = recorder.getRecordsBegin();
		 callbackIter != recorder.getRecordsEnd();
		 ++callbackIter)
	{
		const AllocationCallbackRecord&		record	= *callbackIter;

		// Validate scope
		{
			const VkSystemAllocationScope* const	scopePtr	= record.type == AllocationCallbackRecord::TYPE_ALLOCATION			? &record.data.allocation.scope
																: record.type == AllocationCallbackRecord::TYPE_REALLOCATION		? &record.data.reallocation.scope
																: record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION	? &record.data.internalAllocation.scope
																: record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE		? &record.data.internalAllocation.scope
																: DE_NULL;

			if (scopePtr && !de::inBounds(*scopePtr, (VkSystemAllocationScope)0, VK_SYSTEM_ALLOCATION_SCOPE_LAST))
				results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_ALLOCATION_SCOPE));
		}

		// Validate alignment
		if (record.type == AllocationCallbackRecord::TYPE_ALLOCATION ||
			record.type == AllocationCallbackRecord::TYPE_REALLOCATION)
		{
			if (!deIsPowerOfTwoSize(getAlignment(record)))
				results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_ALIGNMENT));
		}

		// Validate actual allocation behavior
		switch (record.type)
		{
			case AllocationCallbackRecord::TYPE_ALLOCATION:
			{
				if (record.data.allocation.returnedPtr)
				{ 
					if (!de::contains(ptrToSlotIndex, record.data.allocation.returnedPtr))
					{
						ptrToSlotIndex[record.data.allocation.returnedPtr] = allocations.size();
						allocations.push_back(AllocationSlot(record, true));
					}
					else
					{
						const size_t		slotNdx		= ptrToSlotIndex[record.data.allocation.returnedPtr];
						if (!allocations[slotNdx].isLive) 
						{
							allocations[slotNdx].isLive = true;
							allocations[slotNdx].record = record;
						}
						else
						{
							// we should not have multiple live allocations with the same pointer
							DE_ASSERT(false);
						}
					}
				}

				break;
			}

			case AllocationCallbackRecord::TYPE_REALLOCATION:
			{
				if (de::contains(ptrToSlotIndex, record.data.reallocation.original))
				{
					const size_t		origSlotNdx		= ptrToSlotIndex[record.data.reallocation.original];
					AllocationSlot&		origSlot		= allocations[origSlotNdx];

					DE_ASSERT(record.data.reallocation.original != DE_NULL);

					if (record.data.reallocation.size > 0)
					{
						if (getAlignment(origSlot.record) != record.data.reallocation.alignment)
							results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_DIFFERENT_ALIGNMENT));

						if (record.data.reallocation.original == record.data.reallocation.returnedPtr)
						{
							if (!origSlot.isLive)
							{
								results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_FREED_PTR));
								origSlot.isLive	= true; // Mark live to suppress further errors
							}

							// Just update slot record
							allocations[origSlotNdx].record = record;
						}
						else
						{
							if (record.data.reallocation.returnedPtr)
							{
								allocations[origSlotNdx].isLive = false;
								if (!de::contains(ptrToSlotIndex, record.data.reallocation.returnedPtr))
								{
									ptrToSlotIndex[record.data.reallocation.returnedPtr] = allocations.size();
									allocations.push_back(AllocationSlot(record, true));
								}
								else
								{
									const size_t slotNdx = ptrToSlotIndex[record.data.reallocation.returnedPtr];
									if (!allocations[slotNdx].isLive)
									{
										allocations[slotNdx].isLive = true;
										allocations[slotNdx].record = record;
									}
									else
									{
										// we should not have multiple live allocations with the same pointer
										DE_ASSERT(false);
									}
								}
							}
							// else original ptr remains valid and live
						}
					}
					else
					{
						DE_ASSERT(!record.data.reallocation.returnedPtr);

						origSlot.isLive = false;
					}
				}
				else
				{
					if (record.data.reallocation.original)
						results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_NOT_ALLOCATED_PTR));

					if (record.data.reallocation.returnedPtr)
					{
						DE_ASSERT(!de::contains(ptrToSlotIndex, record.data.reallocation.returnedPtr));
						ptrToSlotIndex[record.data.reallocation.returnedPtr] = allocations.size();
						allocations.push_back(AllocationSlot(record, true));
					}
				}

				break;
			}

			case AllocationCallbackRecord::TYPE_FREE:
			{
				if (record.data.free.mem != DE_NULL) // Freeing null pointer is valid and ignored
				{
					if (de::contains(ptrToSlotIndex, record.data.free.mem))
					{
						const size_t	slotNdx		= ptrToSlotIndex[record.data.free.mem];

						if (allocations[slotNdx].isLive)
							allocations[slotNdx].isLive = false;
						else
							results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_DOUBLE_FREE));
					}
					else
						results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_FREE_NOT_ALLOCATED_PTR));
				}

				break;
			}

			case AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION:
			case AllocationCallbackRecord::TYPE_INTERNAL_FREE:
			{
				if (de::inBounds(record.data.internalAllocation.type, (VkInternalAllocationType)0, VK_INTERNAL_ALLOCATION_TYPE_LAST))
				{
					size_t* const		totalAllocSizePtr	= &results->internalAllocationTotal[record.data.internalAllocation.type][record.data.internalAllocation.scope];
					const size_t		size				= record.data.internalAllocation.size;

					if (record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE)
					{
						if (*totalAllocSizePtr < size)
						{
							results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL));
							*totalAllocSizePtr = 0; // Reset to 0 to suppress compound errors
						}
						else
							*totalAllocSizePtr -= size;
					}
					else
						*totalAllocSizePtr += size;
				}
				else
					results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_INTERNAL_ALLOCATION_TYPE));

				break;
			}

			default:
				DE_ASSERT(false);
		}
	}

	DE_ASSERT(!de::contains(ptrToSlotIndex, DE_NULL));

	// Collect live allocations
	for (std::vector<AllocationSlot>::const_iterator slotIter = allocations.begin();
		 slotIter != allocations.end();
		 ++slotIter)
	{
		if (slotIter->isLive)
			results->liveAllocations.push_back(slotIter->record);
	}
}

bool checkAndLog (tcu::TestLog& log, const AllocationCallbackValidationResults& results, deUint32 allowedLiveAllocScopeBits)
{
	using tcu::TestLog;

	size_t	numLeaks	= 0;

	if (!results.violations.empty())
	{
		for (size_t violationNdx = 0; violationNdx < results.violations.size(); ++violationNdx)
		{
			log << TestLog::Message << "VIOLATION " << (violationNdx+1)
													<< ": " << results.violations[violationNdx]
													<< " (" << results.violations[violationNdx].record << ")"
				<< TestLog::EndMessage;
		}

		log << TestLog::Message << "ERROR: Found " << results.violations.size() << " invalid allocation callbacks!" << TestLog::EndMessage;
	}

	// Verify live allocations
	for (size_t liveNdx = 0; liveNdx < results.liveAllocations.size(); ++liveNdx)
	{
		const AllocationCallbackRecord&		record	= results.liveAllocations[liveNdx];
		const VkSystemAllocationScope		scope	= record.type == AllocationCallbackRecord::TYPE_ALLOCATION		? record.data.allocation.scope
													: record.type == AllocationCallbackRecord::TYPE_REALLOCATION	? record.data.reallocation.scope
													: VK_SYSTEM_ALLOCATION_SCOPE_LAST;

		DE_ASSERT(de::inBounds(scope, (VkSystemAllocationScope)0, VK_SYSTEM_ALLOCATION_SCOPE_LAST));

		if ((allowedLiveAllocScopeBits & (1u << scope)) == 0)
		{
			log << TestLog::Message << "LEAK " << (numLeaks+1) << ": " << record << TestLog::EndMessage;
			numLeaks += 1;
		}
	}

	// Verify internal allocations
	for (int internalAllocTypeNdx = 0; internalAllocTypeNdx < VK_INTERNAL_ALLOCATION_TYPE_LAST; ++internalAllocTypeNdx)
	{
		for (int scopeNdx = 0; scopeNdx < VK_SYSTEM_ALLOCATION_SCOPE_LAST; ++scopeNdx)
		{
			const VkInternalAllocationType	type			= (VkInternalAllocationType)internalAllocTypeNdx;
			const VkSystemAllocationScope	scope			= (VkSystemAllocationScope)scopeNdx;
			const size_t					totalAllocated	= results.internalAllocationTotal[type][scope];

			if ((allowedLiveAllocScopeBits & (1u << scopeNdx)) == 0 &&
				totalAllocated > 0)
			{
				log << TestLog::Message << "LEAK " << (numLeaks+1) << ": " << totalAllocated
										<< " bytes of (" << type << ", " << scope << ") internal memory is still allocated"
					<< TestLog::EndMessage;
				numLeaks += 1;
			}
		}
	}

	if (numLeaks > 0)
		log << TestLog::Message << "ERROR: Found " << numLeaks << " memory leaks!" << TestLog::EndMessage;

	return results.violations.empty() && numLeaks == 0;
}

bool validateAndLog (tcu::TestLog& log, const AllocationCallbackRecorder& recorder, deUint32 allowedLiveAllocScopeBits)
{
	AllocationCallbackValidationResults	validationResults;

	validateAllocationCallbacks(recorder, &validationResults);

	return checkAndLog(log, validationResults, allowedLiveAllocScopeBits);
}

size_t getLiveSystemAllocationTotal (const AllocationCallbackValidationResults& validationResults)
{
	size_t	allocationTotal	= 0;

	DE_ASSERT(validationResults.violations.empty());

	for (std::vector<AllocationCallbackRecord>::const_iterator alloc = validationResults.liveAllocations.begin();
		 alloc != validationResults.liveAllocations.end();
		 ++alloc)
	{
		DE_ASSERT(alloc->type == AllocationCallbackRecord::TYPE_ALLOCATION ||
				  alloc->type == AllocationCallbackRecord::TYPE_REALLOCATION);

		const size_t	size		= (alloc->type == AllocationCallbackRecord::TYPE_ALLOCATION ? alloc->data.allocation.size : alloc->data.reallocation.size);
		const size_t	alignment	= (alloc->type == AllocationCallbackRecord::TYPE_ALLOCATION ? alloc->data.allocation.alignment : alloc->data.reallocation.alignment);

		allocationTotal += size + alignment - (alignment > 0 ? 1 : 0);
	}

	for (int internalAllocationTypeNdx = 0; internalAllocationTypeNdx < VK_INTERNAL_ALLOCATION_TYPE_LAST; ++internalAllocationTypeNdx)
	{
		for (int internalAllocationScopeNdx = 0; internalAllocationScopeNdx < VK_SYSTEM_ALLOCATION_SCOPE_LAST; ++internalAllocationScopeNdx)
			allocationTotal += validationResults.internalAllocationTotal[internalAllocationTypeNdx][internalAllocationScopeNdx];
	}

	return allocationTotal;
}

std::ostream& operator<< (std::ostream& str, const AllocationCallbackRecord& record)
{
	switch (record.type)
	{
		case AllocationCallbackRecord::TYPE_ALLOCATION:
			str << "ALLOCATION: size=" << record.data.allocation.size
				<< ", alignment=" << record.data.allocation.alignment
				<< ", scope=" << record.data.allocation.scope
				<< ", returnedPtr=" << tcu::toHex(record.data.allocation.returnedPtr);
			break;

		case AllocationCallbackRecord::TYPE_REALLOCATION:
			str << "REALLOCATION: original=" << tcu::toHex(record.data.reallocation.original)
				<< ", size=" << record.data.reallocation.size
				<< ", alignment=" << record.data.reallocation.alignment
				<< ", scope=" << record.data.reallocation.scope
				<< ", returnedPtr=" << tcu::toHex(record.data.reallocation.returnedPtr);
			break;

		case AllocationCallbackRecord::TYPE_FREE:
			str << "FREE: mem=" << tcu::toHex(record.data.free.mem);
			break;

		case AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION:
		case AllocationCallbackRecord::TYPE_INTERNAL_FREE:
			str << "INTERNAL_" << (record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION ? "ALLOCATION" : "FREE")
				<< ": size=" << record.data.internalAllocation.size
				<< ", type=" << record.data.internalAllocation.type
				<< ", scope=" << record.data.internalAllocation.scope;
			break;

		default:
			DE_ASSERT(false);
	}

	return str;
}

std::ostream& operator<< (std::ostream& str, const AllocationCallbackViolation& violation)
{
	switch (violation.reason)
	{
		case AllocationCallbackViolation::REASON_DOUBLE_FREE:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_FREE);
			str << "Double free of " << tcu::toHex(violation.record.data.free.mem);
			break;
		}

		case AllocationCallbackViolation::REASON_FREE_NOT_ALLOCATED_PTR:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_FREE);
			str << "Attempt to free " << tcu::toHex(violation.record.data.free.mem) << " which has not been allocated";
			break;
		}

		case AllocationCallbackViolation::REASON_REALLOC_NOT_ALLOCATED_PTR:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_REALLOCATION);
			str << "Attempt to reallocate " << tcu::toHex(violation.record.data.reallocation.original) << " which has not been allocated";
			break;
		}

		case AllocationCallbackViolation::REASON_REALLOC_FREED_PTR:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_REALLOCATION);
			str << "Attempt to reallocate " << tcu::toHex(violation.record.data.reallocation.original) << " which has been freed";
			break;
		}

		case AllocationCallbackViolation::REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE);
			str << "Internal allocation total for (" << violation.record.data.internalAllocation.type << ", " << violation.record.data.internalAllocation.scope << ") is negative";
			break;
		}

		case AllocationCallbackViolation::REASON_INVALID_INTERNAL_ALLOCATION_TYPE:
		{
			DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION ||
					  violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE);
			str << "Invalid internal allocation type " << tcu::toHex(violation.record.data.internalAllocation.type);
			break;
		}

		case AllocationCallbackViolation::REASON_INVALID_ALLOCATION_SCOPE:
		{
			str << "Invalid allocation scope";
			break;
		}

		case AllocationCallbackViolation::REASON_INVALID_ALIGNMENT:
		{
			str << "Invalid alignment";
			break;
		}

		case AllocationCallbackViolation::REASON_REALLOC_DIFFERENT_ALIGNMENT:
		{
			str << "Reallocation with different alignment";
			break;
		}

		default:
			DE_ASSERT(false);
	}

	return str;
}

} // vk
