📄 icode.c
字号:
/* icode.c * Define the instructions. * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-mem.h"#include "gtypes.h"#include "slots.h"#include "seq.h"#include "md.h"#include "registers.h"#include "basecode.h"#include "labels.h"#include "constpool.h"#include "icode.h"#include "soft.h"#include "access.h"#include "object.h"#include "constants.h"#include "classMethod.h"#include "gc.h"#include "itypes.h"#include "locks.h"#include "machine.h"#include "codeproto.h"#include "thread.h"#include "jthread.h"#include "support.h"#include "code-analyse.h"#include "funcs.h"#include "kaffe_jni.h"#include "fp.h"#include "global-regs.h"#if defined(HAVE_branch_and_link)#define blink 0x8000000#else#define blink 0#endif/* * This flag can turn off array bounds checking. * - for experimental purposes only. */int noArrayBoundsChecks = 0;#if defined(WORDS_BIGENDIAN)#define LSLOT(_s) ((_s)+1)#define HSLOT(_s) (_s)#else#define LSLOT(_s) (_s)#define HSLOT(_s) ((_s)+1)#endifbool used_ieee_rounding;bool used_ieee_division;sequence* lastSpill;#define MAXLABTAB 64label* labtab[MAXLABTAB];static void _call_soft(void *routine, int profiled);/* ----------------------------------------------------------------------- *//* Register loads and spills. *//* */#if defined(HAVE_spill_int)voidspill_int(SlotData* src){ sequence s; seq_dst(&s) = src; seq_value(&s, 1) = slotOffsetNoSpill(src, Rint); HAVE_spill_int(&s);}#endif#if defined(HAVE_reload_int)voidreload_int(SlotData* dst){ sequence s; seq_dst(&s) = dst; seq_value(&s, 1) = slotOffsetNoSpill(dst, Rint); HAVE_reload_int(&s);}#endif#if defined(HAVE_spill_ref)voidspill_ref(SlotData* src){ sequence s; seq_dst(&s) = src; seq_value(&s, 1) = slotOffsetNoSpill(src, Rref); HAVE_spill_ref(&s);}#endif#if defined(HAVE_reload_ref)voidreload_ref(SlotData* dst){ sequence s; seq_dst(&s) = dst; seq_value(&s, 1) = slotOffsetNoSpill(dst, Rref); HAVE_reload_ref(&s);}#endif#if defined(HAVE_spill_long)voidspill_long(SlotData* src){ sequence s; seq_dst(&s) = src; seq_value(&s, 1) = slotOffsetNoSpill(src, Rlong); HAVE_spill_long(&s);}#endif#if defined(HAVE_reload_long)voidreload_long(SlotData* dst){ sequence s; seq_dst(&s) = dst; seq_value(&s, 1) = slotOffsetNoSpill(dst, Rlong); HAVE_reload_long(&s);}#endif#if defined(HAVE_spill_float)voidspill_float(SlotData* src){ sequence s; seq_dst(&s) = src; seq_value(&s, 1) = slotOffsetNoSpill(src, Rfloat); HAVE_spill_float(&s);}#endif#if defined(HAVE_reload_float)voidreload_float(SlotData* dst){ sequence s; seq_dst(&s) = dst; seq_value(&s, 1) = slotOffsetNoSpill(dst, Rfloat); HAVE_reload_float(&s);}#endif#if defined(HAVE_spill_double)voidspill_double(SlotData* src){ sequence s; seq_dst(&s) = src; seq_value(&s, 1) = slotOffsetNoSpill(src, Rdouble); HAVE_spill_double(&s);}#endif#if defined(HAVE_reload_double)voidreload_double(SlotData* dst){ sequence s; seq_dst(&s) = dst; seq_value(&s, 1) = slotOffsetNoSpill(dst, Rdouble); HAVE_reload_double(&s);}#endifvoidcopyslots(SlotInfo* dst, SlotInfo* src, int type){ slot_slot_slot(dst, NULL, src, slotAlias, Tcopy); activeSeq->u[1].value.i = type;}voidcopylslots(SlotInfo* dst, SlotInfo* src, int type){ lslot_lslot_lslot(dst, NULL, src, slotAlias, Tcopy); activeSeq->u[1].value.i = type;}/* ----------------------------------------------------------------------- *//* Prologues and epilogues. *//* */voidprologue(Method* meth){ label* l; used_ieee_rounding = false; used_ieee_division = false; l = KaffeJIT3_newLabel(); l->type = Lnull; l->at = 0; l->to = 0; l->from = 0; setupSlotsForBasicBlock();#if defined(NR_GLOBALS) setupGlobalRegisters();#endif setupArgumentRegisters(); /* Emit prologue code */ slot_const_const(NULL, (jword)l, (jword)meth, HAVE_prologue, Tnull); slot_const_const(NULL, (jword)createSpillMask(), SR_START, doReload, Tnull); #if defined(ENABLE_JVMPI) { SlotInfo *tmp; slot_alloctmp(tmp); if( METHOD_IS_STATIC(meth) ) move_ref_const(tmp, NULL); else move_ref(tmp, local(0)); softcall_enter_method(tmp, meth); slot_freetmp(tmp); }#endif}voidcheck_stack_limit(void){#if defined(STACK_LIMIT)#if defined(HAVE_check_stack_limit_constpool) label* l; constpool* c; l = KaffeJIT3_newLabel(); c = KaffeJIT3_newConstant(CPref, soft_stackoverflow); l->type = Lexternal; l->at = 0; l->to = (uintp)c; l->from = 0; slot_slot_const(NULL, stack_limit, (jword)l, HAVE_check_stack_limit_constpool, Tnull);#elif defined(HAVE_check_stack_limit) label* l; l = KaffeJIT3_newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)soft_stackoverflow; l->from = 0; slot_slot_const(NULL, stack_limit, (jword)l, HAVE_check_stack_limit, Tnull);#endif#endif /* STACK_LIMIT */}voidexception_prologue(void){ label* l; l = KaffeJIT3_newLabel(); l->type = Lnull; l->at = 0; l->to = 0; l->from = 0; /* Emit exception prologue code */ slot_const_const(NULL, (jword)l, 0, HAVE_exception_prologue, Tnull); slot_const_const(NULL, (jword)createSpillMask(), SR_EXCEPTION, doReload, Tnull);}voidepilogue(Method* meth UNUSED){ label* l; l = KaffeJIT3_newLabel(); l->type = Lnull; /* Lnegframe|Labsolute|Lgeneral */ l->at = 0; l->to = 0; l->from = 0;#if defined(TRACE_METHOD_END) if (Kaffe_JavaVMArgs.enableVerboseCall != 0) { begin_func_sync(); call_soft(soft_end); popargs(); end_func_sync(); }#endif slot_const_const(NULL, (jword)l, 0, HAVE_epilogue, Tnull);}voidexit_method(void){#if defined(ENABLE_JVMPI) softcall_exit_method(globalMethod);#endif}voidret(void){ label *l; l = KaffeJIT3_newLabel(); l->at = 0; l->to = 0; l->from = 0; /* Jump to epilogue */ l->type = Lepilogue; branch (l, ba);}/* ----------------------------------------------------------------------- *//* Conditional monitor management. *//* */voidmon_enter(methods* meth, SlotInfo* obj){ /* Emit monitor entry if required */ if ((meth->accflags & ACC_SYNCHRONISED) == 0) { return; }#if defined(HAVE_mon_enter) { label* l; begin_func_sync(); l = KaffeJIT3_newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowLockObject; l->from = 0; if (METHOD_IS_STATIC(meth) == 0) { meth = NULL; } else { obj = NULL; } slot_slot_slot_const_const(NULL, NULL, obj, (jword)meth, (jword)l, HAVE_mon_enter, Tnull); end_func_sync(); }#else begin_func_sync(); if ((meth->accflags & ACC_STATIC) != 0) { pusharg_class_const(meth->class, 0); } else { pusharg_ref(obj, 0); } call_soft(lockObject); popargs(); end_func_sync();#endif}voidmon_exit(methods* meth, SlotInfo* obj){ /* Emit monitor entry if required */ if ((meth->accflags & ACC_SYNCHRONISED) == 0) { return; }#if defined(HAVE_mon_exit) { label* l; begin_func_sync(); l = KaffeJIT3_newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowUnlockObject; l->from = 0; if (METHOD_IS_STATIC(meth) == 0) { meth = NULL; } else { obj = NULL; } slot_slot_slot_const_const(NULL, NULL, obj, (jword)meth, (jword)l, HAVE_mon_exit, Tnull); end_func_sync(); }#else begin_func_sync(); if (METHOD_IS_STATIC(meth) != 0) { pusharg_class_const(meth->class, 0); } else { pusharg_ref(obj, 0); } call_soft(unlockObject); popargs(); end_func_sync();#endif}voidsoftcall_monitorenter(SlotInfo* mon){#if defined(HAVE_mon_enter) label* l; l = KaffeJIT3_newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowLockObject; l->from = 0; slot_slot_slot_const_const(NULL, NULL, mon, 0, (jword)l, HAVE_mon_enter, Tnull);#else pusharg_ref(mon, 0); call_soft(lockObject); popargs();#endif}voidsoftcall_monitorexit(SlotInfo* mon){#if defined(HAVE_mon_exit) label* l; l = KaffeJIT3_newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowUnlockObject; l->from = 0; slot_slot_slot_const_const(NULL, NULL, mon, 0, (jword)l, HAVE_mon_exit, Tnull);#else pusharg_ref(mon, 0); call_soft(unlockObject); popargs();#endif}/* ----------------------------------------------------------------------- *//* Basic block and instruction management. *//* */voidmark_all_writes(void){ int i; SlotData* sd; /* We must reference all slots sequence since they may be used */ for (i = maxslot - 1; i >= 0; i--) { sd = slotinfo[i].slot; if (sd->wseq != 0) { sd->wseq->refed = 1; } }}void_start_sub_block(void){ slot_const_const(NULL, (jword)createSpillMask(), SR_SUBBASIC, doReload, Tnull); setupSlotsForBasicBlock();}void_start_basic_block(void){ slot_const_const(NULL, (jword)createSpillMask(), SR_BASIC, doReload, Tnull); setupSlotsForBasicBlock();}void_end_sub_block(void){ mark_all_writes(); slot_const_const(NULL, (jword)createSpillMask(), SR_SUBBASIC, doSpill, Tnull);}void_end_basic_block(void){ mark_all_writes(); slot_const_const(NULL, (jword)createSpillMask(), SR_BASIC, doSpill, Tnull);}void_syncRegisters(uintp stk UNUSED, uintp temp UNUSED){ slot_const_const(NULL, (jword)createSpillMask(), SR_SYNC, doSpill, Tnull);}void_start_instruction(uintp _pc){ slot_const_const(NULL, 0, _pc, startInsn, Tnull);}void_start_exception_block(uintp stk){ /* Exception blocks act like function returns - the return * value is the exception object. */ start_basic_block(); exception_prologue(); return_ref(&localinfo[stk]);}/* * Begin a register/slot syncronization - this is the point we will * store all our cached values back to where they belong. We don't know * which values to store yet - this is decided at the end_sync point. */voidbegin_sync(void){ assert(lastSpill == 0); slot_const_const(NULL, 0, SR_BASIC, doSpill, Tnull); lastSpill = activeSeq;}voidend_sync(void){ /* Make sure a sync is in progress */ assert(lastSpill != 0); lastSpill->u[1].smask = createSpillMask(); lastSpill = NULL; mark_all_writes();}voidbegin_func_sync(void){ assert(lastSpill == 0); slot_const_const(NULL, 0, SR_FUNCTION, doSpill, Tnull); lastSpill = activeSeq; /* If we might throw and catch and exception we better make everything * is written which should be. */ if (canCatch(ANY)) { mark_all_writes(); }}voidend_func_sync(void){ SlotData** mask; /* Build a mask of the slots to spill and reload */ mask = createSpillMask(); /* Save the slots to spill */ assert(lastSpill != 0); lastSpill->u[1].smask = mask; lastSpill = NULL; /* Create a reload and save the slots to reload */ slot_const_const(NULL, (jword)mask, SR_FUNCTION, doReload, Tnull);}/* ----------------------------------------------------------------------- *//* Moves. *//* */voidmove_int_const(SlotInfo* dst, jint val){#if defined(HAVE_move_int_const) if (HAVE_move_int_const_rangecheck(val)) { slot_slot_const(dst, NULL, val, HAVE_move_int_const, Tconst); } else#endif { constpool *c; label* l; c = KaffeJIT3_newConstant(CPint, val); l = KaffeJIT3_newLabel(); l->type = Lconstant; l->at = 0; l->to = (uintp)c; l->from = 0;#if defined(HAVE_load_constpool_int) slot_slot_const(dst, 0, (jword)l, HAVE_load_constpool_int, Tnull);#else { SlotInfo* tmp; slot_alloctmp(tmp); move_label_const(tmp, l); load_int(dst, tmp); slot_freetmp(tmp); }#endif }}voidmove_ref_const(SlotInfo* dst, void *val){#if defined(HAVE_move_ref_const) if (HAVE_move_ref_const_rangecheck(val)) { slot_slot_const(dst, NULL, (jword)val, HAVE_move_ref_const, Tconst); } else#endif { constpool *c; label* l; c = KaffeJIT3_newConstant(CPref, val); l = KaffeJIT3_newLabel(); l->type = Lconstant; l->at = 0; l->to = (uintp)c; l->from = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -