📄 jitcodesched.c
字号:
/* * @(#)jitcodesched.c 1.8 06/10/10 * * 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. * *//* * Copyright 2005 Intel Corporation. All rights reserved. */#include "javavm/include/iai_opt_config.h"#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/utils.h"#include "javavm/include/bcutils.h"#include "javavm/include/globals.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitir.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitstackmap.h"#include "javavm/include/jit/jitfixup.h"#include "javavm/include/jit/jitcodesched.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitconstantpool.h"#include "javavm/include/jit/jitmemory.h"#include "portlibs/jit/risc/include/porting/jitriscemitter.h"#include "portlibs/jit/risc/include/export/jitregman.h"#include "portlibs/jit/risc/jitstackman.h"#include "javavm/include/clib.h"typedef struct { union { struct { CVMUint32 offset_12:12; CVMUint32 Rd:4; CVMUint32 Rn:4; CVMUint32 Lbit:1; CVMUint32 Wbit:1; CVMUint32 Bbit:1; CVMUint32 Ubit:1; CVMUint32 Pbit:1; CVMUint32 bit25:1; CVMUint32 bit2627:2; CVMUint32 cond:4; } ldrInstructionBits; CVMUint32 instr; } u;} CVMARMLdrStrInstruction;struct CVMJITCSPatchInstruction{ CVMUint32 flags; CVMUint32 targetAddress; CVMUint32 logicalPC;};#undef MAX#define MAX(a, b) (a > b ? a : b)#define CVMARMisNOP2Instruction(instr) \ (instr == CVMCPU_NOP2_INSTRUCTION)#define CVMARMgetLdrTargetOffsetAddress(instr) \ ((instr).u.ldrInstructionBits.Ubit \ ? (instr.u.ldrInstructionBits.offset_12) \ : -(instr.u.ldrInstructionBits.offset_12))#define CVMARMisBranchInstruction(instr) \ (((instr) & 0x0e000000) == 0x0a000000)#define CVMARMisLdrInstruction(instr) \ ((((instr) & 0x0c100000) == 0x04100000) || \ ((((instr) & 0x0e100090) == 0x00100090) && (((instr) & 0x00000060) != 0)))#define CVMARMgetLdrInstructionBaseRegister(instr) \ ((instr) & 0x000f0000)#define CVMARMgetBranchTargetOffsetAddress(instr) \ ((((instr) & 0x800000) \ ? ((instr) | 0xff800000) \ : ((instr) & 0x007fffff)) << 2)#define CVM_XSCALE_LDR_LATENCY 3#define MAX_TEMP_INSTRUCTION_BUFFER (4*1024)voidCVMJITcsInitInstructionStack(CVMJITCompilationContext* con){ CVMJITCSInstructionStack(con) = CVMJITmemNew(con, JIT_ALLOC_CODE_SCHEDULING, MAX_TEMP_INSTRUCTION_BUFFER); CVMJITcsTopOfInstructions(con) = 0;}voidCVMJITcsInitNOPsArray(CVMJITCompilationContext* con){ CVMJITgarrInit(con, CVMJITcsNopsArray(con), sizeof(CVMUint32));}voidCVMJITcsPushNOPInstruction(CVMJITCompilationContext* con, CVMUint32 logicalPC){ CVMUint32* item; void* garrElem; CVMJITgarrNewElem(con, CVMJITcsNopsArray(con), garrElem); item = (CVMUint32*)garrElem; *item = logicalPC;}voidCVMJITcsPopNOPInstruction(CVMJITCompilationContext* con){ CVMJITgarrPopElem(con, CVMJITcsNopsArray(con));}voidCVMJITCSInitConstantPoolEntry(CVMJITCompilationContext* con){ CVMJITCSConstantPoolDumpInfo* item; CVMJITgarrInit(con, CVMJITcsConstantPoolArray(con), sizeof(CVMJITCSConstantPoolDumpInfo)); item = CVMJITcsAllocateConstantPoolDumpInfoEntry(con); item->startPC = (CVMUint32)CVMJITcbufGetLogicalPC(con); item->endPC = (CVMUint32)CVMJITcbufGetLogicalPC(con);}CVMJITCSConstantPoolDumpInfo*CVMJITcsAllocateConstantPoolDumpInfoEntry(CVMJITCompilationContext* con){ void* item; CVMJITgarrNewElem(con, CVMJITcsConstantPoolArray(con), item); return (CVMJITCSConstantPoolDumpInfo*)item;}void CVMJITcsPushInstruction(CVMJITCompilationContext* con, CVMUint32 flags, CVMUint32 logicalPC, CVMUint32 targetAddress){ CVMUint32* NOPs; if (CVMJITcsTopOfInstructions(con) == (MAX_TEMP_INSTRUCTION_BUFFER / sizeof(CVMJITCSPatchInstruction))) { /* * Fixup the possible instruction */ int i; CVMUint32 end = CVMJITcsTopOfInstructions(con); CVMJITcsTopOfInstructions(con) = 0; CVMJITcsPushNOPInstruction(con, (CVMUint32)CVMJITcbufGetLogicalPC(con)); NOPs = CVMJITgarrGetElems(con, CVMJITcsNopsArray(con)); for (i = 0; i < end; i++) { if (CVMJITCSInstructionStack(con)[i].targetAddress < (CVMUint32)CVMJITcbufGetLogicalPC(con)) { CVMUint32 numOfNopsFounded; for (numOfNopsFounded = 0; CVMJITCSInstructionStack(con)[i].targetAddress > NOPs[numOfNopsFounded]; numOfNopsFounded++); CVMJITCSInstructionStack(con)[i].targetAddress -= numOfNopsFounded * sizeof(CVMCPUInstruction); CVMtraceJITCodegen(("fix up instruction @ (%d) to %d\n", CVMJITCSInstructionStack(con)[i].logicalPC, CVMJITCSInstructionStack(con)[i].targetAddress)); CVMJITfixupAddress(con, CVMJITCSInstructionStack(con)[i].logicalPC, CVMJITCSInstructionStack(con)[i].targetAddress, CVMJITCSInstructionStack(con)[i].flags); } else { CVMJITCSInstructionStack(con)[CVMJITcsTopOfInstructions(con)] = CVMJITCSInstructionStack(con)[i]; CVMJITcsTopOfInstructions(con)++; } } CVMJITcsPopNOPInstruction(con); } if (CVMJITcsTopOfInstructions(con) < (MAX_TEMP_INSTRUCTION_BUFFER / sizeof(CVMJITCSPatchInstruction))) { CVMJITCSInstructionStack(con) [CVMJITcsTopOfInstructions(con)].flags = flags; CVMJITCSInstructionStack(con) [CVMJITcsTopOfInstructions(con)].logicalPC = logicalPC; CVMJITCSInstructionStack(con) [CVMJITcsTopOfInstructions(con)].targetAddress = targetAddress; CVMJITcsTopOfInstructions(con)++; } else { /* This should be rare. */ CVMJITerror(con, CANNOT_COMPILE, "CANNOT handle too many patch-necessary instructions"); }}voidCVMJITcsCommitMethod(CVMJITCompilationContext* con)/* * Constant Pool Table is required */{ int i; /* * first scan */ CVMUint32 curLogicalPC; CVMUint32 startAddress; CVMUint32 endAddress; CVMUint32 curConstantPoolEntryIndex; CVMUint32 numberOfConstantPoolEntries; CVMUint32* NOPs; CVMUint32 numOfNopsCounted; CVMJITCSConstantPoolDumpInfo *constantPoolEntries; CVMJITStackmapItem* smap; CVMCPUInstruction* patchedInstructions;#ifdef IAI_CACHEDCONSTANT CVMJITConstantEntry *thisEntry; CVMJITFixupElement *thisRef;#endif #ifdef CVM_TRACE_JIT CVMUint32 numOfNops;#endif CVMJITCSConstantPoolDumpInfo* item; CVMJITcsInitInstructionStack(con); CVMJITcsInitNOPsArray(con); item = CVMJITcsAllocateConstantPoolDumpInfoEntry(con); endAddress = CVMJITcbufGetLogicalPC(con); item->startPC = (CVMUint32)CVMJITcbufGetLogicalPC(con); item->endPC = (CVMUint32)CVMJITcbufGetLogicalPC(con); constantPoolEntries = CVMJITgarrGetElems(con, CVMJITcsConstantPoolArray(con)); numberOfConstantPoolEntries = CVMJITgarrGetNumElems(con, CVMJITcsConstantPoolArray(con)); startAddress = constantPoolEntries[0].startPC; CVMJITcbufGetLogicalPC(con) = constantPoolEntries[0].startPC; for (curConstantPoolEntryIndex = 0; curConstantPoolEntryIndex < numberOfConstantPoolEntries - 1; curConstantPoolEntryIndex++) { for (curLogicalPC = constantPoolEntries[curConstantPoolEntryIndex].endPC; curLogicalPC < constantPoolEntries[curConstantPoolEntryIndex + 1].startPC; curLogicalPC += sizeof(CVMCPUInstruction)) { CVMCPUInstruction* curPhysicalPC = (CVMCPUInstruction*) CVMJITcbufLogicalToPhysical(con, curLogicalPC); CVMCPUInstruction* targetPhysicalPC = (CVMCPUInstruction*) CVMJITcbufLogicalToPhysical(con, CVMJITcbufGetLogicalPC(con)); if (CVMARMisNOP2Instruction(*curPhysicalPC)) { CVMJITcsPushNOPInstruction(con, curLogicalPC); } else { *targetPhysicalPC = *curPhysicalPC; if (CVMARMisBranchInstruction(*curPhysicalPC)) { CVMUint32 targetAddress = CVMARMgetBranchTargetOffsetAddress(*curPhysicalPC) + curLogicalPC + 8; if (targetAddress > startAddress && targetAddress < endAddress) { CVMJITcsPushInstruction(con, CVMJIT_BRANCH_ADDRESS_MODE, CVMJITcbufGetLogicalPC(con), targetAddress); } else { CVMtraceJITCodegen(( "fix up instruction @ (%d,%d) to %d\n", CVMJITcbufGetLogicalPC(con), curLogicalPC, targetAddress)); CVMJITfixupAddress(con, CVMJITcbufGetLogicalPC(con), targetAddress, CVMJIT_BRANCH_ADDRESS_MODE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -