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 + -
显示快捷键?