jitmemory.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 763 行 · 第 1/2 页

C
763
字号
/* * @(#)jitmemory.c	1.11 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/utils.h"#include "javavm/include/globals.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/jit/jitutils.h"#include "javavm/include/jit/jitmemory.h"/* * This file implements the CVMJITmemXXX() apis. *//* * Large chunks are preallocated to reduce fragmentation, speed up  * allocation, and speed up freeing all memory. Each chunk holds * CVMJIT_MEMCHUNK_MAXSIZE many bytes of data by default */#define CVMJIT_MEMCHUNK_MAXSIZE 8192struct CVMJITMemChunk {    CVMJITMemChunk* next;    CVMUint8*       curPtr;    CVMUint8*       dataEnd;#ifdef CVM_JIT_COLLECT_STATS    CVMUint32       alignmentWaste; /* Total per-chunk */#endif    CVMUint8        data[1];};/* Note: #define CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION if you want to   validate the memory fence blocks on every allocation. */#undef CVM_DO_INTENSIVE_MEMORY_FENCE_VALIDATION#ifdef CVM_DEBUG_ASSERTS/* NOTES: About the memory fence debugging tool:   ============================================   The Memory Fence tool works by padding all allocation requests with some   header and footer records.   The header contains information about the caller of the allocation as well   as some checksums to ensure the header itself hasn't been corrupted.  The   header ends in an array of CVM_MEMORY_FENCE_SIZE fences which are filled   with the CVM_MEMORY_FENCE_MAGIC_WORD value.   The footer starts with an array of CVM_MEMORY_FENCE_SIZE fences which are   also filled with the CVM_MEMORY_FENCE_MAGIC_WORD value.  After the fences,   some extra memory is allocated for extra info that the particular instance   of the fence may require.   The integrity of blocks in a block list can be validated by invoking   CVMmemoryFenceValidateBlocks() on a block list.  The validation process will   validate the checksum of the header first.  This ensures that the info in   the header (including the checksum of the footer) is reliable.       Next, the checksum of the footer is validated which ensures that the   extra info in the footer is valid.  Subsequently, the fences in the header   and footer are validated.   When a corruption is detected, CVMmemoryFenceValidateBlocks() will call on   CVMmemoryFenceReportError() to dump the info in the block.   CVMmemoryFenceReportError() is conscious of possible corrupted data and will   not make use of any data that is corrupted in an unreliable way.   The memory fence implementation can be customized by the user during   initialization of each block by passing in a vtbl.  This vtbl provides the   callbacks necessary to initialize and dump the the extra info fields.   NOTE: The memory fence list is built with a singly linked list.  This is   deliberate as it simplifies the checksum computations.  a doubly linked   list would add complication in the form of having to update checksums and   may open the window to corruptions sneaking by if not done carefully.*//* Data structures for the memory fence debugging util: */typedef struct CVMMemoryFenceVtbl CVMMemoryFenceVtbl;typedef struct CVMMemoryFenceBlock CVMMemoryFenceBlock;#define CVM_MEMORY_FENCE_SIZE          5#define CVM_MEMORY_FENCE_MAGIC_WORD    0xcafebabe#define CVM_MEMORY_FENCE_CHECKSUM_SEED 0xa5a5a5a5struct CVMMemoryFenceVtbl{    void (*initExtraInfo)(void *blockExtraInfo, void *extraInfo);    void (*dumpExtraInfo)(void *blockExtraInfo);};struct CVMMemoryFenceBlock{    CVMUint32 headerChecksum;    CVMUint32 footerChecksum;    const CVMMemoryFenceVtbl *vtbl;    CVMMemoryFenceBlock *prev;    const char *filename;    CVMUint32 lineNumber;    CVMUint32 size;    CVMUint32 extraInfoSize;    /* Header fence goes here ... */    /* User data is next ... */    /* Footer fence comes after ... */    /* ExtraInfo is last ... */};/*===========================================================================// CVMMemoryFence prototypes:*/static voidCVMmemoryFenceInit(void **blocksList, const CVMMemoryFenceVtbl *vtbl,                   CVMMemoryFenceBlock *block, const char *filename,                   CVMUint32 lineNumber, CVMUint32 size,                   void *extraInfo, CVMUint32 extraInfoSize);static voidCVMmemoryFenceDestroy(void **blocksList, CVMMemoryFenceBlock *block);static CVMUint32CVMmemoryFenceComputeHeaderChecksum(CVMMemoryFenceBlock *block);static CVMUint32CVMmemoryFenceComputeFooterChecksum(CVMMemoryFenceBlock *block);static voidCVMmemoryFenceValidateBlocks(void **blocksList,                             const char *validatingFilename,                             CVMUint32 validatingLineNumber,                             const char *validatingMessage);static voidCVMmemoryFenceReportError(CVMMemoryFenceBlock *block,                          const char *errMessage,                          const char *validatingFilename,                          CVMUint32 validatingLineNumber,                          const char *validatingMessage);/*===========================================================================// CVMMemoryFence macros:*//* Purpose: Increases the size by the amount of memory needed by the memory            fence. */#define CVMmemoryFenceComputeAdjustedSize(requestedSize, extraInfoSize) \    (CVMpackSizeBy(sizeof(CVMMemoryFenceBlock), 4) + \     (sizeof(CVMUint32) * CVM_MEMORY_FENCE_SIZE) + \     CVMpackSizeBy((requestedSize), 4) + \     (sizeof(CVMUint32) * CVM_MEMORY_FENCE_SIZE) + \     CVMpackSizeBy((extraInfoSize), 4))/* Purpose: Gets the location of the header fence in the block. */#define CVMmemoryFenceBlock2HeaderFence(block) \    ((CVMUint32 *)((CVMUint8 *)(block) + \                   CVMpackSizeBy(sizeof(CVMMemoryFenceBlock), 4)))/* Purpose: Gets the location of the data area in the block. */#define CVMmemoryFenceBlock2Data(block) \    ((CVMUint8 *)CVMmemoryFenceBlock2HeaderFence(block) + \     (sizeof(CVMUint32) * CVM_MEMORY_FENCE_SIZE))/* Purpose: Gets the location of the footer fence in the block. */#define CVMmemoryFenceBlock2FooterFence(block) \    ((CVMUint32 *)(CVMmemoryFenceBlock2Data(block) + \                   CVMpackSizeBy((block)->size, 4)))/* Purpose: Gets the location of the extraInfo in the block. */#define CVMmemoryFenceBlock2ExtraInfo(block) \    ((void *)(CVMmemoryFenceBlock2FooterFence(block) + CVM_MEMORY_FENCE_SIZE))/* Purpose: Gets the location of the block given the data area. */#define CVMmemoryFenceData2Block(data) \    ((CVMMemoryFenceBlock *)(((CVMUint8 *)data) - \                             CVMpackSizeBy(sizeof(CVMMemoryFenceBlock), 4) - \                             (sizeof(CVMUint32) * CVM_MEMORY_FENCE_SIZE)))/*===========================================================================// CVMMemoryFence functions:*//* Purpose: Initializes the memory fence. */static voidCVMmemoryFenceInit(void **blocksList, const CVMMemoryFenceVtbl *vtbl,                   CVMMemoryFenceBlock *block, const char *filename,                   CVMUint32 lineNumber, CVMUint32 size,                   void *extraInfo, CVMUint32 extraInfoSize){    CVMUint32 *headerFence;    CVMUint32 *footerFence;    void *blockExtraInfo;    int i;    /* NOTE: The initialization sequence is deliberately done in the following       order because some steps may depend on the previous ones having being       initialized.  Be careful if you wish to rearrange the order of things.    */    /* Initialize block info: */    block->vtbl = vtbl;    block->prev = NULL;    block->filename = filename;    block->lineNumber = lineNumber;    block->size = size;    block->extraInfoSize = extraInfoSize;    /* Initialize header & footer fence: */    headerFence = CVMmemoryFenceBlock2HeaderFence(block);    footerFence = CVMmemoryFenceBlock2FooterFence(block);    for (i = 0; i < CVM_MEMORY_FENCE_SIZE; i++) {        headerFence[i] = CVM_MEMORY_FENCE_MAGIC_WORD;        footerFence[i] = CVM_MEMORY_FENCE_MAGIC_WORD;    }    /* Initialize the extraInfo: */    blockExtraInfo = CVMmemoryFenceBlock2ExtraInfo(block);    if (vtbl != NULL) {        vtbl->initExtraInfo(blockExtraInfo, extraInfo);    }    /* Add this block to the memory fence blocks list: */    if (*blocksList != NULL) {        CVMMemoryFenceBlock *prev = (CVMMemoryFenceBlock *)*blocksList;        block->prev = prev;    }    *blocksList = (void *)block;    /* Initialize footer checksum: */    block->footerChecksum = CVMmemoryFenceComputeFooterChecksum(block);    /* Lastly, initialize header checksum: */    block->headerChecksum = CVMmemoryFenceComputeHeaderChecksum(block);}/* Purpose: Removes the block from the block list and do house-cleaning. *//* NOTE: This function assumes that the list has already been validated using         CVMmemoryFenceValidateBlocks(). */static voidCVMmemoryFenceDestroy(void **blocksList, CVMMemoryFenceBlock *block){    CVMMemoryFenceBlock *b = (CVMMemoryFenceBlock *)*blocksList;    CVMMemoryFenceBlock *next = 0;    while (b && b != block) {        next = b;        b = b->prev;    }    /* Make sure that we actually found the block: */    CVMassert(b != NULL);    if (next != 0) {        next->prev = b->prev;        /* Need to recompute the header checksum in the next block because the           prev pointer has changed: */        next->headerChecksum = CVMmemoryFenceComputeHeaderChecksum(next);    } else {        *blocksList = b->prev;    }}/* Purpose: Computes the checksum for the block header fields. */static CVMUint32CVMmemoryFenceComputeHeaderChecksum(CVMMemoryFenceBlock *block){    return CVM_MEMORY_FENCE_CHECKSUM_SEED +           (CVMUint32)block->footerChecksum +           (CVMUint32)block->vtbl +           (CVMUint32)block->prev +           (CVMUint32)block->filename +           (CVMUint32)block->lineNumber +           (CVMUint32)block->size +           (CVMUint32)block->extraInfoSize;}/* Purpose: Computes the checksum for the block footer fields. */static CVMUint32CVMmemoryFenceComputeFooterChecksum(CVMMemoryFenceBlock *block){    CVMUint32 checksum = CVM_MEMORY_FENCE_CHECKSUM_SEED;    CVMUint32 scaledExtraInfoSize;    CVMUint32 *extraInfo = (CVMUint32 *)CVMmemoryFenceBlock2ExtraInfo(block);    int i;    scaledExtraInfoSize = CVMpackSizeBy(block->extraInfoSize, 4) / 4;    for (i = 0; i < scaledExtraInfoSize; i++) {        checksum += extraInfo[i];    }    return checksum;}/* Purpose: Validates the contents of the memory fence to see if any corruption            has been detected. */static voidCVMmemoryFenceValidateBlocks(void **blocksList,                             const char *validatingFilename,                             CVMUint32 validatingLineNumber,                             const char *validatingMessage){    CVMMemoryFenceBlock *block = (CVMMemoryFenceBlock *)*blocksList;    while (block) {        CVMUint32 checksum;        CVMUint32 *fence;        int i;        /* First we validate the header checksum to make sure that none of the           data in the header (including the footer checksum, but not including           the fence itself) has been corrupted:        */        checksum = CVMmemoryFenceComputeHeaderChecksum(block);        if (checksum != block->headerChecksum) {            CVMmemoryFenceReportError(block, "header checksum failure",                validatingFilename, validatingLineNumber, validatingMessage);        }        /* Next we validate the footer checksum to make sure that the extraInfo           has been corrupted:        */        checksum = CVMmemoryFenceComputeFooterChecksum(block);        if (checksum != block->footerChecksum) {            CVMmemoryFenceReportError(block, "footer checksum failure",                validatingFilename, validatingLineNumber, validatingMessage);        }        /* Next, inspect the header fence: */        fence = CVMmemoryFenceBlock2HeaderFence(block);        for (i = 0; i < CVM_MEMORY_FENCE_SIZE; i++) {            if (fence[i] != CVM_MEMORY_FENCE_MAGIC_WORD) {                CVMmemoryFenceReportError(block,                    "header fence corrupted", validatingFilename,                    validatingLineNumber, validatingMessage);            }        }        /* Next, inspect the footer fence: */        fence = CVMmemoryFenceBlock2FooterFence(block);        for (i = 0; i < CVM_MEMORY_FENCE_SIZE; i++) {            if (fence[i] != CVM_MEMORY_FENCE_MAGIC_WORD) {                CVMmemoryFenceReportError(block,                    "footer fence corrupted", validatingFilename,                    validatingLineNumber, validatingMessage);            }        }        /* Move onto next fence: */        block = block->prev;    }}/* Purpose: Reports an error detected during memory fence validation. */static voidCVMmemoryFenceReportError(CVMMemoryFenceBlock *block,                          const char *errMessage,                          const char *validatingFilename,                          CVMUint32 validatingLineNumber,                          const char *validatingMessage){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?