void* NorlsAllocator::_AllocNonZero(size_t& sz)
{
    AssertIfFalse((size_t)nextFree % sizeof(void*) == 0);
    AssertIfFalse((size_t)limitFree % sizeof(void*) == 0);

    void * p = nextFree;
    if (sz == 0 && p == NULL)
    {
        sz = 1;
    }

    size_t roundSize = VBMath::RoundUpAllocSize(sz);
    size_t available = limitFree - nextFree;

    if ( available < roundSize )
    {
        AllocNewPage(sz);
    }

    p = nextFree;
    nextFree += roundSize; // this shouldn't overflow because we got the memory for the request (we would have thrown in AllocNewPage() otherwise)

    MakeCurrentPageWriteableInternal();

    AssertIfFalse((size_t)nextFree % sizeof(void*) == 0);
    AssertIfFalse((size_t)limitFree % sizeof(void*) == 0);
    AssertIfFalse((size_t)p % sizeof(void*) == 0);

#if NRLSTRACK
    m_nTotalAllocated += roundSize;
    m_dwAllocThreadId  = 0;
#endif NRLSTRACK

    sz = roundSize;
#if NRLSTRACK
    VSASSERT(m_dwAllocThreadId == 0," NorlsAlloc: only 1 thread allowed at a time");
    m_dwAllocThreadId = GetCurrentThreadId();
    m_nSeqNo+=1;


#if NRLSTRACK_GETSTACKS
    //
    NrlsHeapData  *pdata =
        (NrlsHeapData *) VsDebugAllocInternal(TrackingHeapToUse(),
                HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
                (sizeof (NrlsHeapData )), __FILE__, __LINE__, INSTANCE_GLOBAL, NULL);

    pdata->m_ptrNextBlock = m_pLastBlock; // linked list of allocations: point to prior one
    pdata->m_size = sz;  // record the size
    pdata->m_data = p;  // record the actual allocation
    m_pLastBlock = pdata; // track the most recent one
#endif NRLSTRACK_GETSTACKS
#endif NRLSTRACK
    return p;
}
Esempio n. 2
0
/*
 * Algorithm:
 *   - Find bucket
 *   - Check bucket pages - if it has enough free space, allocate that chunk
 *   - Check pages in bigger buckets - if that has enough space, split that page and allocate from that chunk
 *   - Allocate new page
 */
Allocation* Heap::Alloc(size_t bytes, ushort pdataCount, ushort xdataSize, bool canAllocInPreReservedHeapPageSegment, bool isAnyJittedCode, _Inout_ bool* isAllJITCodeInPreReservedRegion)
{
    Assert(bytes > 0);
    Assert((allocXdata || pdataCount == 0) && (!allocXdata || pdataCount > 0));
    Assert(pdataCount > 0 || (pdataCount == 0 && xdataSize == 0));

    // Round up to power of two to allocate, and figure out which bucket to allocate in
    size_t bytesToAllocate = PowerOf2Policy::GetSize(bytes);
    BucketId bucket = (BucketId) GetBucketForSize(bytesToAllocate);
    Allocation* allocation;

    if (bucket == BucketId::LargeObjectList)
    {
        return AllocLargeObject(bytes, pdataCount, xdataSize, canAllocInPreReservedHeapPageSegment, isAnyJittedCode, isAllJITCodeInPreReservedRegion);
    }

    VerboseHeapTrace(L"Bucket is %d\n", bucket);
    VerboseHeapTrace(L"Requested: %d bytes. Allocated: %d bytes\n", bytes, bytesToAllocate);

    Page* page = nullptr;
    if(!this->buckets[bucket].Empty())
    {
        page = &this->buckets[bucket].Head();
    }
    else
    {
        page = FindPageToSplit(bucket, canAllocInPreReservedHeapPageSegment);
    }

    if(page == nullptr)
    {
        page = AllocNewPage(bucket, canAllocInPreReservedHeapPageSegment, isAnyJittedCode, isAllJITCodeInPreReservedRegion);
    }

    // Out of memory
    if (page == nullptr)
    {
        return nullptr;
    }

    allocation = AllocInPage(page, bytesToAllocate, pdataCount, xdataSize);
    return allocation;
}
Esempio n. 3
0
int UpdateObjDataByRange(ObjStoreContext* pContext, uint64_t objid, uint64_t startpos, const uint8_t* pData, uint64_t dataLen)
{
	ObjMeta theMeta;
	//theMeta.objid = objid;
	//theMeta.datalen = dataLen;

	int result = -1;
	if (ReadObjMeta(pContext, objid, &theMeta) != 0)
	{
		return -1;
	}

	if (startpos > theMeta.datalen)
	{
		printf("start pos too big!\n");
		return -1;
	}

	int startpage = startpos / pContext->pagesize;
	int endpage = (startpos + dataLen) / pContext->pagesize;

	int i = 0;
	int readlen = 0;
	uint64_t datalen = theMeta.datalen;
	uint8_t utf8path[257] = { 0 };
	uint8_t* pWritePos = pData;
	uint8_t* pageBuffer = malloc(pContext->pagesize);
	uint8_t* willWritePageBuffer = pageBuffer;
	int willWriteLen = pContext->pagesize;
	int pagepos = startpos % pContext->pagesize;
	for (i = startpage; i <= endpage; ++i)
	{
		if (i == startpage)
		{
			//处理头部
			if (pagepos != 0)
			{
				//不是整页
				GetPagePath(pContext, theMeta.dataPage.pPageArray[i], utf8path);
				FILE* pfPage = fopen(utf8path, "rb");
				if (pfPage)
				{
					uint64_t pagesize = pContext->pagesize;
					ReadFileContentWithPos(pfPage, pageBuffer, &pagesize,sizeof(uint64_t));
					fclose(pfPage);
				}
				else
				{
					printf("read page error\n");
					free(pageBuffer);
					return -1;
				}
			}

			int copylen = pagepos + dataLen > pContext->pagesize ? pContext->pagesize - pagepos : dataLen;
			memcpy(pageBuffer + pagepos, pData, copylen);
			willWritePageBuffer = pageBuffer;
		}
		else if (i == endpage)
		{
			//处理尾部
			willWriteLen = dataLen - (pContext->pagesize - pagepos);
			if (willWriteLen > 0)
			{
				willWriteLen = willWriteLen % pContext->pagesize;
			}
			else
			{
				willWriteLen = 0;
			}

			if (willWriteLen != pContext->pagesize)
			{
				//不是整页
				GetPagePath(pContext, theMeta.dataPage.pPageArray[i], utf8path);
				FILE* pfPage = fopen(utf8path, "rb");
				if (pfPage)
				{
					uint64_t pagesize = pContext->pagesize;
					ReadFileContentWithPos(pfPage, pageBuffer, &pagesize,sizeof(uint64_t));
					fclose(pfPage);
				}
				else
				{
					printf("read page error\n");
					free(pageBuffer);
					return -1;
				}

				memcpy(pageBuffer, pData + dataLen - willWriteLen, willWriteLen);
				willWritePageBuffer = pageBuffer;
			}
			else
			{
				willWritePageBuffer = pData + (pContext->pagesize - pagepos) + (i - startpage - 1) * pContext->pagesize;
				willWriteLen = pContext->pagesize;
			}
		}
		else
		{
			willWritePageBuffer = pData + (pContext->pagesize - pagepos) + (i - startpage - 1) * pContext->pagesize;
			willWriteLen = pContext->pagesize;
		}

		//把准备好的pagebuffer写入新的页面文件
		uint64_t newPageIndex = 0;
		AllocNewPage(pContext, utf8path, &newPageIndex);
		FILE* pfPage = fopen(utf8path, "wb");
		if (pfPage)
		{
			fwrite(&objid, sizeof(uint64_t), 1, pfPage);
			WriteFileContent(pfPage, willWritePageBuffer, willWriteLen);
			theMeta.dataPage.pPageArray[i] = newPageIndex;
			fclose(pfPage);
		}
		else
		{
			printf("write page error\n");
			free(pageBuffer);
			return -1;
		}

	}
	free(pageBuffer);


	uint8_t utf8Path[257] = { 0 };
	uint8_t utf8MetaPath[257] = { 0 };
	GetNewObjPageListDataPath(pContext, utf8Path);
	FILE* pfPageList = fopen(utf8Path, "wb");
	if (pfPageList)
	{
		int bufferSize = GetSizeOfPageList(&(theMeta.dataPage));
		uint8_t *pBuffer = (uint8_t*)malloc(bufferSize);
		WritePageList(pContext, pBuffer, &(theMeta.dataPage));
		WriteFileContent(pfPageList, pBuffer, bufferSize);
		fclose(pfPageList);
		free(pBuffer);

		GetObjMetaPath(pContext, objid, utf8MetaPath);
		FILE* pfMeta = fopen(utf8MetaPath, "wb");
		if (pfMeta) {
			bufferSize = GetSizeOfObjMeta(pContext, &theMeta, utf8Path);
			pBuffer = (uint8_t*)malloc(bufferSize);
			WriteObjMeta(pContext, pBuffer, &theMeta, utf8Path);
			WriteFileContent(pfMeta, pBuffer, bufferSize);
			fclose(pfMeta);
			free(pBuffer);
			free(theMeta.dataPage.pPageArray);
			return 0;
		}
		else
		{
			printf("write meta error\n");
			free(theMeta.dataPage.pPageArray);
			return -1;
		}
	}
	else
	{
		printf("write pagelist error\n");
		free(theMeta.dataPage.pPageArray);
		return -1;
	}

	return -1;
}
Esempio n. 4
0
int UpdateObjData(ObjStoreContext* pContext, uint64_t objid, const uint8_t* pData, uint64_t dataLen)
{
	ObjMeta theMeta;
	theMeta.objid = objid;
	theMeta.datalen = dataLen;

	int pagelen = dataLen / pContext->pagesize;
	if (dataLen % pContext->pagesize != 0)
	{
		pagelen = pagelen + 1;
	}

	theMeta.dataPage.listSize = pagelen;
	theMeta.dataPage.pPageArray = (uint64_t*)malloc(sizeof(uint64_t) * pagelen);

	int i = 0;
	uint64_t writePos = 0;
	for (i = 0; i < pagelen; ++i)
	{
		uint8_t pagepath[257] = { 0 };
		uint64_t pageIndex = 0;
		AllocNewPage(pContext, pagepath, &pageIndex);
		FILE* pfPage = fopen(pagepath, "wb");
		if (pfPage)
		{
			fwrite(&objid, sizeof(uint64_t), 1, pfPage);
			WriteFileContent(pfPage, pData + writePos, dataLen - writePos > pContext->pagesize ? pContext->pagesize : dataLen - writePos);
			fclose(pfPage);
			writePos += pContext->pagesize;
			theMeta.dataPage.pPageArray[i] = pageIndex;
		}
		else
		{
			free(theMeta.dataPage.pPageArray);
			printf("error\n");
		}
	}

	uint8_t utf8Path[257] = { 0 };
	uint8_t utf8MetaPath[257] = { 0 };
	GetNewObjPageListDataPath(pContext, utf8Path);
	FILE* pfPageList = fopen(utf8Path, "wb");
	if (pfPageList)
	{
		int bufferSize = GetSizeOfPageList(&(theMeta.dataPage));
		uint8_t *pBuffer = (uint8_t*)malloc(bufferSize);
		WritePageList(pContext, pBuffer, &(theMeta.dataPage));
		WriteFileContent(pfPageList, pBuffer, bufferSize);
		fclose(pfPageList);
		free(pBuffer);

		GetObjMetaPath(pContext, objid, utf8MetaPath);
		FILE* pfMeta = fopen(utf8MetaPath, "wb");
		if (pfMeta) 
		{
			//用前面的方法,解决meta可能过大的问题
			bufferSize = GetSizeOfObjMeta(pContext, &theMeta, utf8Path);
			pBuffer = (uint8_t*)malloc(bufferSize);
			WriteObjMeta(pContext, pBuffer, &theMeta, utf8Path);
			WriteFileContent(pfMeta, pBuffer, bufferSize);

			free(pBuffer);
			free(theMeta.dataPage.pPageArray);
			fclose(pfMeta);
			return 0;
		}
		else
		{
			printf("write meta error\n");
			free(theMeta.dataPage.pPageArray);
			return -1;
		}
	}
	else
	{
		printf("write pagelist error\n");
		free(theMeta.dataPage.pPageArray);
		return -1;
	}

	free(theMeta.dataPage.pPageArray);
	return -1;
}