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