jitmemory.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 763 行 · 第 1/2 页
C
763 行
CVMUint32 *fence; CVMUint32 headerChecksum; CVMBool headerIsGood; int i; /* Print error message: */ CVMconsolePrintf("\n"); CVMconsolePrintf("CVMMemoryFenceError: %s\n", errMessage); CVMconsolePrintf(" Detected while doing %s\n", validatingMessage); CVMconsolePrintf(" at line %d in %s\n", validatingLineNumber, validatingFilename); /* Print some block info: */ CVMconsolePrintf("\n"); CVMconsolePrintf(" Found at block: 0x%x\n", block); headerChecksum = CVMmemoryFenceComputeHeaderChecksum(block); headerIsGood = (headerChecksum == block->headerChecksum); CVMconsolePrintf(" actual header checksum: 0x%x\n", headerChecksum); CVMconsolePrintf(" expected header checksum: 0x%x\n", block->headerChecksum); if (headerIsGood) { CVMconsolePrintf(" actual footer checksum: 0x%x\n", CVMmemoryFenceComputeFooterChecksum(block)); CVMconsolePrintf(" expected footer checksum: 0x%x\n", block->footerChecksum); } else { CVMconsolePrintf(" actual footer checksum: " "Unavailable due to corrupted header\n"); CVMconsolePrintf(" expected footer checksum: " "Unavailable due to corrupted header\n"); } CVMconsolePrintf(" vtbl: 0x%x\n", block->vtbl); CVMconsolePrintf(" prev: 0x%x\n", block->prev); /* Print block allocation info: */ CVMconsolePrintf("\n"); CVMconsolePrintf(" Allocated by:\n"); if (headerIsGood) { CVMconsolePrintf(" filename: %s\n", block->filename); } else { CVMconsolePrintf(" filename: 0x%x\n", block->filename); } CVMconsolePrintf(" lineNumber: %d\n", block->lineNumber); CVMconsolePrintf(" alloc size: %d\n", block->size); CVMconsolePrintf(" alloc extraInfoSize: %d\n", block->extraInfoSize); CVMconsolePrintf(" data address: 0x%x\n", CVMmemoryFenceBlock2Data(block)); /* Print header fence values: */ CVMconsolePrintf("\n"); CVMconsolePrintf(" Header fence values:\n"); fence = CVMmemoryFenceBlock2HeaderFence(block); for (i = 0; i < CVM_MEMORY_FENCE_SIZE; i++) { CVMconsolePrintf(" fence[%d]: 0x%x\n", i, fence[i]); } /* Print footer fence values: */ CVMconsolePrintf("\n"); CVMconsolePrintf(" Footer fence values:\n"); fence = CVMmemoryFenceBlock2FooterFence(block); for (i = 0; i < CVM_MEMORY_FENCE_SIZE; i++) { CVMconsolePrintf(" fence[%d]: 0x%x\n", i, fence[i]); } /* Print extra Info: */ CVMconsolePrintf("\n"); CVMconsolePrintf(" Extra info:\n"); if (headerIsGood) { /* If we get here, then the header is probably fine, and we can trust the vtbl: */ if (block->vtbl != NULL) { block->vtbl->dumpExtraInfo(CVMmemoryFenceBlock2ExtraInfo(block)); CVMconsolePrintf("\n"); } else { CVMconsolePrintf(" No extra info\n"); } } else { CVMconsolePrintf(" Unavailable due to corrupted header\n"); } CVMassert(CVM_FALSE);}/*============================================================================// Memory Fence for CVMJITmemNew():*/static voidmemNewInitExtraInfo(void *blockExtraInfo, void *extraInfo){ CVMJITAllocationTag *tag = (CVMJITAllocationTag *)extraInfo; CVMJITAllocationTag *info = (CVMJITAllocationTag *)blockExtraInfo; *info = *tag;}/* Purpose: Returns the name of the allocator based on the specified tag. */static const char*CVMJITallocationTag2Name(CVMJITAllocationTag i){ switch(i) { case JIT_ALLOC_IRGEN_NODE: return "JIT_ALLOC_IRGEN_NODE"; case JIT_ALLOC_IRGEN_OTHER: return "JIT_ALLOC_IRGEN_OTHER"; case JIT_ALLOC_OPTIMIZER: return "JIT_ALLOC_OPTIMIZER"; case JIT_ALLOC_CGEN_REGMAN: return "JIT_ALLOC_CGEN_REGMAN"; case JIT_ALLOC_CGEN_ALURHS: return "JIT_ALLOC_CGEN_ALURHS"; case JIT_ALLOC_CGEN_MEMSPEC: return "JIT_ALLOC_CGEN_MEMSPEC"; case JIT_ALLOC_CGEN_FIXUP: return "JIT_ALLOC_CGEN_FIXUP"; case JIT_ALLOC_CGEN_OTHER: return "JIT_ALLOC_CGEN_OTHER"; case JIT_ALLOC_COLLECTIONS: return "JIT_ALLOC_COLLECTIONS"; case JIT_ALLOC_DEBUGGING: return "JIT_ALLOC_DEBUGGING";/* IAI - 08 */#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD case JIT_ALLOC_CODE_SCHEDULING: return "JIT_ALLOC_CODE_SCHEDULING";#endif /* IAI_CODE_SCHEDULER_SCORE_BOARD */ default: return "<UNKNOWN ALLOCATION>"; }}static voidmemNewDumpExtraInfo(void *blockExtraInfo){ CVMJITAllocationTag tag = *(CVMJITAllocationTag *)blockExtraInfo; const char *typeStr = CVMJITallocationTag2Name(tag); CVMconsolePrintf(" tag: %s\n", typeStr);}const CVMMemoryFenceVtbl memNewMemoryFenceVtbl ={ memNewInitExtraInfo, memNewDumpExtraInfo,};#endif/* Purpose: Allocates a buffer to be used as working memory by the dynamic compiler.*/static CVMJITMemChunk*allocateAndLinkNewChunk(CVMJITCompilationContext* con, CVMUint32 dataSize){ CVMJITMemChunk* allocChunk; CVMJITMemChunk* topChunk = con->memChunks; CVMUint32 chunkSize = sizeof(CVMJITMemChunk) + (dataSize - 1) * sizeof(CVMUint8); allocChunk = calloc(1, chunkSize); if (allocChunk == NULL) { CVMJITerror(con, OUT_OF_MEMORY, "Failed to allocate new chunk"); CVMassert(CVM_FALSE); /* CVMJITerror must not return */ } allocChunk->curPtr = allocChunk->data; allocChunk->dataEnd = &allocChunk->data[dataSize]; allocChunk->next = topChunk;#ifdef CVM_JIT_COLLECT_STATS allocChunk->alignmentWaste = 0;#endif con->memChunks = allocChunk; return allocChunk;}voidCVMJITmemInitialize(CVMJITCompilationContext* con){ /* Have one chunk ready */ allocateAndLinkNewChunk(con, CVMJIT_MEMCHUNK_MAXSIZE);}/* Purpose: Allocates some working memory from the allocator specified by the allocation tag. */void*CVMJITmemNewInternal(CVMJITCompilationContext* con, CVMJITAllocationTag tag, CVMUint32 sizeIn DECLARE_CALLER_INFO(callerFilename, callerLineNumber)){ CVMJITMemChunk* allocChunk = con->memChunks; CVMUint32 size; CVMUint8 *dataEnd = allocChunk->dataEnd; CVMUint8 *result = allocChunk->curPtr; CVMUint8 *resultEnd;#ifdef CVM_DEBUG_ASSERTS CVMUint32 origSize;#endif size = CVMpackSizeBy(sizeIn, 4); /* Round it up. */#ifdef CVM_DEBUG_ASSERTS origSize = size; size = CVMmemoryFenceComputeAdjustedSize(origSize, sizeof(tag));#define STATS_SIZE origSize#else#define STATS_SIZE size#endif if (tag != JIT_ALLOC_DEBUGGING) { con->workingMemory += STATS_SIZE; if (con->workingMemory > CVMglobals.jit.maxWorkingMemorySize) { CVMJITlimitExceeded(con, "out of working memory"); } } resultEnd = result + size; if (resultEnd < dataEnd) { allocChunk->curPtr = resultEnd; } else { /* Time to expand. You'd better fit in this next chunk */ if (size < CVMJIT_MEMCHUNK_MAXSIZE) { allocChunk = allocateAndLinkNewChunk(con, CVMJIT_MEMCHUNK_MAXSIZE); } else { /* Make it just big enough for this big big allocation */ allocChunk = allocateAndLinkNewChunk(con, size); } result = allocChunk->data; allocChunk->curPtr = result + size; CVMassert((size < CVMJIT_MEMCHUNK_MAXSIZE) || (allocChunk->curPtr == allocChunk->dataEnd)); } #ifdef CVM_JIT_COLLECT_STATS CVMJITstatsRecordAdd(con, (CVMJITStatsTag)tag, STATS_SIZE); CVMJITstatsRecordAdd(con, CVMJIT_STATS_TOTAL_WORKING_MEMORY, STATS_SIZE); allocChunk->alignmentWaste += STATS_SIZE - sizeIn;#endif /* CVM_JIT_COLLECT_STATS */#ifdef CVM_DEBUG_ASSERTS#ifdef CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION /* Make sure there is no corruption before allocating a new block: */ CVMmemoryFenceValidateBlocks(&con->memoryFenceBlocks, callerFilename, callerLineNumber, "CVMJITmemNew()");#endif /* CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION */ /* Initialize the fence: */ CVMmemoryFenceInit(&con->memoryFenceBlocks, &memNewMemoryFenceVtbl, (CVMMemoryFenceBlock *)result, callerFilename, callerLineNumber, sizeIn, &tag, sizeof(tag)); /* Compute the address of the data buffer requested by the caller: */ result = CVMmemoryFenceBlock2Data(result);#endif /* CVM_DEBUG_ASSERTS */ return result;}/* * Flush all memory allocated with CVMJITmemNew() */voidCVMJITmemFlush(CVMJITCompilationContext* con){ CVMJITMemChunk* chunk; CVMJITMemChunk* nextChunk;#ifdef CVM_DEBUG_ASSERTS /* Make sure there is no corruption before releasing all the blocks: */ CVMmemoryFenceValidateBlocks(&con->memoryFenceBlocks, __FILE__, __LINE__, "CVMJITmemFlush()");#endif /* CVM_DEBUG_ASSERTS */ for (chunk = con->memChunks; chunk != NULL; chunk = nextChunk) { nextChunk = chunk->next;#ifdef CVM_DEBUG /* Make sure you delete all data before blowing it off */ memset(chunk->data, 0, chunk->dataEnd - chunk->data);#endif#ifdef CVMJIT_MEM_STATS#ifdef CVM_JIT_COLLECT_STATS { CVMUint32 chunkSize = chunk->dataEnd - chunk->data; CVMconsolePrintf("\tCVMJITmemAlloc(): FREEING CHUNK 0x%x\n", chunk); CVMconsolePrintf("\t\tsize=%d, alignment waste=%d%% unused=%d%%\n", chunkSize, chunk->alignmentWaste * 100 / chunkSize, (chunk->dataEnd-chunk->curPtr) * 100 / chunkSize); };#endif /* CVM_JIT_COLLECT_STATS */#endif /* CVMJIT_MEM_STATS */ free(chunk); } con->memChunks = NULL; /* Just in case */}/* * Separate "permanent" memory allocations from temporary allocations */void*CVMJITmemNewLongLivedMemoryInternal(CVMJITCompilationContext* con, CVMUint32 size DECLARE_CALLER_INFO(callerFilename, callerLineNumber)){ void *ret;#ifdef CVM_DEBUG_ASSERTS CVMUint32 origSize = size; size = CVMpackSizeBy(size, 4); /* Round it up. */ size = CVMmemoryFenceComputeAdjustedSize(size, 0);#endif ret = calloc(1, size); if (ret == NULL) { CVMJITerror(con, OUT_OF_MEMORY, "Failed to new long lived memory"); }#ifdef CVM_DEBUG_ASSERTS#ifdef CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION /* Make sure there is no corruption before allocating a new block: */ CVMmemoryFenceValidateBlocks(&CVMglobals.jit.longLivedMemoryBlocks, callerFilename, callerLineNumber, "CVMJITmemNewLongLivedMemory()");#endif /* CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION */ CVMmemoryFenceInit(&CVMglobals.jit.longLivedMemoryBlocks, NULL, (CVMMemoryFenceBlock *)ret, callerFilename, callerLineNumber, origSize, NULL, 0); /* Compute the address of the data buffer requested by the caller: */ ret = CVMmemoryFenceBlock2Data(ret);#endif /* CVM_DEBUG_ASSERTS */ return ret;}void*CVMJITmemExpandLongLivedMemoryInternal(CVMJITCompilationContext* con, void * ptr, CVMUint32 size DECLARE_CALLER_INFO(callerFilename, callerLineNumber)){ void *ret;#ifdef CVM_DEBUG_ASSERTS CVMUint32 origSize = size; size = CVMpackSizeBy(size, 4); /* Round it up. */ size = CVMmemoryFenceComputeAdjustedSize(size, 0); ptr = CVMmemoryFenceData2Block(ptr);#ifdef CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION /* Make sure there is no corruption before re-allocating the block: */ CVMmemoryFenceValidateBlocks(&CVMglobals.jit.longLivedMemoryBlocks, callerFilename, callerLineNumber, "CVMJITmemExpandLongLivedMemory()");#endif /* CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION */ /* Remove from the list first because the realloc() may free it: */ CVMmemoryFenceDestroy(&CVMglobals.jit.longLivedMemoryBlocks, (CVMMemoryFenceBlock *)ptr);#endif ret = realloc(ptr, size); if (ret == NULL) { CVMJITerror(con, OUT_OF_MEMORY, "Failed to expand long lived memory"); }#ifdef CVM_DEBUG_ASSERTS /* Re-initialize it: */ CVMmemoryFenceInit(&CVMglobals.jit.longLivedMemoryBlocks, NULL, (CVMMemoryFenceBlock *)ret, callerFilename, callerLineNumber, origSize, NULL, 0); /* Compute the address of the data buffer requested by the caller: */ ret = CVMmemoryFenceBlock2Data(ret);#endif /* CVM_DEBUG_ASSERTS */ return ret;}voidCVMJITmemFreeLongLivedMemoryInternal(void* ptr DECLARE_CALLER_INFO(callerFilename, callerLineNumber)){#ifdef CVM_DEBUG_ASSERTS /* Make sure there is no corruption before re-allocating the block: */ CVMmemoryFenceValidateBlocks(&CVMglobals.jit.longLivedMemoryBlocks, callerFilename, callerLineNumber, "CVMJITmemFreeLongLivedMemory()"); ptr = CVMmemoryFenceData2Block(ptr); CVMmemoryFenceDestroy(&CVMglobals.jit.longLivedMemoryBlocks, ptr);#endif free(ptr);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?