jitstackman.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 381 行
C
381 行
/* * @(#)jitstackman.c 1.27 03/11/14 * * 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. *//* * Stack manager implementation. */#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/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"/* SVMC_JIT d022609 (ML) 2004-02-23. rename/move */#include "javavm/include/jit/jitarchemitter.h"#include "javavm/include/jit/jitregman.h"#include "javavm/include/jit/jitstackman.h"#include "javavm/include/clib.h"/* x86 can store a constant */#define CVMCPU_HAS_CONSTANT_STORE/* * Compile-time management of the run-time Java expression and * parameter stack. * There will be target-specific things mixed in here, and they will be * obvious and easy to separate out. * *//* SVMC_JIT *//* define architecture dependent size of a stack slot */#ifdef CVM_64#define SIZE_OF_STACK_SLOT 8#else#define SIZE_OF_STACK_SLOT 4#endifvoidCVMSMinit(CVMJITCompilationContext* con){ con->SMdepth = 0; con->SMmaxDepth = 0;#ifndef CVMCPU_HAS_POSTINCREMENT_STORE con->SMjspOffset = 0;#endif CVMJITsetInit(con, &(con->SMstackRefSet));}voidCVMSMstartBlock(CVMJITCompilationContext* con){ CVMassert(con->SMdepth == 0); CVMJITsetClear(con, &(con->SMstackRefSet));}#ifdef CVM_DEBUG/* * Check for stack sanity */voidCVMSMassertStackTop(CVMJITCompilationContext* con, CVMJITIRNode* expr){ /* Make sure it used to be an invocation */ CVMassert((CVMJITgetOpcode(expr) == (CVMJIT_INVOKE<<CVMJIT_SHIFT_OPCODE)) || (CVMJITgetOpcode(expr)== (CVMJIT_INTRINSIC<<CVMJIT_SHIFT_OPCODE))); /* Make sure that the SMdepth we recorded after pushing it is the * same one we have now. */ CVMassert(expr->type_node.binOp.data == con->SMdepth);}#endif/* * push word(s) to the TOS from the given src register(s). * Adjusts TOS */voidCVMSMpushSingle(CVMJITCompilationContext* con, CVMJITRMContext* rc, CVMRMResource* r){ /* if this is a reference, note the fact */ if (CVMRMisRef(r)){ CVMJITsetAdd(con, &(con->SMstackRefSet), con->SMdepth); } else { CVMJITsetRemove(con, &(con->SMstackRefSet), con->SMdepth); } con->SMdepth += 1; if (con->SMdepth > con->SMmaxDepth) con->SMmaxDepth = con->SMdepth;#ifdef CVMCPU_HAS_CONSTANT_STORE/* SVMC_JIT d022609 (ML) 2004-02-23. CISC architectures do have these. */ if ( CVMRMisConstant( r ) ) {#ifdef CVMCPU_HAS_POSTINCREMENT_STORE CVMCPUemitMemoryReferenceConst(con, CVMRMgetStoreOpcode(rc, r), r->constant, CVMCPU_JSP_REG, CVMCPUmemspecEncodePostIncrementImmediateToken(con, SIZE_OF_STACK_SLOT));#else /* CVMCPU_HAS_POSTINCREMENT_STORE */ CVMCPUemitMemoryReferenceConst(con, CVMRMgetStoreOpcode(rc, r), r->constant, CVMCPU_JSP_REG, CVMCPUmemspecEncodeImmediateToken(con, con->SMjspOffset*SIZE_OF_STACK_SLOT)); con->SMjspOffset += 1;#endif /* CVMCPU_HAS_POSTINCREMENT_STORE */ } else {#endif /* CVMCPU_HAS_CONSTANT_STORE */ if (con->SMdepth > CVMRM_MAX_STACK_LOCATION) { CVMJITlimitExceeded(con, "exceeding max stack locations"); } CVMRMpinResource(rc, r, CVMRM_GET_ANY_SET(rc), CVMRM_EMPTY_SET);#ifdef CVMCPU_HAS_POSTINCREMENT_STORE CVMCPUemitMemoryReference(con, CVMRMgetStoreOpcode(rc, r), CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodePostIncrementImmediateToken(con, SIZE_OF_STACK_SLOT));#else CVMCPUemitMemoryReference(con, CVMRMgetStoreOpcode(rc, r), CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodeImmediateToken(con, con->SMjspOffset*SIZE_OF_STACK_SLOT)); con->SMjspOffset += 1;#endif#ifdef CVMCPU_HAS_CONSTANT_STORE }#endif}voidCVMSMpushDouble( CVMJITCompilationContext* con, CVMJITRMContext* rc, CVMRMResource* r){ CVMassert(!CVMRMisRef(r)); CVMJITsetRemove(con, &(con->SMstackRefSet), con->SMdepth); CVMJITsetRemove(con, &(con->SMstackRefSet), con->SMdepth+1); con->SMdepth += 2; if (con->SMdepth > con->SMmaxDepth) con->SMmaxDepth = con->SMdepth; if (con->SMdepth > CVMRM_MAX_STACK_LOCATION) { CVMJITlimitExceeded(con, "exceeding max stack locations"); } CVMRMpinResource(rc, r, CVMRM_GET_ANY_SET(rc), CVMRM_EMPTY_SET);#ifdef CVM_64 /* get opcode directly from regman context (due to trouble with double words and CVMRMgetStoreOpcode (size mismatch yields wrong opcode)) */#ifdef CVMCPU_HAS_POSTINCREMENT_STORE CVMCPUemitMemoryReference(con, rc->storeOpcode[ 1 ], CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodePostIncrementImmediateToken(con, 2 * SIZE_OF_STACK_SLOT ));#else /* CVMCPU_HAS_POSTINCREMENT_STORE */ CVMCPUemitMemoryReference(con, rc->storeOpcode[ 1 ], CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodeImmediateToken(con, con->SMjspOffset * SIZE_OF_STACK_SLOT )); con->SMjspOffset += 2;#endif /* CVMCPU_HAS_POSTINCREMENT_STORE */#else /* CVM_64 */#ifdef CVMCPU_HAS_POSTINCREMENT_STORE CVMCPUemitMemoryReference(con, CVMRMgetStoreOpcode(rc, r), CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodePostIncrementImmediateToken(con, 2 * SIZE_OF_STACK_SLOT ));#else /* CVMCPU_HAS_POSTINCREMENT_STORE */ CVMCPUemitMemoryReference(con, CVMRMgetStoreOpcode(rc, r), CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodeImmediateToken(con, con->SMjspOffset * SIZE_OF_STACK_SLOT )); con->SMjspOffset += 2;#endif /* CVMCPU_HAS_POSTINCREMENT_STORE */#endif /* CVM_64 */}voidCVMSMpopParameters(CVMJITCompilationContext* con, CVMUint16 numberOfArgs){ con->SMdepth -= numberOfArgs; CVMassert(con->SMdepth >= 0);}/* * Make JSP point just past the last argument. This is only needed when * postincrement stores are not supported. In this case we defer making * any stack adjustments until we are ready to make the method call. */#ifndef CVMCPU_HAS_POSTINCREMENT_STOREextern voidCVMSMadjustJSP(CVMJITCompilationContext* con){ if (con->SMjspOffset != 0) { CVMJITaddCodegenComment((con, "adjust JSP before method call")); CVMCPUemitBinaryALUConstant(con, CVMCPU_ADD_OPCODE, CVMCPU_JSP_REG, CVMCPU_JSP_REG, con->SMjspOffset*SIZE_OF_STACK_SLOT, CVMJIT_NOSETCC); con->SMjspOffset = 0; }}#endif/* * Record the effect on the stack of the method call. Returns a * CVMRMResource which is stack bound. */CVMRMResource*CVMSMinvocation(CVMJITCompilationContext* con, CVMJITIRNode* invokeNode){ int typetag = CVMJITgetTypeTag(invokeNode); int resultWords = 1; CVMJITRMContext* regCon; switch (typetag){ case CVM_TYPEID_VOID: return NULL; case CVM_TYPEID_OBJ: CVMJITsetAdd(con, &(con->SMstackRefSet), con->SMdepth); con->SMdepth += 1; break; case CVM_TYPEID_DOUBLE: case CVM_TYPEID_LONG: resultWords = 2; CVMJITsetRemove(con, &(con->SMstackRefSet), con->SMdepth); con->SMdepth += 1; /* FALLTHRU */ default: /* includes int, float */ CVMJITsetRemove(con, &(con->SMstackRefSet), con->SMdepth); con->SMdepth += 1; break; } #ifdef CVM_JIT_USE_FP_HARDWARE switch (typetag){ case CVM_TYPEID_FLOAT: case CVM_TYPEID_DOUBLE: regCon = CVMRM_FP_REGS(con); break; default: regCon = CVMRM_INT_REGS(con); break; }#else /* CVM_JIT_USE_FP_HARDWARE */ regCon = CVMRM_INT_REGS(con);#endif /* CVM_JIT_USE_FP_HARDWARE */#ifdef CVM_DEBUG CVMJITirnodeGetBinaryOp(invokeNode)->data = con->SMdepth;#endif if (con->SMdepth > con->SMmaxDepth) con->SMmaxDepth = con->SMdepth; if (con->SMdepth > CVMRM_MAX_STACK_LOCATION) { CVMJITlimitExceeded(con, "exceeding max stack locations"); } return CVMRMbindStackTempToResource(regCon, invokeNode, resultWords);}static voidphysicalStackAdjust(CVMJITCompilationContext* con, int n){ CVMCPUemitBinaryALUConstant(con, CVMCPU_SUB_OPCODE, CVMCPU_JSP_REG, CVMCPU_JSP_REG, n, CVMJIT_NOSETCC);}/* * pop "size" words from the TOS into the given dest register(s). * If r == NULL then just adjust JSP without the memory fetch. * Adjusts TOS. * NOTE: The resource r must be of type JavaStackTopValue. */voidCVMSMpopSingle( CVMJITCompilationContext* con, CVMRMResource* r){ int opcode; con->SMdepth -= 1; CVMassert(con->SMdepth >= 0); if (r == NULL){ physicalStackAdjust(con, SIZE_OF_STACK_SLOT); return; }#ifdef CVM_DEBUG_ASSERTS { CVMBool isRef; CVMJITsetContains(&con->SMstackRefSet, con->SMdepth, isRef); CVMassert(r == NULL || CVMRMisRef(r) == isRef); }#endif opcode = CVMRMgetLoadOpcode(r->rmContext, r); /* Register already pinned for us, just issue the load */ CVMassert(CVMRMisJavaStackTopValue(r)); CVMCPUemitMemoryReference(con, opcode, CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodePreDecrementImmediateToken(con, SIZE_OF_STACK_SLOT));}voidCVMSMpopDouble( CVMJITCompilationContext* con, CVMRMResource* r){ int opcode; con->SMdepth -= 2; CVMassert(con->SMdepth >= 0); if (r == NULL){ physicalStackAdjust(con, 2 * SIZE_OF_STACK_SLOT); return; } /* Registers already pinned for us, just issue the loads */ opcode = CVMRMgetLoadOpcode(r->rmContext, r); CVMassert(CVMRMisJavaStackTopValue(r)); CVMCPUemitMemoryReference(con, opcode, CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, CVMCPUmemspecEncodePreDecrementImmediateToken(con, 2 * SIZE_OF_STACK_SLOT));}/* Purpose: Fetches a word from the java stack into a register without adjusting the stack pointer. *//* * Get "size" words from the stack locations corresponding to the specified * resources into the given dest register(s). * CVMSMgetSingle for all single-word data types, including ref's * CVMSMgetDouble for both double-word types. * NOTE: The resource r must be of type StackParam. */voidCVMSMgetSingle(CVMJITCompilationContext *con, CVMRMResource *r){ int offset; CVMassert(con->SMdepth >= r->stackLoc); CVMassert(CVMRMisStackParam(r)); offset = ((r->stackLoc - con->SMdepth) * 4) - SIZE_OF_STACK_SLOT; /* Register already pinned for us, just issue the load: */ CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDR32_OPCODE, CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, offset);}voidCVMSMgetDouble(CVMJITCompilationContext *con, CVMRMResource *r){ int offset; CVMassert(con->SMdepth >= r->stackLoc); CVMassert(CVMRMisStackParam(r)); offset = ((r->stackLoc - con->SMdepth) * 4) - ( 2 * SIZE_OF_STACK_SLOT ); /* Registers already pinned for us, just issue the loads: */ CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDR64_OPCODE, CVMRMgetRegisterNumber(r), CVMCPU_JSP_REG, offset);}#undef SIZE_OF_STACK_SLOT
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?