📄 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"/* * 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){ void HAVE_spill_int(sequence*); 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){ void HAVE_reload_int(sequence*); 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){ void HAVE_spill_ref(sequence*); 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){ void HAVE_reload_ref(sequence*); 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){ void HAVE_spill_long(sequence*); 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){ void HAVE_reload_long(sequence*); 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){ void HAVE_spill_float(sequence*); 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){ void HAVE_reload_float(sequence*); 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){ void HAVE_spill_double(sequence*); 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){ void HAVE_reload_double(sequence*); 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, 0, 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 = newLabel(); l->type = Lnull; l->at = 0; l->to = 0; l->from = 0; setupSlotsForBasicBlock(); setupGlobalRegisters(); setupArgumentRegisters(); /* Emit prologue code */ slot_const_const(0, (jword)l, (jword)meth, HAVE_prologue, Tnull); slot_const_const(0, (jword)createSpillMask(), SR_START, doReload, Tnull);}voidcheck_stack_limit(void){#if defined(STACK_LIMIT)#if defined(HAVE_check_stack_limit_constpool) label* l; constpool* c; l = newLabel(); c = newConstant(CPref, soft_stackoverflow); l->type = Lexternal; l->at = 0; l->to = (uintp)c; l->from = 0; slot_slot_const(0, stack_limit, (jword)l, HAVE_check_stack_limit_constpool, Tnull);#elif defined(HAVE_check_stack_limit) label* l; l = newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)soft_stackoverflow; l->from = 0; slot_slot_const(0, stack_limit, (jword)l, HAVE_check_stack_limit, Tnull);#endif#endif /* STACK_LIMIT */}voidexception_prologue(void){ label* l; l = newLabel(); l->type = Lnull; l->at = 0; l->to = 0; l->from = 0; /* Emit exception prologue code */ slot_const_const(0, (jword)l, 0, HAVE_exception_prologue, Tnull); slot_const_const(0, (jword)createSpillMask(), SR_EXCEPTION, doReload, Tnull);}voidepilogue(Method* meth){ label* l; l = newLabel(); l->type = Lnull; /* Lnegframe|Labsolute|Lgeneral */ l->at = 0; l->to = 0; l->from = 0;#if defined(TRACE_METHOD_END) if (Kaffe_JavaVMArgs[0].enableVerboseCall != 0) { begin_func_sync(); call_soft(soft_end); popargs(); end_func_sync(); }#endif slot_const_const(0, (jword)l, 0, HAVE_epilogue, Tnull);}voidret(void){ label *l; l = 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 = newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowLockObject; l->from = 0; if (METHOD_IS_STATIC(meth) == 0) { meth = 0; } else { obj = 0; } slot_slot_slot_const_const(0, 0, 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 = newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowUnlockObject; l->from = 0; if (METHOD_IS_STATIC(meth) == 0) { meth = 0; } else { obj = 0; } slot_slot_slot_const_const(0, 0, 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 = newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowLockObject; l->from = 0; slot_slot_slot_const_const(0, 0, 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 = newLabel(); l->type = Lexternal; l->at = 0; l->to = (uintp)slowUnlockObject; l->from = 0; slot_slot_slot_const_const(0, 0, 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(0, (jword)createSpillMask(), SR_SUBBASIC, doReload, Tnull); setupSlotsForBasicBlock();}void_start_basic_block(void){ _slot_const_const(0, (jword)createSpillMask(), SR_BASIC, doReload, Tnull); setupSlotsForBasicBlock();}void_end_sub_block(void){ mark_all_writes(); _slot_const_const(0, (jword)createSpillMask(), SR_SUBBASIC, doSpill, Tnull);}void_end_basic_block(void){ mark_all_writes(); _slot_const_const(0, (jword)createSpillMask(), SR_BASIC, doSpill, Tnull);}void_syncRegisters(uintp stk, uintp temp){ _slot_const_const(0, (jword)createSpillMask(), SR_SYNC, doSpill, Tnull);}void_start_instruction(uintp pc){ _slot_const_const(0, 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(0, 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 = 0; mark_all_writes();}voidbegin_func_sync(void){ assert(lastSpill == 0); _slot_const_const(0, 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 = 0; /* Create a reload and save the slots to reload */ _slot_const_const(0, (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, 0, val, HAVE_move_int_const, Tconst); } else#endif { constpool *c; label* l; c = newConstant(CPint, val); l = 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, 0, (jword)val, HAVE_move_ref_const, Tconst); } else#endif { constpool *c; label* l; c = newConstant(CPref, val); l = newLabel(); l->type = Lconstant; l->at = 0; l->to = (uintp)c; l->from = 0;#if defined(HAVE_load_constpool_ref) slot_slot_const(dst, 0, (jword)l, HAVE_load_constpool_ref, Tnull);#else { SlotInfo* tmp; slot_alloctmp(tmp); move_label_const(tmp, l); load_ref(dst, tmp); slot_freetmp(tmp); }#endif }}voidmove_string_const(SlotInfo* dst, void *val){#if 1 move_ref_const(dst, val);#else label* l; constpool *c; SlotInfo* tmp; c = newConstant(CPstring, val); l = newLabel(); l->type = Lconstant; l->at = 0; l->to = (uintp)c; l->from = 0;#if defined(HAVE_load_constpool_ref) slot_slot_const(dst, 0, (jword)l, HAVE_load_constpool_ref, Tnull);#else slot_alloctmp(tmp); move_label_const(tmp, l); load_ref(dst, tmp); slot_freetmp(tmp);#endif#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -