void operator()(int) const { TestBlock blocks1[ITERS], blocks2[ITERS]; barrier.wait(); for (int i=0; i<ITERS; i++) { blocks1[i].sz = rand() % minLargeObjectSize; blocks1[i].ptr = StartupBlock::allocate(blocks1[i].sz); ASSERT(blocks1[i].ptr && StartupBlock::msize(blocks1[i].ptr)>=blocks1[i].sz && 0==(uintptr_t)blocks1[i].ptr % sizeof(void*), NULL); memset(blocks1[i].ptr, i, blocks1[i].sz); } for (int i=0; i<ITERS; i++) { blocks2[i].sz = rand() % minLargeObjectSize; blocks2[i].ptr = StartupBlock::allocate(blocks2[i].sz); ASSERT(blocks2[i].ptr && StartupBlock::msize(blocks2[i].ptr)>=blocks2[i].sz && 0==(uintptr_t)blocks2[i].ptr % sizeof(void*), NULL); memset(blocks2[i].ptr, i, blocks2[i].sz); for (size_t j=0; j<blocks1[i].sz; j++) ASSERT(*((char*)blocks1[i].ptr+j) == i, NULL); Block *block = (Block *)alignDown(blocks1[i].ptr, slabSize); ((StartupBlock *)block)->free(blocks1[i].ptr); } for (int i=ITERS-1; i>=0; i--) { for (size_t j=0; j<blocks2[i].sz; j++) ASSERT(*((char*)blocks2[i].ptr+j) == i, NULL); Block *block = (Block *)alignDown(blocks2[i].ptr, slabSize); ((StartupBlock *)block)->free(blocks2[i].ptr); } }
void allocatePages(struct vma* vmas) { int i=0; struct page* newPage=NULL; int perms; int numPages = ((uint64_t)alignUp((void *)vmas->end) - (uint64_t)alignDown((void *)vmas->start))/PAGE_SIZE; if(vmas->flags_vma & 0x2) perms = BIT_RW | BIT_PRESENT | BIT_USER; else perms = BIT_PRESENT | BIT_USER; for(i = 0; i<numPages; i++) { if(!(*pml4Walk(current_pcb->pml4, (uint64_t)(vmas->start+i*PAGE_SIZE)))) { newPage = page_alloc(); page_insert(current_pcb->pml4,(void *)(vmas->start+i*PAGE_SIZE), newPage, perms); //printf("Inserted new page PA:%x at faulting addr: %x\n", getPA(newPage), vmas->start+i*PAGE_SIZE); //printf("walk: %x\n",*pml4Walk(current_pcb->pml4, vmas->start+i*PAGE_SIZE)); } } }
size_t Chunk::bitmapSize() const { auto nonHeaderSize = alignDown(size() - sizeof(Chunk), kWordSize); auto nonHeaderWords = nonHeaderSize / kWordSize; auto bitmapWords = (nonHeaderWords + WORDSIZE) / (WORDSIZE + 1); ASSERT(bitmapWords * WORDSIZE - (nonHeaderWords - bitmapWords) < WORDSIZE); return bitmapWords * kWordSize; }
unsigned getMaxNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { assert(WavesPerEU != 0); unsigned MaxNumVGPRs = alignDown(getTotalNumVGPRs(STI) / WavesPerEU, getVGPRAllocGranule(STI)); unsigned AddressableNumVGPRs = getAddressableNumVGPRs(STI); return std::min(MaxNumVGPRs, AddressableNumVGPRs); }
unsigned getMaxNumVGPRs(const FeatureBitset &Features, unsigned WavesPerEU) { assert(WavesPerEU != 0); unsigned MaxNumVGPRs = alignDown(getTotalNumVGPRs(Features) / WavesPerEU, getVGPRAllocGranule(Features)); unsigned AddressableNumVGPRs = getAddressableNumVGPRs(Features); return std::min(MaxNumVGPRs, AddressableNumVGPRs); }
unsigned getMinNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { assert(WavesPerEU != 0); if (WavesPerEU >= getMaxWavesPerEU()) return 0; unsigned MinNumVGPRs = alignDown(getTotalNumVGPRs(STI) / (WavesPerEU + 1), getVGPRAllocGranule(STI)) + 1; return std::min(MinNumVGPRs, getAddressableNumVGPRs(STI)); }
unsigned getMinNumVGPRs(const FeatureBitset &Features, unsigned WavesPerEU) { assert(WavesPerEU != 0); if (WavesPerEU >= getMaxWavesPerEU(Features)) return 0; unsigned MinNumVGPRs = alignDown(getTotalNumVGPRs(Features) / (WavesPerEU + 1), getVGPRAllocGranule(Features)) + 1; return std::min(MinNumVGPRs, getAddressableNumVGPRs(Features)); }
void copy_on_write_handler(uint64_t faultAddr) { uint64_t * pte=NULL; struct page* newPage=NULL; struct page* faultPage=NULL;; void * buffer = kmalloc(PAGE_SIZE); pte = pml4Walk(current_pcb->pml4, faultAddr); //printf("In COW HANDLER\n"); if(*pte & BIT_COW) { faultPage = getStrPtrFromPA((void *)(*pte)); if(faultPage->ref_count==2)//Allocate new writeable page and map it { //Important: Copy bytes from faulting page to temp buffer memcpy(buffer, alignDown((void *)faultAddr), PAGE_SIZE); page_remove(current_pcb->pml4, (void *)faultAddr); newPage=page_alloc(); page_insert(current_pcb->pml4, (void *)faultAddr, newPage, BIT_PRESENT | BIT_RW | BIT_USER); //Invalidate tlb?, included in page_remove loadcr3(current_pcb->cr3); //Copy back bytes from temp buffer memcpy(alignDown((void *)faultAddr), buffer, PAGE_SIZE); //printf("Inserted new page %x on COW fault on page ref=2\n", getPA(newPage)); } else { //Make page rightable *pte = (*pte & ~BIT_COW) | BIT_RW; //printf("Made page writeable on COW fault, page ref=1\n"); } } }
void AddressSpace::delRMem(VAddr begVAddr, VAddr endVAddr){ begVAddr=alignDown(begVAddr,getPageSize()); endVAddr=alignUp(endVAddr,getPageSize()); RAddr begRAddr=pageTable[getVPage(begVAddr)]; free((void *)begRAddr); for(VAddr pageNum=getVPage(begVAddr);pageNum!=getVPage(endVAddr);pageNum++){ if(pageTable[pageNum]!=begRAddr+(pageNum*getPageSize()-begVAddr)) fatal("AddressSpace::delRMem region not allocated contiguously"); pageTable[pageNum]=0; } }
unsigned getMinNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU) { assert(WavesPerEU != 0); if (WavesPerEU >= getMaxWavesPerEU()) return 0; unsigned MinNumSGPRs = getTotalNumSGPRs(STI) / (WavesPerEU + 1); if (STI->getFeatureBits().test(FeatureTrapHandler)) MinNumSGPRs -= std::min(MinNumSGPRs, (unsigned)TRAP_NUM_SGPRS); MinNumSGPRs = alignDown(MinNumSGPRs, getSGPRAllocGranule(STI)) + 1; return std::min(MinNumSGPRs, getAddressableNumSGPRs(STI)); }
unsigned getMaxNumSGPRs(const FeatureBitset &Features, unsigned WavesPerEU, bool Addressable) { assert(WavesPerEU != 0); IsaVersion Version = getIsaVersion(Features); unsigned MaxNumSGPRs = alignDown(getTotalNumSGPRs(Features) / WavesPerEU, getSGPRAllocGranule(Features)); unsigned AddressableNumSGPRs = getAddressableNumSGPRs(Features); if (Version.Major >= 8 && !Addressable) AddressableNumSGPRs = 112; return std::min(MaxNumSGPRs, AddressableNumSGPRs); }
void AddressSpace::newRMem(VAddr begVAddr, VAddr endVAddr){ begVAddr=alignDown(begVAddr,getPageSize()); endVAddr=alignUp(endVAddr,getPageSize()); void *realMem; if(posix_memalign(&realMem,getPageSize(),endVAddr-begVAddr)) fatal("AddressSpace::newRMem could not allocate memory\n"); for(size_t pageNum=getVPage(begVAddr);pageNum!=getVPage(endVAddr);pageNum++){ if(pageTable[pageNum]) fatal("AddressSpace::newRMem region overlaps with existing memory"); pageTable[pageNum]=(RAddr)realMem+(pageNum*getPageSize()-begVAddr); } }
unsigned getMaxNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU, bool Addressable) { assert(WavesPerEU != 0); IsaVersion Version = getIsaVersion(STI->getCPU()); unsigned AddressableNumSGPRs = getAddressableNumSGPRs(STI); if (Version.Major >= 8 && !Addressable) AddressableNumSGPRs = 112; unsigned MaxNumSGPRs = getTotalNumSGPRs(STI) / WavesPerEU; if (STI->getFeatureBits().test(FeatureTrapHandler)) MaxNumSGPRs -= std::min(MaxNumSGPRs, (unsigned)TRAP_NUM_SGPRS); MaxNumSGPRs = alignDown(MaxNumSGPRs, getSGPRAllocGranule(STI)); return std::min(MaxNumSGPRs, AddressableNumSGPRs); }
// Data Cache Block Zero static void dcbz(ThreadState *state, Instruction instr) { uint32_t addr; if (instr.rA == 0) { addr = 0; } else { addr = state->gpr[instr.rA]; } addr += state->gpr[instr.rB]; addr = alignDown(addr, 32); memset(gMemory.translate(addr), 0, 32); }
void TestObjectRecognition() { size_t headersSize = sizeof(LargeMemoryBlock)+sizeof(LargeObjectHdr); unsigned falseObjectSize = 113; // unsigned is the type expected by getObjectSize size_t obtainedSize; ASSERT(sizeof(BackRefIdx)==4, "Unexpected size of BackRefIdx"); ASSERT(getObjectSize(falseObjectSize)!=falseObjectSize, "Error in test: bad choice for false object size"); void* mem = scalable_malloc(2*slabSize); ASSERT(mem, "Memory was not allocated"); Block* falseBlock = (Block*)alignUp((uintptr_t)mem, slabSize); falseBlock->objectSize = falseObjectSize; char* falseSO = (char*)falseBlock + falseObjectSize*7; ASSERT(alignDown(falseSO, slabSize)==(void*)falseBlock, "Error in test: false object offset is too big"); void* bufferLOH = scalable_malloc(2*slabSize + headersSize); ASSERT(bufferLOH, "Memory was not allocated"); LargeObjectHdr* falseLO = (LargeObjectHdr*)alignUp((uintptr_t)bufferLOH + headersSize, slabSize); LargeObjectHdr* headerLO = (LargeObjectHdr*)falseLO-1; headerLO->memoryBlock = (LargeMemoryBlock*)bufferLOH; headerLO->memoryBlock->unalignedSize = 2*slabSize + headersSize; headerLO->memoryBlock->objectSize = slabSize + headersSize; headerLO->backRefIdx = BackRefIdx::newBackRef(/*largeObj=*/true); setBackRef(headerLO->backRefIdx, headerLO); ASSERT(scalable_msize(falseLO) == slabSize + headersSize, "Error in test: LOH falsification failed"); removeBackRef(headerLO->backRefIdx); const int NUM_OF_IDX = BR_MAX_CNT+2; BackRefIdx idxs[NUM_OF_IDX]; for (int cnt=0; cnt<2; cnt++) { for (int master = -10; master<10; master++) { falseBlock->backRefIdx.master = (uint16_t)master; headerLO->backRefIdx.master = (uint16_t)master; for (int bl = -10; bl<BR_MAX_CNT+10; bl++) { falseBlock->backRefIdx.offset = (uint16_t)bl; headerLO->backRefIdx.offset = (uint16_t)bl; for (int largeObj = 0; largeObj<2; largeObj++) { falseBlock->backRefIdx.largeObj = largeObj; headerLO->backRefIdx.largeObj = largeObj; obtainedSize = safer_scalable_msize(falseSO, NULL); ASSERT(obtainedSize==0, "Incorrect pointer accepted"); obtainedSize = safer_scalable_msize(falseLO, NULL); ASSERT(obtainedSize==0, "Incorrect pointer accepted"); } } } if (cnt == 1) { for (int i=0; i<NUM_OF_IDX; i++) removeBackRef(idxs[i]); break; } for (int i=0; i<NUM_OF_IDX; i++) { idxs[i] = BackRefIdx::newBackRef(/*largeObj=*/false); setBackRef(idxs[i], NULL); } } char *smallPtr = (char*)scalable_malloc(falseObjectSize); obtainedSize = safer_scalable_msize(smallPtr, NULL); ASSERT(obtainedSize==getObjectSize(falseObjectSize), "Correct pointer not accepted?"); scalable_free(smallPtr); obtainedSize = safer_scalable_msize(mem, NULL); ASSERT(obtainedSize>=2*slabSize, "Correct pointer not accepted?"); scalable_free(mem); scalable_free(bufferLOH); }