jit_cisc.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 690 行 · 第 1/2 页
C
690 行
/* * @(#)jit_cisc.c 1.7 06/10/23 * * Portions Copyright 2000-2008 Sun Microsystems, Inc. All Rights * Reserved. Use is subject to license terms. * 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. *//* * This file implements part of the jit porting layer. */#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitirlist.h"#include "javavm/include/jit/jitirdump.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitconstantpool.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitfixup.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitdebug.h"#include "javavm/include/globals.h"/* SVMC_JIT d022609 (ML) 2004-02-23. *//* #include "portlibs/jit/cisc/include/porting/jitciscemitter.h" */#include "javavm/include/jit/jitarchemitter.h"#include "javavm/include/jit/ccmcisc.h"#include "javavm/include/jit/jitregman.h"/* SVMC_JIT d022609 (ML) 2004-02-23. *//* #include "portlibs/jit/cisc/jitstackman.h" */#include "javavm/include/jit/jitstackman.h"#include "javavm/include/jit/jitgrammar.h"#include "javavm/include/porting/jit/jit.h"#include "generated/javavm/include/jit/jitcodegen.h"/* * Special backend actions to be done at the beginning and end of each * codegen rule. Usually only enabled when debugging. */#ifdef MIN#undef MIN#endif#define MIN(x,y) ((x) < (y) ? (x) : (y))voidCVMJITdoStartOfCodegenRuleAction(CVMJITCompilationContext *con, int ruleno, const char *description, CVMJITIRNode* node){ /* Check to see if we need a constantpool dump. If so, emit the dump with a branch around it: */ CVMX86emitConstantPoolDumpWithBranchAroundIfNeeded(con); /* The following is intentionally left here to assist in future codegen rules debugging needs if necessary: */#ifdef CVM_DEBUG_JIT_TRACE_CODEGEN_RULE_EXECUTION /* Tell about the codegen rule that is being executed: */ CVMJITprintCodegenComment(("Doing node %4d codegen rule %s", CVMJITirnodeGetID(node), description));#endif}#if defined(CVM_DEBUG_ASSERTS)void CVMJITdoEndOfCodegenRuleAction(CVMJITCompilationContext *con){ /* There should not be any pinned registers at the end of a codegen rule */ CVMassert(CVMRMhasNoPinnedRegisters(con));}#endif#ifdef CVMJIT_PATCH_BASED_GC_CHECKS/************************************************************************** * GC CheckPoints support. * * Instead of generating gc checks, you can just apply a patch that * calls the gc rendezvous code when requested. This is what we * choose to do for our shared risc implementations. If you do gc * checks inline, then these functions can have empty implementations. **************************************************************************//* * Patch or unpatch gc checkpoints. */static voidcsPatchHelper(CVMExecEnv* ee){ CVMUint8* cbuf; CVMJITGlobalState* jgs = &CVMglobals.jit; CVMassert(CVMsysMutexIAmOwner(ee, &CVMglobals.jitLock)); if (jgs->destroyed) { return; }#ifdef CVM_JIT_COPY_CCMCODE_TO_CODECACHE /* SVMC_JIT d022609 (ML) */#if CVMCPU_NUM_CCM_PATCH_POINTS > 0 /* Patch CCM method call and return spots */ { int i; for (i=0; i < CVMCPU_NUM_CCM_PATCH_POINTS; i++) { CVMCCMGCPatchPoint* gcPatchPoint = &jgs->ccmGcPatchPoints[i]; CVMCPUInstruction tmpInstr; CVMCPUInstruction* instrPtr; if (gcPatchPoint->patchPoint == NULL) { continue; } instrPtr = (CVMCPUInstruction*)gcPatchPoint->patchPoint; tmpInstr = gcPatchPoint->patchInstruction; gcPatchPoint->patchInstruction = *instrPtr; /* swap current instruction with saved instruction */ CVMatomicSwap64(instrPtr, tmpInstr); } }#endif#endif /* CVM_JIT_COPY_CCMCODE_TO_CODECACHE */ /* iterate over the code cache, patching all gc points */ for (cbuf = jgs->codeCacheStart; cbuf < jgs->codeCacheEnd; cbuf += CVMJITcbufSize(cbuf)) { if (CVMJITcbufIsCommitted(cbuf)) { CVMCompiledMethodDescriptor* cmd = CVMJITcbufCmd(cbuf); CVMCompiledGCCheckPCs* gcpcs = CVMcmdGCCheckPCs(cmd); CVMUint8* codeBufAddr = CVMcmdCodeBufAddr(cmd); if (gcpcs != NULL) { int i; CVMCPUInstruction* patchedInstructions = CVMCompiledGCCheckPCs_patchedInstructions(gcpcs, gcpcs->noEntries); for (i = 0; i < gcpcs->noEntries; i++) { if (gcpcs->pcEntries[i] != 0) { CVMCPUInstruction tmpInstr; CVMCPUInstruction* instrPtr = (CVMCPUInstruction*) (gcpcs->pcEntries[i] + codeBufAddr); /* swap current instruction with saved instruction */ tmpInstr = patchedInstructions[i]; patchedInstructions[i] = *instrPtr; /* SVMC_JIT rr 01Sept2003: On CISC * `*instrPtr = tmpInstr;' in general is not * atomic. * Used cmpxchg8b to achieve atomic swap. This means * more instruction overhead. But x86 does not support * any other atomic 64 bit move! Need lock prefix too. */ CVMatomicSwap64(instrPtr, tmpInstr); } } } } } /* Flush cache */ CVMJITflushCache(jgs->codeCacheStart, jgs->codeCacheEnd);}voidCVMJITenableRendezvousCalls(CVMExecEnv* ee){ csPatchHelper(ee);}voidCVMJITdisableRendezvousCalls(CVMExecEnv* ee){ csPatchHelper(ee);}#endif#ifdef CVMJIT_TRAP_BASED_GC_CHECKSvoidCVMJITenableRendezvousCalls(CVMExecEnv* ee){ CVMJITenableRendezvousCallsTrapbased(ee);}voidCVMJITdisableRendezvousCalls(CVMExecEnv* ee){ CVMJITdisableRendezvousCallsTrapbased(ee);}#endif/* * fixBranchesToBlock - store the proper branch offset in the branch * instructions that reference the specified ir block. This is * needed for forward branches. */static voidfixBranchesToBlock(CVMJITCompilationContext* con, CVMJITIRBlock* bk, CVMJITFixupElement* fixupList, CVMJITAddressMode addrMode){ CVMInt32 logicalTargetAddress = bk->logicalAddress; CVMJITFixupElement* thisRef = fixupList; while (thisRef != NULL) { CVMJITFixupElement* nextRef = thisRef->next; CVMJITfixupAddress(con, thisRef->logicalAddress, logicalTargetAddress, addrMode); thisRef = nextRef; } }static voidallocateCodeBuffer(CVMJITCompilationContext* con);/* * CVMJITcompileGenerateCode: Main function for compiler back-end * responsible for generating platform specific machine code. By the time * this function is called the IR has already been generated. */#undef MAX#define MAX(a,b) (((a) > (b)) ? (a) : (b))void CVMJITcompileGenerateCode(CVMJITCompilationContext* con){ CVMJITIRBlock* bk; int maxStructSize; int maxStructNumber; int maxStateMachineAllocation; int allocationSize; CVMCPUPrologueRec prec; CVMBool success = CVM_TRUE; /* * Allocate sufficient room for compile-time stacks. * These are VERY generous. */ maxStructSize = MAX( sizeof(struct CVMJITCompileExpression_rule_computation_state), sizeof(struct CVMJITCompileExpression_match_computation_state) ); /* Estimate the max stack depth for the compilation stacks: */ maxStructNumber = (con->saveRootCnt + 1) * 3; CVMJITstatsRecordSetCount(con, CVMJIT_STATS_COMPUTED_COMP_STACK_MAX, maxStructNumber); maxStateMachineAllocation = maxStructSize * maxStructNumber; allocationSize = maxStateMachineAllocation + sizeof(struct CVMJITStackElement) * maxStructNumber; con->compilationStateStack = CVMJITmemNew(con, JIT_ALLOC_CGEN_OTHER, allocationSize); con->cgstackInit = (struct CVMJITStackElement*) ((char*)(con->compilationStateStack) + maxStateMachineAllocation); con->cgstackLimit = con->cgstackInit + maxStructNumber; /* * Initialize subsystems */ CVMRMinit(con); CVMSMinit(con); allocateCodeBuffer(con); /* Emit prologue and get patchable instruction state into prec */ CVMJITprintCodegenComment(("Method prologue")); CVMCPUemitMethodPrologue(con, &prec); CVMJITsetInit(con, &con->localRefSet); /* Support for passing phis in registers. Decide the register assignments and store the result in the USED nodes */ bk = (CVMJITIRBlock*)CVMJITirlistGetHead(&(con->bkList)); while ( bk != NULL){ if (CVMJITirblockIsTranslated(bk)) { if (bk->phiCount > 0) { CVMRMallocatePhiRegisters(con, bk); }#ifdef CVM_JIT_REGISTER_LOCALS if (bk->incomingLocalsCount > 0) { CVMassert(bk->phiCount <= 0); CVMRMallocateIncomingLocalsRegisters(con, bk); }#endif } bk = CVMJITirblockGetNext(bk); } bk = (CVMJITIRBlock*)CVMJITirlistGetHead(&(con->bkList)); while ( bk != NULL){ CVMJITIRRoot* root = (CVMJITIRRoot*)CVMJITirlistGetHead(CVMJITirblockGetRootList(bk)); CVMtraceJITCodegen(("%d: L%d:\n", CVMJITcbufGetLogicalPC(con), CVMJITirblockGetBlockID(bk))); if (!CVMJITirblockIsTranslated(bk)) { CVMassert(root == NULL); CVMassert(bk->branchFixupList == NULL); CVMassert(bk->condBranchFixupList == NULL); CVMassert(bk->condBranchFixupList == NULL); } else { con->currentCompilationBlock = bk; /* NOTE: CVMRMbeginBlock() may need to emit some code for the start of the block e.g. the GC rendezvous code. Hence, we should record the starting address of the block before calling CVMRMbeginBlock(). */ bk->flags |= CVMJITIRBLOCK_ADDRESS_FIXED; bk->logicalAddress = CVMJITcbufGetLogicalPC(con); fixBranchesToBlock(con, bk, bk->branchFixupList, CVMJIT_BRANCH_ADDRESS_MODE); fixBranchesToBlock(con, bk, bk->condBranchFixupList, CVMJIT_COND_BRANCH_ADDRESS_MODE); CVMRMbeginBlock(con, bk); while (root != NULL){ int compilationResult; con->cgsp = con->cgstackInit;#ifdef CVM_JIT_ENABLE_IR_CFG
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?