[svn:parrot] r41312 - in branches/kill_jit: . config/gen/makefiles src src/jit tools/build
darbelo at svn.parrot.org
darbelo at svn.parrot.org
Thu Sep 17 04:30:27 UTC 2009
Author: darbelo
Date: Thu Sep 17 04:30:13 2009
New Revision: 41312
URL: https://trac.parrot.org/parrot/changeset/41312
Log:
JIT is dead, except for the bit necessary to sustain JIT frames in x86.
The bits in src/frame_builder.c and src/frame_builder.h are DISTILLED EVIL and nead to be cleaned up.
Linux x86 passes make test.
Added:
branches/kill_jit/src/frame_builder.c (contents, props changed)
- copied, changed from r41310, branches/kill_jit/src/jit/i386/jit_defs.c
branches/kill_jit/src/frame_builder.h (contents, props changed)
- copied, changed from r41310, branches/kill_jit/src/jit/i386/jit_emit.h
Deleted:
branches/kill_jit/src/jit/
branches/kill_jit/src/jit.c
branches/kill_jit/src/jit.h
branches/kill_jit/src/jit_debug.c
branches/kill_jit/src/jit_debug_xcoff.c
Modified:
branches/kill_jit/MANIFEST
branches/kill_jit/config/gen/makefiles/root.in
branches/kill_jit/src/embed.c
branches/kill_jit/src/packfile.c
branches/kill_jit/tools/build/nativecall.pl
Modified: branches/kill_jit/MANIFEST
==============================================================================
--- branches/kill_jit/MANIFEST Thu Sep 17 03:08:51 2009 (r41311)
+++ branches/kill_jit/MANIFEST Thu Sep 17 04:30:13 2009 (r41312)
@@ -1,7 +1,7 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Sep 16 21:14:43 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Thu Sep 17 04:23:40 2009 UT
#
# See below for documentation on the format of this file.
#
@@ -1279,6 +1279,8 @@
src/exec_start.c []
src/exit.c []
src/extend.c []
+src/frame_builder.c []
+src/frame_builder.h []
src/gc/alloc_memory.c []
src/gc/alloc_resources.c []
src/gc/api.c []
@@ -1310,15 +1312,6 @@
src/io/unix.c []
src/io/utf8.c []
src/io/win32.c []
-src/jit.c []
-src/jit.h []
-src/jit/i386/core.jit []
-src/jit/i386/exec_dep.c []
-src/jit/i386/exec_dep.h []
-src/jit/i386/jit_defs.c []
-src/jit/i386/jit_emit.h []
-src/jit_debug.c []
-src/jit_debug_xcoff.c []
src/key.c []
src/libnci_test.def []
src/library.c []
Modified: branches/kill_jit/config/gen/makefiles/root.in
==============================================================================
--- branches/kill_jit/config/gen/makefiles/root.in Thu Sep 17 03:08:51 2009 (r41311)
+++ branches/kill_jit/config/gen/makefiles/root.in Thu Sep 17 04:30:13 2009 (r41312)
@@ -1188,7 +1188,7 @@
$(SRC_DIR)/pmc/pmc_nci.h \
$(SRC_DIR)/pmc/pmc_pointer.h
-#IF(can_build_call_frames):$(SRC_DIR)/frame_builder$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/frame_builder.c $(SRC_DIR)/frame_builder.str
+#IF(can_build_call_frames):$(SRC_DIR)/frame_builder$(O) : $(SRC_DIR)/frame_builder.h $(GENERAL_H_FILES) $(SRC_DIR)/frame_builder.c $(SRC_DIR)/frame_builder.str
$(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c
Modified: branches/kill_jit/src/embed.c
==============================================================================
--- branches/kill_jit/src/embed.c Thu Sep 17 03:08:51 2009 (r41311)
+++ branches/kill_jit/src/embed.c Thu Sep 17 04:30:13 2009 (r41312)
@@ -80,13 +80,6 @@
*/
-#ifdef JIT_CAPABLE
-# if EXEC_CAPABLE
-# include "parrot/exec.h"
-# endif /* EXEC_CAPABLE */
-# include "jit.h"
-#endif
-
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
Parrot_Interp
@@ -571,8 +564,8 @@
if (!(pf->options & PFOPT_HEADERONLY))
do_sub_pragmas(interp, pf->cur_cs, PBC_PBC, NULL);
- /* JITting and/or prederefing the sub/the bytecode is done
- * in switch_to_cs before actual usage of the segment */
+ /* Prederefing the sub/the bytecode is done in switch_to_cs before
+ * actual usage of the segment */
#ifdef PARROT_HAS_HEADER_SYSMMAN
/* the man page states that it's ok to close a mmaped file */
Copied and modified: branches/kill_jit/src/frame_builder.c (from r41310, branches/kill_jit/src/jit/i386/jit_defs.c)
==============================================================================
--- branches/kill_jit/src/jit/i386/jit_defs.c Wed Sep 16 23:13:30 2009 (r41310, copy source)
+++ branches/kill_jit/src/frame_builder.c Thu Sep 17 04:30:13 2009 (r41312)
@@ -6,15 +6,26 @@
/* HEADERIZER HFILE: none */
/* HEADERIZER STOP */
-#include <assert.h>
#include "parrot/parrot.h"
-#include "parrot/hash.h"
-#include "parrot/oplib/ops.h"
#include "pmc/pmc_fixedintegerarray.h"
#include "pmc/pmc_unmanagedstruct.h"
-#include "pmc/pmc_pointer.h"
-#include "jit.h"
-#include "jit_emit.h"
+#include "frame_builder.h"
+
+void
+Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)
+{
+ Parrot_jit_fixup_t *fixup;
+
+ fixup = mem_allocate_zeroed_typed(Parrot_jit_fixup_t);
+
+ /* Insert fixup at the head of the list */
+ fixup->next = jit_info->arena.fixups;
+ jit_info->arena.fixups = fixup;
+
+ /* Fill in the native code offset */
+ fixup->native_offset =
+ (ptrdiff_t)(jit_info->native_ptr - jit_info->arena.start);
+}
INTVAL
get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
@@ -892,7 +903,7 @@
Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info,
PARROT_INTERP, int n, int *args)
{
- int nvtable = op_jit[*jit_info->cur_op].extcall;
+ int nvtable = NULL; /*op_jit[*jit_info->cur_op].extcall;*/
size_t offset;
op_info_t *op_info = &interp->op_info_table[*jit_info->cur_op];
int pi;
@@ -966,17 +977,11 @@
&interp->code->const_table->
constants[pi]->u.number);
store:
-#if NUMVAL_SIZE == 8
/* make room for double */
emitm_addb_i_r(jit_info->native_ptr, -8, emit_ESP);
emitm_fstpl(interp, jit_info->native_ptr, emit_ESP, emit_None, 1, 0);
/* additional stack adjustment */
st += 4;
-#else
- emitm_addb_i_r(jit_info->native_ptr, -12, emit_ESP);
- emitm_fstpt(jit_info->native_ptr, emit_ESP, emit_None, 1, 0);
- st += 8;
-#endif
break;
case PARROT_ARG_SC:
@@ -1579,84 +1584,6 @@
int control_word = 0x27f;
-#ifdef JIT_CGP
-
-/*
- * This is the somewhat complicated program flow
- *
- * JIT code prederef code
- * 1) jit_begin
- * stack_enter
- * call cgp_core --> set stack frame
- * jump to retaddr
- * test EAX, 0 <-- also from HALT
- * jnz code_start
- * stack_leave
- * ret
- * code_start: of JIT code
- * jit code
- * ....
- *
- * 2) normal_op
- * mov prederef_code_ptr, esi
- * call *(esi) ----> prederefed (non JITted code)
- * ....
- * .... <---- ret
- * jit_code
- * ....
- * 3) HALT == jit_end
- * mov prederefed_op_func[0], esi
- * jump *esi -----> cleanup prederef stack frame
- * xor eax,eax ; return 0
- * ret (--> after call cgp_core in 1)
- *
- */
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- jit_emit_stack_frame_enter(jit_info->native_ptr);
- emitm_fldcw(interp, jit_info->native_ptr, &control_word);
- emitm_pushl_r(jit_info->native_ptr, emit_EBX);
- /* get the pc from stack: mov 12(%ebp), %ebx */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBP, emit_None, 1, 12);
- /* emit cgp_core(1, interp) */
- /* get the interpreter from stack: mov 8(%ebp), %eax */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 8);
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
- /*
- * TODO define the offset of the interpreter on the stack
- * relative to %ebp
- */
- emitm_pushl_i(jit_info->native_ptr, 1);
- /* use EAX as flag, when jumping back on init, EAX==1 */
- jit_emit_mov_ri_i(interp, jit_info->native_ptr, emit_EAX, 1);
- if (!jit_info->objfile)
- call_func(jit_info, (void (*)(void))cgp_core);
-# if EXEC_CAPABLE
- else {
- Parrot_exec_add_text_rellocation_func(jit_info->objfile,
- jit_info->native_ptr, "cgp_core");
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
- }
-# endif
- /* when cur_opcode == 1, cgp_core jumps back here
- * when EAX == 0, the official return from HALT was called */
- jit_emit_test_r_i(jit_info->native_ptr, emit_EAX);
- emitm_jxs(jit_info->native_ptr, emitm_jnz, 5);
- emitm_popl_r(jit_info->native_ptr, emit_EBX);
- jit_emit_stack_frame_leave(jit_info->native_ptr);
- emitm_ret(jit_info->native_ptr);
- /* get PC = ebx to eax, jump there */
- jit_emit_mov_rr_i(jit_info->native_ptr, emit_EAX, emit_EBX);
- Parrot_emit_jump_to_eax(jit_info, interp);
-
-/* code_start: */
-}
-
-#else /* JIT_CGP */
-
void
Parrot_jit_begin(Parrot_jit_info_t *jit_info,
PARROT_INTERP)
@@ -1701,8 +1628,6 @@
Parrot_emit_jump_to_eax(jit_info, interp);
}
-#endif /* JIT_CGP */
-
/*
* create a JITted version of a PIR sub, where everything
* resided in registers
@@ -1825,76 +1750,6 @@
jit_emit_finit(jit_info->native_ptr);
}
-#ifdef JIT_CGP
-/*
- * XXX needs some fixing
- * s. t/sub/pmc_{8,9}.t: the 2 print in tail call without that 'end'
- * are recognized as one non JITted block
- */
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_optimizer_section_ptr cur_section =
- jit_info->optimizer->cur_section;
- int last_is_branch = 0;
- void ** offset;
-
- PARROT_ASSERT(op_jit[*jit_info->cur_op].extcall == 1);
- if (cur_section->done == 1)
- return;
- else if (cur_section->done == -1 && --cur_section->ins_count > 0)
- return;
- /* check, where section ends
- */
- if (interp->op_info_table[*cur_section->end].jump)
- last_is_branch = 1;
- else if (cur_section->next && !cur_section->next->isjit)
- last_is_branch = 1;
- /* if more then 1 op, then jump to CGP, branches are never
- * executed in CGP, they are handled below */
- if (cur_section->done >= 0 &&
- (INTVAL)cur_section->op_count >= 2 + last_is_branch) {
- int saved = 0;
- offset = (jit_info->cur_op - interp->code->base.data) +
- interp->code->prederef.code;
-
- jit_emit_mov_ri_i(interp, jit_info->native_ptr, emit_ESI, offset);
- emitm_callm(jit_info->native_ptr, emit_ESI, 0, 0, 0);
- /* now patch a B<cpu_ret> opcode after the end of the
- * prederefed (non JIT) section */
- if (last_is_branch) {
- offset = (cur_section->end - interp->code->base.data) +
- interp->code->prederef.code;
- cur_section->done = -1;
- /* ins to skip */
- cur_section->ins_count = cur_section->op_count - 1;
- }
- else {
- /* There must be a next section: either we have a B<end>
- * or a JITed branch,
- * when the branch is non JIT, we are in the above case
- */
- offset = (cur_section->next->begin - interp->code->base.data)
- + interp->code->prederef.code;
- cur_section->done = 1;
- }
- *offset = ((op_func_t*)interp->op_lib->op_func_table)[PARROT_OP_cpu_ret];
- }
- else {
- /* else call normal funtion */
- emitm_pushl_i(jit_info->native_ptr, interp);
- emitm_pushl_i(jit_info->native_ptr, jit_info->cur_op);
- call_func(jit_info,
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)]);
- emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
- /* when this was a branch, then EAX is now the offset
- * in the byte_code
- */
- }
-}
-
-#else /* JIT_CGP */
extern int jit_op_count(void);
void
@@ -1904,10 +1759,10 @@
int cur_op = *jit_info->cur_op;
static int check;
- if (cur_op >= jit_op_count()) {
+/* if (cur_op >= jit_op_count()) {
cur_op = CORE_OPS_wrapper__;
}
-
+*/
if ((++check & 0x7) == 0) {
/*
* every 8 ??? normal ops, we emit a check for event processing
@@ -1963,8 +1818,6 @@
# endif
}
-#endif /* JIT_CGP */
-
void
Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
PARROT_INTERP)
@@ -2425,70 +2278,6 @@
return (void *)D2FPTR(jit_info.arena.start);
}
-const char i_map[] =
- { emit_EDI, emit_ESI, emit_EDX, emit_ECX };
-const char floatval_map[] =
- { 1, 2, 3, 4, 5 }; /* ST(1) .. (ST(4) */
-
-const char i_map_sub[] =
- { emit_EDX, emit_ECX, emit_EBX, emit_EDI, emit_ESI };
-
-const jit_arch_info arch_info = {
- jit_mov_rm_offs,
- jit_mov_rm_n_offs,
- jit_mov_mr_offs,
- jit_mov_mr_n_offs,
- Parrot_jit_dofixup,
- (jit_arch_f)0, /* no cache flush needed */
- {
- {
- Parrot_jit_begin, /* emit code prologue */
- 4, /* 4 mapped ints */
- 2, /* first 2 are preserved */
- i_map,
- 4, /* 4 mapped float regs */
- 0, /* ABI sez it's not preserved */
- floatval_map
- },
- /* unused */
- {
- Parrot_jit_begin_sub, /* emit code prologue */
- 4, /* 4 mapped ints */
- 2, /* first 2 are *non*preserved */
- i_map_sub,
- 4, /* 4 mapped float regs */
- 0, /* ABI sez it's not preserved */
- floatval_map
- },
- /*
- * compile a sub to registers only
- * if a mapped count is 0, code containing this register kind
- * will not be created
- *
- * TODO implement FLOATVAL arg passing and set mapped
- * register count.
- */
- {
- Parrot_jit_begin_sub_regs, /* emit code prologue */
- 5, /* 5 mapped ints */
- 2, /* first 2 are *non*preserved */
- i_map_sub,
- 5, /* TODO 0 mapped float regs */
- 5, /* ABI sez it's not preserved */
- floatval_map
- }
- }
-};
-
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info *
-Parrot_jit_init(PARROT_INTERP)
-{
- return &arch_info;
-}
-
/*
* Local variables:
* c-file-style: "parrot"
Copied and modified: branches/kill_jit/src/frame_builder.h (from r41310, branches/kill_jit/src/jit/i386/jit_emit.h)
==============================================================================
--- branches/kill_jit/src/jit/i386/jit_emit.h Wed Sep 16 23:13:30 2009 (r41310, copy source)
+++ branches/kill_jit/src/frame_builder.h Thu Sep 17 04:30:13 2009 (r41312)
@@ -24,6 +24,309 @@
#include "parrot/hash.h"
#include "parrot/oplib/ops.h"
+/* Parrot_jit_fixup_t
+ * Platform generic fixup information
+ *
+ * type: The type of fixup.
+ * native_offset: Where to apply the fixup.
+ * skip: Skip instructions after the target.
+ * param: Fixup specific data.
+ */
+
+typedef struct Parrot_jit_fixup *Parrot_jit_fixup_ptr;
+
+typedef struct Parrot_jit_fixup {
+ int type;
+ ptrdiff_t native_offset;
+ char skip;
+ char dummy[3]; /* For alignment ??? XXX */
+ union { /* What has to align with what? */
+ opcode_t opcode;
+ void (*fptr)(void);
+ } param;
+
+ Parrot_jit_fixup_ptr next;
+} Parrot_jit_fixup_t;
+
+/* Parrot_jit_opmap_t
+ * Hold native code offsets/addresses
+ *
+ * ptr: Pointer to native code
+ * offset: Offset of native code from arena.start
+ */
+
+typedef union {
+ void *ptr;
+ ptrdiff_t offset;
+} Parrot_jit_opmap_t;
+
+enum {
+ JIT_BRANCH_NO, /* The opcode doesn't branch */
+ JIT_BRANCH_TARGET, /* The opcode is a branch target */
+ JIT_BRANCH_SOURCE /* The opcode is a branch source */
+};
+
+
+/* Parrot_jit_arena_t
+ * Holds pointers to the native code of one or more sections.
+ *
+ * start: Start of current native code segment.
+ * size: The size of the arena in bytes
+ * op_map: Maps opcode offsets to native code.
+ * map_size: The size of the map in bytes.
+ * fixups: List of fixups.
+ */
+
+typedef struct Parrot_jit_arena_t {
+ char *start;
+ ptrdiff_t size;
+ Parrot_jit_opmap_t *op_map;
+ unsigned long map_size;
+ Parrot_jit_fixup_t *fixups;
+} Parrot_jit_arena_t;
+
+/* Parrot_jit_optimizer_section_t
+ * The bytecode will be divided in sections depending on the
+ * program structure.
+ *
+ * begin: Points where sections begins in the bytecode.
+ * end: Points where sections ends in the bytecode.
+ * arena: The first arena for this section, or NULL if the
+ * section is in the arena inlined in jit_info.
+ * ru[4]: register_usage_t per [IPSN]
+ * maps: Total maps done.
+ * jit_op_count: How many opcodes are jitted.
+ * op_count: Opcodes in this section.
+ * load_size: The size of the register load instructions to be
+ * skipped in an in-section branch.
+ * isjit: If this section is a jitted one or not.
+ * block: block number of section
+ * branch_target: The section where execution continues if this section
+ * ends at a branch source the targeted section is used.
+ */
+
+typedef struct Parrot_jit_optimizer_section *Parrot_jit_optimizer_section_ptr;
+
+/* reg_count: An array with one position for each register
+ * holding the number of times each register is used in the
+ * section.
+ * reg_usage: An array with the registers sorted by the usage.
+ * reg_dir: If the register needs to be loaded or saved.
+ * registers_used: count of used registers
+ */
+typedef struct Parrot_jit_register_usage_t {
+ int reg_count[NUM_REGISTERS];
+ unsigned int reg_usage[NUM_REGISTERS];
+ char reg_dir[NUM_REGISTERS];
+ int registers_used;
+} Parrot_jit_register_usage_t;
+
+typedef struct Parrot_jit_optimizer_section {
+ opcode_t *begin;
+ opcode_t *end;
+ Parrot_jit_register_usage_t ru[4];
+ Parrot_jit_arena_t *arena;
+ unsigned int maps;
+ unsigned int jit_op_count;
+ unsigned int op_count;
+ ptrdiff_t load_size;
+ char isjit;
+ char done;
+ char ins_count;
+ char dummy; /* For alignment ??? XXX */
+ int block; /* What has to align with what? */
+ Parrot_jit_optimizer_section_ptr branch_target;
+ Parrot_jit_optimizer_section_ptr prev;
+ Parrot_jit_optimizer_section_ptr next;
+} Parrot_jit_optimizer_section_t;
+
+/* Parrot_jit_optimizer_section_t
+ * All the information related to optimizing the bytecode.
+ *
+ * sections: A pointer to the first section.
+ * cur_section: Pointer to the current section.
+ * map_branch: A pointer to an array with the size of the bytecode
+ * where the positions of the opcodes will have a value
+ * indicating if the opcode is a branch target, source
+ * or isn't related with a control flow opcode at all,
+ * and which register was allocated for each opcode
+ * argument if any.
+ * has_unpredictable_jump: XXX need to define how to handle this.
+ */
+
+typedef struct Parrot_jit_optimizer_t {
+ Parrot_jit_optimizer_section_t *sections;
+ Parrot_jit_optimizer_section_t *cur_section;
+ char *map_branch;
+ opcode_t **branch_list;
+ unsigned char has_unpredictable_jump;
+ unsigned char dummy[3]; /* For alignment ??? XXX */
+} Parrot_jit_optimizer_t; /* What has to align with what? */
+
+/* Parrot_jit_constant_pool_t
+ * Constants pool information.
+ *
+ */
+typedef struct Parrot_jit_constant_pool_t {
+ long frames_used;
+ long cur_used;
+ char *cur_const;
+ INTVAL *slot_ptr;
+} Parrot_jit_constant_pool_t;
+
+typedef enum {
+ JIT_CODE_FILE,
+ JIT_CODE_SUB,
+ JIT_CODE_SUB_REGS_ONLY,
+
+ /* size */
+ JIT_CODE_TYPES,
+ /* special cases */
+ JIT_CODE_RECURSIVE = 0x10,
+ JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
+} enum_jit_code_type;
+
+/* Parrot_jit_info_t
+ * All the information needed to jit the bytecode will be here.
+ *
+ * prev_op: The previous opcode in this section.
+ * cur_op: The current opcode during the build process.
+ * op_i: Opcode index.
+ * native_ptr: Current pointer to native code.
+ * arena: The arena inlined, this will be the only one used in cases
+ * where there is a way to load an immediate.
+ * optimizer: Optimizer information.
+ * constant_pool: The constant pool information.
+ */
+
+typedef struct Parrot_jit_info_t {
+ opcode_t *prev_op;
+ opcode_t *cur_op;
+ opcode_t op_i;
+ char *native_ptr;
+ Parrot_jit_arena_t arena;
+ Parrot_jit_optimizer_t *optimizer;
+ Parrot_jit_constant_pool_t *constant_pool;
+ INTVAL code_type;
+ int flags;
+ const struct jit_arch_info_t *arch_info;
+ int n_args;
+#if EXEC_CAPABLE
+ Parrot_exec_objfile_t *objfile;
+#else
+ void *objfile;
+#endif /* EXEC_CAPABLE */
+} Parrot_jit_info_t;
+
+#define Parrot_jit_fixup_target(jit_info, fixup) \
+ ((jit_info)->arena.start + (fixup)->native_offset)
+
+typedef void (*jit_fn_t)(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+/* Parrot_jit_fn_info_t
+ * The table of opcodes.
+ *
+ * jit_fn_t: A pointer to the function that emits code for the opcode
+ * or to the C funtion if the opcode is not jitted.
+ * extcall: If the opcode makes an external call to a C funtion.
+ * also used for vtable functions, extcall is #of vtable func
+ */
+
+typedef struct Parrot_jit_fn_info_t {
+ jit_fn_t fn;
+ int extcall;
+} Parrot_jit_fn_info_t;
+
+void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info);
+
+void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+void Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info,
+ PARROT_INTERP);
+
+/*
+ * interface functions for the register save/restore code
+ * with offsets relative to the base register (obtained by
+ * Parrot_jit_emit_get_base_reg_no)
+ */
+void Parrot_jit_emit_mov_mr_n_offs(
+ Interp *, int base_reg, size_t offs, int src_reg);
+void Parrot_jit_emit_mov_mr_offs(
+ Interp *, int base_reg, size_t offs, int src_reg);
+void Parrot_jit_emit_mov_rm_n_offs(
+ Interp *, int dst_reg, int base_reg, size_t offs);
+void Parrot_jit_emit_mov_rm_offs(
+ Interp *, int dst_reg, int base_reg, size_t offs);
+
+/*
+ * interface to architecture specific details
+ */
+typedef void (*jit_arch_f)(Parrot_jit_info_t *, Interp *);
+
+typedef struct jit_arch_regs {
+ /*
+ * begin function - emit ABI call prologue
+ */
+ jit_arch_f jit_begin;
+
+ int n_mapped_I;
+ int n_preserved_I;
+ const char *map_I;
+ int n_mapped_F;
+ int n_preserved_F;
+ const char *map_F;
+} jit_arch_regs;
+
+typedef void (*mov_RM_f)(PARROT_INTERP, Parrot_jit_info_t *,
+ int cpu_reg, int base_reg, INTVAL offs);
+typedef void (*mov_MR_f)(PARROT_INTERP, Parrot_jit_info_t *,
+ int base_reg, INTVAL offs, int cpu_reg);
+
+typedef struct jit_arch_info_t {
+ /* CPU <- Parrot reg move functions */
+ mov_RM_f mov_RM_i;
+ mov_RM_f mov_RM_n;
+ /* Parrot <- CPU reg move functions */
+ mov_MR_f mov_MR_i;
+ mov_MR_f mov_MR_n;
+
+ /* fixup branches and calls after codegen */
+ jit_arch_f jit_dofixup;
+ /* flush caches */
+ jit_arch_f jit_flush_cache;
+ /* register mapping info */
+ const jit_arch_regs regs[JIT_CODE_TYPES];
+} jit_arch_info;
+
+/*
+ * interface to create JIT code
+ */
+Parrot_jit_info_t *
+parrot_build_asm(PARROT_INTERP,
+ opcode_t *code_start, opcode_t *code_end,
+ void *objfile, INTVAL);
+/*
+ * NCI interface
+ */
+void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
+/* custom pmc callback functions */
+void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
+PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
+struct jit_buffer_private_data {
+ int size;
+};
+
/* Scale factor values */
#define emit_Scale(scale) ((scale) << 6)
#define emit_Scale_1 emit_Scale(0)
Deleted: branches/kill_jit/src/jit.c
==============================================================================
--- branches/kill_jit/src/jit.c Thu Sep 17 04:30:13 2009 (r41311)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1869 +0,0 @@
-/*
-Copyright (C) 2001-2009, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit.c - JIT
-
-=head1 DESCRIPTION
-
-JIT (Just In Time) compilation converts bytecode to native machine code
-instructions and executes the generated instruction sequence directly.
-
-Actually it's not really just in time, it's just before this piece of code is
-used and not per subroutine or even opcode, it works per bytecode segment.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#if PARROT_EXEC_CAPABLE
-# include "parrot/exec.h"
-#endif
-#include "jit.h"
-#define JIT_EMIT 0
-#include "jit_emit.h"
-#include "parrot/packfile.h"
-#include "parrot/oplib/ops.h"
-#include "pmc/pmc_sub.h"
-#include "pmc/pmc_managedstruct.h"
-
-#define JIT_SEGS 0
-
-extern int jit_op_count(void);
-/*
- * s. jit/$jitcpuarch/jit_emit.h for the meaning of these defs
- */
-
-#ifndef ALLOCATE_REGISTERS_PER_SECTION
-# define ALLOCATE_REGISTERS_PER_SECTION 1
-#endif
-
-#if defined __GNUC__ || defined __IBMC__
-void Parrot_jit_debug(PARROT_INTERP);
-#endif
-
-/*
-
-=item C<static void
-insert_fixup_targets(PARROT_INTERP, char *branch,
- size_t limit)>
-
-Look at fixups, mark all fixup entries as branch target.
-
-TODO: actually this is wrong: fixups belong only to one code segment.
-The code below doesn't check, for which segments the fixups are
-inserted.
-
-=cut
-
-*/
-
-static void
-insert_fixup_targets(PARROT_INTERP, char *branch,
- size_t limit)
-{
- PackFile_FixupTable *ft = interp->code->fixups;
- int i;
-
- if (!ft)
- return;
-
- for (i = 0; i < ft->fixup_count; i++) {
- if (ft->fixups[i]->type == enum_fixup_label) {
- if ((size_t)ft->fixups[i]->offset < limit)
- branch[ft->fixups[i]->offset] |= JIT_BRANCH_TARGET;
- }
- }
-}
-
-/*
-
-=item C<static void
-make_branch_list(PARROT_INTERP,
- Parrot_jit_optimizer_t * optimizer,
- opcode_t *code_start, opcode_t *code_end)>
-
-C<< optimizer->map_branch >> parallels the opcodes with a list of
-branch information and register mapping information
-
-=over 4
-
-=item branch instructions have C<JIT_BRANCH_SOURCE>
-
-=item opcodes jumped to have C<JIT_BRANCH_TARGET>
-
-=item mapped arguments have register type + 1 and finally
-
-=item after register allocation these have the processor register that
-got mapped
-
-=back
-
-=cut
-
-*/
-
-static void
-make_branch_list(PARROT_INTERP,
- Parrot_jit_optimizer_t * optimizer,
- opcode_t *code_start, opcode_t *code_end)
-{
- op_info_t *op_info;
- char *branch;
- opcode_t *cur_op;
-
- cur_op = code_start;
-
- /* Allocate space for the branch information and register map */
- optimizer->map_branch = branch =
- (char *)mem_sys_allocate_zeroed((size_t)(code_end - code_start + 1));
-
- /* Allocate space for the branch list */
- optimizer->branch_list = (opcode_t **)
- mem_sys_allocate_zeroed(
- (size_t)(code_end - code_start) * sizeof (opcode_t *));
-
- /* If the opcode jumps we may:
- *
- * PARROT_JUMP_RELATIVE:
- * The op jumps to an address relative to the current position,
- * thus we mark the branch target and the branch source.
- *
- * PARROT_JUMP_ADDRESS:
- * The op jumps to an absolute address, thus we mark the branch
- * target.
- *
- * PARROT_JUMP_POP:
- * The op pops the address to jump to, thus we don't mark the
- * branch target, anyway it may probably use expr(NEXT)
- *
- * PARROT_JUMP_ENEXT:
- * The op does something with expr(NEXT),
- * XXX I'll assume that it's stored in the control stack for
- * later returning since that's the only way it's used now
- * but this should go away by the time we add some metadata
- * to the ops.
- * So we will mark the branch target.
- *
- * PARROT_JUMP_GNEXT:
- * Means the opcode does some other kind of jump, and also
- * might goto(NEXT)
- *
- * PARROT_JUMP_UNPREDICTABLE:
- * The branch target is unpredictable.
- * Things get a little tricky since it's not 100% true that the
- * target is unpredictable because of the set_addr opcode, we
- * need to find a solution for this, in the mean time, we will
- * make each section have its own arena and try to avoid
- * going in and out from them as much as possible.
- *
- * PARROT_JUMP_RESTART
- * If the parrot program counter is zero, fall out of the
- * run loop.
- *
- */
-
- while (cur_op < code_end) {
- opcode_t op = *cur_op;
- int i, n;
- size_t rel_offset;
-
-
- /* Predereference the opcode information table for this opcode
- * early since it's going to be used many times */
- op_info = &interp->op_info_table[op];
-
- /* if op_info->jump is not 0 this opcode may jump,
- * so mark this opcode as a branch source */
- rel_offset = cur_op - code_start;
-
- n = op_info->op_count;
-
- if (op == PARROT_OP_set_args_pc ||
- op == PARROT_OP_set_returns_pc ||
- op == PARROT_OP_get_results_pc)
- goto no_branch;
- if (op_info->jump)
- branch[rel_offset] |= JIT_BRANCH_SOURCE;
- for (i = 1; i < n; ++i) {
- /* If it's not a constant, no joy */
- if (op_info->types[i-1] == PARROT_ARG_IC && op_info->labels[i-1]) {
- /* The branch target is relative,
- * the offset is in the i argument
- */
- if (op_info->jump & PARROT_JUMP_RELATIVE) {
- /* Set the branch target */
- optimizer->branch_list[rel_offset] = cur_op + cur_op[i];
- branch[rel_offset + cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- /* The branch target is absolute,
- * the address is in the i argument
- */
- else if (op_info->jump & PARROT_JUMP_ADDRESS) {
- /* Set the branch target */
- optimizer->branch_list[rel_offset] = cur_op + cur_op[i];
- branch[cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- /* the labels of set_addr and newsub are branch targets too
- * this is needed e.g. for JIT_CGP
- */
- else {
- branch[rel_offset + cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- }
- }
- /* The address of the next opcode */
- if ((op_info->jump & PARROT_JUMP_ENEXT) ||
- (op_info->jump & PARROT_JUMP_GNEXT))
- branch[rel_offset + n] |= JIT_BRANCH_TARGET;
- if (op_info->jump & PARROT_JUMP_UNPREDICTABLE) {
- /*
- * TODO
- * this flag is currently not used or set
- * and: if we have a branch that isn't going to a constant
- * target like a calculated branch used by rx_ opcodes
- * we are totally lost WRT register preservation.
- * If we don't know, that the code is a branch target, inside
- * a JITted code section, mapped registers might be
- * not up to date WRT Parrot registers.
- */
- optimizer->has_unpredictable_jump = 1;
- }
-no_branch:
- /* Move to the next opcode */
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
- }
- insert_fixup_targets(interp, branch, code_end - code_start);
-}
-
-/*
-
-=item C<static void
-set_register_usage(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- op_info_t *op_info, opcode_t *cur_op, opcode_t *code_start)>
-
-Sets the register usage counts.
-
-=cut
-
-*/
-
-static void
-set_register_usage(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- op_info_t *op_info, opcode_t *cur_op, opcode_t *code_start)
-{
- int argn, args, argt;
- int typ;
- Parrot_jit_register_usage_t *ru = cur_section->ru;
- Parrot_jit_optimizer_t * optimizer = jit_info->optimizer;
- char * const map = optimizer->map_branch;
-
- /* For each argument that has the opcode increment the usage count,
- * We move from the end since we need to check if the first opcode
- * using the register will read or write it.
- *
- * registers are set per their type [IPSN]
- * */
- args = argt = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, argt);
- for (argn = argt - 1; argn > 0; argn--) {
- /* TODO check the argn-1 entries */
- int idx = *(cur_op + argn);
- int arg_type;
- PMC *sig;
- if (argn >= args) {
- sig = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), cur_op[1]);
- arg_type = VTABLE_get_integer_keyed_int(interp,
- sig, argn - args);
- arg_type &= (PARROT_ARG_TYPE_MASK | PARROT_ARG_CONSTANT);
- }
- else
- arg_type = op_info->types[argn - 1];
-
- switch (arg_type) {
- case PARROT_ARG_I:
- case PARROT_ARG_KI:
- typ = 0;
- /*
- * if the register number is negative, the register mapping
- * was done by imcc/jit.c, which used negative numbers
- * for allocated CPU registers. That's currently not
- * functional because of changed register allocation
- * strategy inside imcc.
- * The code is still here and should probably be reactivated
- * later, when things are stable: imcc has all the
- * necessary information like basic blocks and loop depth
- * calculated already. A lot is duplicated here to regain this
- * information.
- */
- if (idx < 0)
- idx = -1 - idx;
- break;
- case PARROT_ARG_P:
- case PARROT_ARG_K:
- /*
- * P and S regs aren't currently used at all. That's not
- * really optimal. If we have plenty of mappable registers
- * and if we can call vtables or MMD functions directly
- * we should finally allocate P and S regs too.
- */
- typ = 1;
- break;
- case PARROT_ARG_S:
- typ = 2;
- break;
- case PARROT_ARG_N:
- if (idx < 0)
- idx = -1 - idx;
- typ = 3;
- break;
- default:
- typ = -1;
- break;
- }
- /*
- * JIT structures are NUM_REGISTERS big
- * we can currently allocate only that much
- */
- if (typ >= 0 && idx < NUM_REGISTERS) {
- /* remember the register typ (+1) for this op argument
- * for register allocation */
- map[cur_op + argn - code_start] = typ + 1;
- if ((!ru[typ].reg_count[idx]++) &&
- (op_info->dirs[argn-1] & PARROT_ARGDIR_IN))
- ru[typ].reg_dir[idx] |= PARROT_ARGDIR_IN;
- if (op_info->dirs[argn-1] & PARROT_ARGDIR_OUT) {
- ru[typ].reg_dir[idx] |= PARROT_ARGDIR_OUT;
- }
- }
- /* key constants may have register keys */
- else if (arg_type == PARROT_ARG_KC) {
- PMC *key = interp->code->const_table->constants[idx]->u.key;
- while (key) {
- const UINTVAL flags = PObj_get_FLAGS(key);
- if (flags & KEY_register_FLAG) {
- INTVAL n = 0;
- if (flags & KEY_integer_FLAG) {
- n = VTABLE_get_integer(interp, key);
- typ = 0;
- if (n < 0)
- n = -1 - n;
- }
- else if (flags & KEY_pmc_FLAG)
- typ = 1;
- else if (flags & KEY_string_FLAG)
- typ = 2;
-
- if (n < NUM_REGISTERS && !ru[typ].reg_count[n]++)
- ru[typ].reg_dir[n] |= PARROT_ARGDIR_IN;
- }
- key = VTABLE_shift_pmc(interp, key);
- }
- }
- }
-}
-
-/*
-
-=item C<static void
-init_regusage(PARROT_INTERP,
- Parrot_jit_optimizer_section_ptr cur_section)>
-
-Init all register usage to Parrot register usage. Used when JITting
-subroutines to registers only
-
-=cut
-
-*/
-
-static void
-init_regusage(PARROT_INTERP, Parrot_jit_optimizer_section_ptr cur_section)
-{
- int typ;
-
- cur_section->ru[0].registers_used = Parrot_pcc_get_regs_used(interp,
- CURRENT_CONTEXT(interp), REGNO_INT);
- cur_section->ru[3].registers_used = Parrot_pcc_get_regs_used(interp,
- CURRENT_CONTEXT(interp), REGNO_NUM);
- cur_section->ru[1].registers_used = cur_section->ru[2].registers_used = 0;
-
- for (typ = 0; typ < 4; typ++) {
- int j;
- for (j = 0; j < cur_section->ru[typ].registers_used; j++)
- cur_section->ru[typ].reg_usage[j] = j;
- }
-}
-
-/*
-
-=item C<static void make_sections(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)>
-
-I386 has JITed vtables, which have the vtable# in extcall.
-
-This C<Parrot_jit_vtable_n_op()> does use register mappings.
-
-=cut
-
-*/
-
-#ifndef EXTCALL
-# define EXTCALL(op) (op_jit[(op)].extcall >= 1 || (op) >= jit_op_count())
-# define CALLS_C_CODE(op) (op_func[(op)].extcall == -1)
-#endif
-
-static void
-make_sections(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)
-{
- Parrot_jit_optimizer_section_ptr cur_section, t_section, prev_section;
- opcode_t *next_op;
- op_info_t *op_info;
- char *branch;
- int branched, start_new;
- opcode_t *cur_op;
- Parrot_jit_optimizer_t * optimizer;
-
- optimizer = jit_info->optimizer;
- branch = optimizer->map_branch;
-
- /* Allocate the first section */
- cur_section = optimizer->sections = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_section_t));
- cur_section->begin = code_start;
- prev_section = cur_section;
-
- cur_op = code_start;
- /* set all regs to Parrot's */
- if (jit_info->code_type == JIT_CODE_SUB_REGS_ONLY)
- init_regusage(interp, cur_section);
- while (cur_section) {
- opcode_t op = *cur_op;
- branched = start_new = 0;
- /* Predereference the opcode information for this opcode
- * early since it's going to be used many times */
- op_info = &interp->op_info_table[op];
-
- /* Calculate the next pc */
- next_op = cur_op + op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, next_op);
-
- /* Update op_count */
- cur_section->op_count++;
-
- /* set register usage for this section */
- set_register_usage(interp, jit_info, cur_section,
- op_info, cur_op, code_start);
-
- /*
- * End a section:
- * If this opcode is jitted and next is a C function */
- if (!EXTCALL(op)) {
- cur_section->jit_op_count++;
-
- if (next_op < code_end && EXTCALL(*next_op))
- start_new = 1;
- }
- else
- /* or if current section is not jitted, and the next opcode
- * is. */
- if (next_op < code_end && !EXTCALL(*next_op))
- start_new = 1;
-
- /* or when the current opcode is a branch source,
- * in other words if the opcode jumps, or if the next opcode is
- * a branch target, allocate a new section only if it's not the
- * last opcode */
- if ((branch[cur_op - code_start] & JIT_BRANCH_SOURCE)
- || (next_op < code_end &&
- (branch[next_op - code_start] & JIT_BRANCH_TARGET))
- || (next_op >= code_end)) {
- /* remember to start a new block */
- branched = 1;
- start_new = 1;
- }
-
- if (start_new) {
- /* Set the type, depending on whether the current
- * instruction is external or jitted. */
- cur_section->isjit = !EXTCALL(op);
-
- /* Save the address where the section ends */
- cur_section->end = cur_op;
-
- if (next_op < code_end) {
- /* Allocate a new section */
- t_section = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(
- sizeof (Parrot_jit_optimizer_section_t));
- /* Add it to the double linked list */
- cur_section->next = t_section;
- t_section->prev = cur_section;
- /* Make the new section be the current one */
- cur_section = t_section;
- /* set all regs to Parrot's */
- if (jit_info->code_type == JIT_CODE_SUB_REGS_ONLY)
- init_regusage(interp, cur_section);
-
- /* registers get either allocated per section or
- * per basic block (i.e. one or more sections divided
- * by branches. When allocation per block is done
- * all sections in one block have the same block number
- */
- if (ALLOCATE_REGISTERS_PER_SECTION || branched) {
- cur_section->block = prev_section->block + 1;
- prev_section = cur_section;
- }
- else
- cur_section->block = prev_section->block;
- /* Save the address where the section begins */
- cur_section->begin = next_op;
- }
- else {
- cur_section = NULL;
- }
- }
-
- /* Move to the next opcode */
- cur_op = next_op;
- }
-}
-
-/*
-
-=item C<static void
-make_branch_targets(
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
-
-Makes the branch targets.
-
-=cut
-
-*/
-
-static void
-make_branch_targets(Parrot_jit_optimizer_t *optimizer, const opcode_t * code_start)
-{
- Parrot_jit_optimizer_section_ptr cur_section, t_section;
- /* Set the branch target of this section, that is the section where
- * the program execution continues, if it ends in a branch source we
- * use the branch target and not the next section. */
- cur_section = optimizer->sections;
- while (cur_section) {
- if (optimizer->branch_list[cur_section->end - code_start]) {
- /* If the branch target is to a section before the current one
- * move from the start, otherwise from the current section */
- if (optimizer->branch_list[cur_section->end - code_start] <
- cur_section->begin)
- t_section = optimizer->sections;
- else
- t_section = cur_section;
-
- while (t_section) {
- /* If we find the section attach it to the current one. */
- if (t_section->begin ==
- optimizer->branch_list[cur_section->end - code_start]) {
- cur_section->branch_target = t_section;
- break;
- }
- /* If not move to the next. */
- t_section = t_section->next;
- }
-
- }
- /* Move to the next section */
- cur_section = cur_section->next;
- }
-}
-
-/*
-
-=item C<static void
-sort_registers(Parrot_jit_info_t *jit_info)>
-
-Sorts the Parrot registers prior to mapping them to actual hardware registers.
-
-=cut
-
-*/
-
-static void
-sort_registers(Parrot_jit_info_t *jit_info)
-{
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_optimizer_section_ptr cur_section, next;
- int any, k, typ, code_type;
- int max_count, max_i = 0;
- int to_map[] = { 0, 0, 0, 0 };
-
- code_type = jit_info->code_type;
- to_map[0] = jit_info->arch_info->regs[code_type].n_mapped_I;
- to_map[3] = jit_info->arch_info->regs[code_type].n_mapped_F;
-
- optimizer = jit_info->optimizer;
- /* Start from the first section */
- cur_section = optimizer->sections;
-
- while (cur_section) {
- Parrot_jit_register_usage_t *ru = cur_section->ru;
- /* sum up register usage for one block, don't change
- * reg_dir. If allocation is done per section, block numbers
- * are different, so this is a nop
- */
- next = cur_section->next;
- while (next && next->block == cur_section->block) {
- const Parrot_jit_register_usage_t * const nru = next->ru;
- for (typ = 0; typ < 4; typ++) {
- int i;
- for (i = 0; i < NUM_REGISTERS; i++)
- ru[typ].reg_count[i] += nru[typ].reg_count[i];
- }
- next = next->next;
- }
-
- /* now sort registers by their usage count */
- for (typ = 0; typ < 4; typ++) {
- /* find most used register */
- int i;
- for (i = max_count = 0; i < NUM_REGISTERS; i++) {
- if (cur_section->ru[typ].reg_count[i] > max_count) {
- max_count = cur_section->ru[typ].reg_count[i];
- max_i = i;
- }
- }
- /* start from this register and set usage */
- k = ru[typ].registers_used = 0;
- /* no usage, go on with next type */
- if (max_count == 0 || !to_map[typ])
- continue;
- /* as long as we map registers for this typ */
- while (1) {
- if (max_i >= 0)
- ru[typ].reg_usage[k++] = max_i;
- /* all mapped? */
- if (k == to_map[typ])
- break;
- /* now check for equal usage starting after maxi */
- for (any = 0, i = max_i + 1; i < NUM_REGISTERS; i++) {
- if (ru[typ].reg_count[i] == max_count) {
- max_i = i;
- any = 1;
- break;
- }
- }
- /* if same usage not found, look for lower usage */
- if (any == 0) {
- if (max_count > 1) {
- max_count--;
- max_i = -1;
- continue;
- }
- break;
- }
- }
- ru[typ].registers_used = k;
- }
- next = cur_section->next;
- /* duplicate usage to all sections of block */
- while (next && next->block == cur_section->block) {
- Parrot_jit_register_usage_t * const nru = next->ru;
- for (typ = 0; typ < 4; typ++) {
- int i;
- for (i = 0; i < ru[typ].registers_used; i++) {
- nru[typ].reg_count[i] = ru[typ].reg_count[i];
- nru[typ].reg_usage[i] = ru[typ].reg_usage[i];
- }
- nru[typ].registers_used = ru[typ].registers_used;
- }
- next = next->next;
- }
- /* Move to the next section */
- cur_section = next;
- }
-}
-
-/*
-
-=item C<static void
-assign_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- opcode_t * code_start, int from_imcc)>
-
-Called by C<map_registers()> to actually assign the Parrot registers to
-hardware registers.
-
-TODO
-
-Before actually assigning registers, we should optimize a bit:
-
-1) calculate max use count of register types for all sections
-
-2) calculate costs for register preserving and restoring
- for two different allocation strategies:
-
- a) allocate non-volatiles first
- overhead for jit_begin, jit_end:
- - 2 * max_used_non_volatile registers
- overhead for register preserving around non-jitted sections:
- - only used IN arguments are saved
- - only OUT non-volatile arguments are restored
- b) allocate volatiles first
- no overhead for jit_begin, jit_end
- overhead per JITed op that calls a C function:
- - 2 * n_used_volatiles_to_preserve for each call
- overhead for register preserving around non-jitted sections:
- - all volatiles are saved and restored around non-jitted sections
-
-NB for all cost estimations size does matter: a 64bit double counts as
- two 32bit ints. Opcode count is assumed to be just one.
-
-3) depending on costs from 2) use one of the strategies
- That does still not account for any usage patterns. Imcc has loop
- nesting depth, but that's not available here. OTOH smaller code tends
- to perform better because of better cache usage.
-
-Usage analysis could show that a mixture of both strategies is best, e.g:
-allocate 2-4 non-volatiles and the rest from volatiles. But that would
-complicate the allocation code a bit.
-
-=cut
-
-*/
-
-static void
-assign_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- opcode_t * code_start, int from_imcc)
-{
- char *map;
- Parrot_jit_optimizer_t *optimizer;
- int i;
- opcode_t * cur_op;
- const char * maps[] = {0, 0, 0, 0};
- const int code_type = jit_info->code_type;
-
- maps[0] = jit_info->arch_info->regs[code_type].map_I;
- maps[3] = jit_info->arch_info->regs[code_type].map_F;
-
- optimizer = jit_info->optimizer;
- map = optimizer->map_branch;
- /* For each opcode in this section */
- cur_op = cur_section->begin;
- while (cur_op <= cur_section->end) {
- const opcode_t op = *cur_op;
- const op_info_t * const op_info = &interp->op_info_table[op];
- int op_arg;
- int n;
-
- /* For each argument of the current opcode */
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- for (op_arg = 1; op_arg < n; op_arg++) {
- /* get the register typ */
- int typ = map[cur_op + op_arg - code_start];
- /* clear the register typ/map */
- map[cur_op + op_arg - code_start] = 0;
- /* if not JITted, don't map */
- if (!cur_section->isjit)
- continue;
- if (typ > 0) {
- typ--; /* types are + 1 */
- if (!maps[typ])
- continue;
- /* If the argument is in most used list for this typ */
- for (i = 0; i < cur_section->ru[typ].registers_used; i++) {
- opcode_t idx = cur_op[op_arg];
- if (from_imcc)
- idx = -1 - idx;
- if (idx == (opcode_t)cur_section->ru[typ].reg_usage[i]) {
- map[cur_op + op_arg - code_start] = maps[typ][i];
- cur_section->maps++;
- break;
- }
- }
- }
- }
-
- /* Move to the next opcode */
- cur_op += n;
- }
-}
-
-/*
-
-=item C<static void
-map_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info, opcode_t * code_start)>
-
-Maps the most used Parrot registers to hardware registers.
-
-=cut
-
-*/
-
-static void
-map_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t * code_start)
-{
- /* Start from the first section */
- Parrot_jit_optimizer_section_ptr cur_section = jit_info->optimizer->sections;
-
- /* While there is section */
- while (cur_section) {
-
- assign_registers(interp, jit_info, cur_section, code_start, 0);
-
- /* Move to the next section */
- cur_section = cur_section->next;
- }
-}
-
-
-#define JIT_DEBUG 0
-
-#if JIT_DEBUG
-/*
-
-=item C<static void
-debug_sections(PARROT_INTERP,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
-
-Prints out debugging info.
-
-=cut
-
-*/
-
-static void
-debug_sections(PARROT_INTERP,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)
-{
- Parrot_jit_optimizer_section_ptr cur_section;
-# if JIT_DEBUG > 1
- char * map = optimizer->map_branch;
-# endif
- int n;
- const char types[] = "IPSN";
- int types_to_list[] = {0, 3};
-
- cur_section = optimizer->sections;
- while (cur_section) {
- opcode_t * cur_op;
- unsigned int j;
- Parrot_jit_register_usage_t *ru = cur_section->ru;
-
- Parrot_io_eprintf(interp, "\nSection:\n");
- Parrot_io_eprintf(interp, "%s block %d\n",
- (cur_section->isjit) ? "JITTED" : "NOT JITTED",
- cur_section->block);
- for (cur_op = cur_section->begin; cur_op <= cur_section->end;) {
- char instr[256];
- const opcode_t op = *cur_op;
- const op_info_t * const op_info = &interp->op_info_table[op];
-
- PDB_disassemble_op(interp, instr, sizeof (instr),
- op_info, cur_op, NULL, code_start, 0);
- Parrot_io_eprintf(interp, "\t\tOP%vu: ext %3d\t%s\n",
- cur_op - code_start, op_jit[*cur_op].extcall, instr);
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
-# if JIT_DEBUG > 1
- Parrot_io_eprintf(interp, "\t\t\tmap_branch: ");
- for (i = 0; i < n; i++)
- Parrot_io_eprintf(interp, "%02x ", map[cur_op-code_start+i]);
- Parrot_io_eprintf(interp, "\n");
-# endif
- cur_op += n;
- }
- Parrot_io_eprintf(interp, "\tbegin:\t%#p\t(%Ou)\n",
- cur_section->begin, *cur_section->begin);
- Parrot_io_eprintf(interp, "\tend:\t%#p\t(%Ou)\n",
- cur_section->end, *cur_section->end);
-
- for (j = 0; j < sizeof (types_to_list)/sizeof (int); j++) {
- const int typ = types_to_list[j];
- const char t = types[typ];
- Parrot_io_eprintf(interp, "\t%c registers used:\t%i\n",
- t, ru[typ].registers_used);
- if (ru[typ].registers_used) {
- int i;
- Parrot_io_eprintf(interp, "\t%c register count:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", ru[typ].reg_count[i]);
- Parrot_io_eprintf(interp, "\n\t%c register usage:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", ru[typ].reg_usage[i]);
- Parrot_io_eprintf(interp, "\n\t%c register direction:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", (int)ru[typ].reg_dir[i]);
- Parrot_io_eprintf(interp, "\n");
- }
- }
- Parrot_io_eprintf(interp, "\tJit opcodes:\t%u\n",
- cur_section->jit_op_count);
- Parrot_io_eprintf(interp, "\tTotal opcodes:\t%u\n",
- cur_section->op_count);
- if (cur_section->branch_target)
- Parrot_io_eprintf(interp, "\tBranch target:\tOP%u\n",
- cur_section->branch_target->begin - code_start);
-
- cur_section = cur_section->next;
- }
-}
-#endif
-
-/*
-
-=item C<static Parrot_jit_optimizer_t *
-optimize_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)>
-
-Called by C<parrot_build_asm()> to run the optimizer.
-
-=cut
-
-*/
-
-static void
-optimize_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)
-{
- Parrot_jit_optimizer_t *optimizer;
-
- /* Allocate space for the optimizer */
- jit_info->optimizer =
- optimizer = (Parrot_jit_optimizer_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_t));
-
- /* Look, which opcodes might branch */
- make_branch_list(interp, optimizer, code_start, code_end);
-
- /* ok, let's loop again and generate the sections */
- make_sections(interp, jit_info, code_start, code_end);
-
- /* look where a section jumps to */
- make_branch_targets(optimizer, code_start);
-
- /* This is where we start deciding which Parrot registers get
- * mapped to a hardware one in each different section. */
-
-#if JIT_DEBUG > 2
- debug_sections(interp, optimizer, code_start);
-#endif
- if (jit_info->code_type != JIT_CODE_SUB_REGS_ONLY)
- sort_registers(jit_info);
- map_registers(interp, jit_info, code_start);
-
-#if JIT_DEBUG
- debug_sections(interp, optimizer, code_start);
-#endif
-}
-
-/*
-
-=item C<static Parrot_jit_optimizer_t *
-optimize_imcc_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end,
- PackFile_Segment *jit_seg)>
-
-Generate optimizer stuff from the C<_JIT> section in the packfile.
-
-=cut
-
-*/
-
-static void
-optimize_imcc_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end,
- PackFile_Segment *jit_seg)
-{
- Parrot_jit_optimizer_t *optimizer;
- size_t size, i, typ, n;
- int j;
- opcode_t *ptr, offs;
- Parrot_jit_optimizer_section_ptr section, prev;
- char *branch;
- opcode_t *cur_op;
-
- /* Allocate space for the optimizer */
- jit_info->optimizer =
- optimizer = (Parrot_jit_optimizer_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_t));
- /*
- * TODO: pass the whole map_branch in the PBC
- * this would save two runs through all the opcode
- */
- optimizer->map_branch = branch =
- (char *)mem_sys_allocate_zeroed((size_t)(code_end - code_start));
- ptr = jit_seg->data;
- size = jit_seg->size;
- PARROT_ASSERT(jit_seg->itype == 0);
- PARROT_ASSERT((size % 6) == 0);
- cur_op = code_start;
- for (prev = NULL, i = 0; i < size/6; i++, prev = section) {
- section = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_section_t));
- if (prev)
- prev->next = section;
- else
- optimizer->sections = section;
- section->prev = prev;
- section->block = i;
- offs = *ptr++;
- if (offs & 0x80000000) {
- offs &= ~0x80000000;
- branch[offs] = JIT_BRANCH_TARGET;
- }
- section->begin = code_start + offs;
- section->end = code_start + *ptr++;
- section->isjit = 1;
- for (typ = 0; typ < 4; typ++) {
- section->ru[typ].registers_used = *ptr++;
- for (j = 0; j < section->ru[typ].registers_used; j++)
- section->ru[typ].reg_usage[j] = j;
-
- }
- while (cur_op <= section->end) {
- const opcode_t op = *cur_op;
- op_info_t * const op_info = &interp->op_info_table[op];
- set_register_usage(interp, jit_info, section,
- op_info, cur_op, code_start);
- section->op_count++;
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
- }
- assign_registers(interp, jit_info, section, code_start, 1);
- }
- insert_fixup_targets(interp, branch, code_end - code_start);
-#if JIT_DEBUG
- debug_sections(interp, optimizer, code_start);
-#endif
-}
-
-/*
-
-=item C<size_t reg_offs(int typ, int i)>
-
-Returns the offset of register C<typ[i]>.
-
-F<src/jit/arch/jit_emit.h> has to define C<Parrot_jit_emit_get_base_reg_no(pc)>
-
-=cut
-
-*/
-
-/* we always are using offsets */
-
-
-static size_t
-reg_offs(int typ, int i)
-{
- switch (typ) {
- case 0:
- return REG_OFFS_INT(i);
- case 3:
- return REG_OFFS_NUM(i);
- default:
- return 0;
- }
-}
-
-/*
-
-=item C<static void
-Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)>
-
-Load registers for the current section from parrot to processor registers.
-If C<volatiles> is true, this code is used to restore these registers in
-JITted code that calls out to Parrot.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)
-{
- Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
- Parrot_jit_register_usage_t *ru = sect->ru;
- int typ;
- size_t offs;
- int base_reg = 0; /* -O3 warning */
- int lasts[] = { 0, 0, 0, 0 };
- const char * maps[] = {0, 0, 0, 0};
- int first = 1;
- const int code_type = jit_info->code_type;
- const jit_arch_info * const arch_info = jit_info->arch_info;
- const jit_arch_regs * const reg_info = arch_info->regs + code_type;
-
- maps[0] = reg_info->map_I;
- maps[3] = reg_info->map_F;
- lasts[0] = reg_info->n_preserved_I;
- lasts[3] = reg_info->n_preserved_F;
-
- for (typ = 0; typ < 4; typ++) {
- if (maps[typ]) {
- int i;
- for (i = ru[typ].registers_used-1; i >= 0; --i) {
- const int us = ru[typ].reg_usage[i];
- const int is_used = i >= lasts[typ] && ru[typ].reg_dir[us];
- if ((is_used && volatiles) ||
- (!volatiles &&
- ((ru[typ].reg_dir[us] & PARROT_ARGDIR_IN)))) {
- if (first) {
- base_reg = Parrot_jit_emit_get_base_reg_no(
- jit_info->native_ptr);
- first = 0;
- }
- offs = reg_offs(typ, us);
- if (typ == 3)
- (arch_info->mov_RM_n)(interp, jit_info,
- maps[typ][i], base_reg, offs);
- else
- (arch_info->mov_RM_i)(interp, jit_info,
- maps[typ][i], base_reg, offs);
-
- }
- }
- }
- }
-
- /* The total size of the loads. This is used for branches to
- * the same section - these skip the load asm bytes */
- sect->load_size = jit_info->native_ptr -
- (jit_info->arena.start +
- jit_info->arena.op_map[jit_info->op_i].offset);
-}
-
-/*
-
-=item C<static void
-Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)>
-
-Save registers for the current section.
-If C<volatiles> is true, this code is used to preserve these registers in
-JITted code that calls out to Parrot.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)
-{
- Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
- Parrot_jit_register_usage_t *ru = sect->ru;
- int i, typ;
- size_t offs;
- int base_reg = 0; /* -O3 warning */
- int lasts[] = { 0, 0, 0, 0 };
- const char * maps[] = {0, 0, 0, 0};
- int first = 1;
- int code_type;
- const jit_arch_info *arch_info;
- const jit_arch_regs *reg_info;
-
- arch_info = jit_info->arch_info;
- code_type = jit_info->code_type;
- reg_info = arch_info->regs + code_type;
- maps[0] = reg_info->map_I;
- maps[3] = reg_info->map_F;
- lasts[0] = reg_info->n_preserved_I;
- lasts[3] = reg_info->n_preserved_F;
-
- for (typ = 0; typ < 4; typ++) {
- if (maps[typ])
- for (i = 0; i < ru[typ].registers_used; ++i) {
- const int us = ru[typ].reg_usage[i];
- const int is_used = i >= lasts[typ] && ru[typ].reg_dir[us];
- if ((is_used && volatiles) ||
- (!volatiles &&
- (ru[typ].reg_dir[us] & PARROT_ARGDIR_OUT))) {
- if (first) {
- base_reg = Parrot_jit_emit_get_base_reg_no(
- jit_info->native_ptr);
- first = 0;
- }
-
- offs = reg_offs(typ, us);
- if (typ == 3)
- (arch_info->mov_MR_n)(interp, jit_info,
- base_reg, offs, maps[typ][i]);
- else
- (arch_info->mov_MR_i)(interp, jit_info,
- base_reg, offs, maps[typ][i]);
-
- }
- }
- }
-}
-
-/*
-
-=item C<void
-Parrot_destroy_jit(void *ptr)>
-
-Frees the memory used by the JIT subsystem.
-
-=cut
-
-*/
-
-void
-Parrot_destroy_jit(void *ptr)
-{
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_optimizer_section_ptr cur_section, next;
- Parrot_jit_fixup_t *fixup, *next_f;
- Parrot_jit_info_t *jit_info = (Parrot_jit_info_t *)ptr;
-
- if (!jit_info)
- return;
- /* delete sections */
- optimizer = jit_info->optimizer;
- cur_section = optimizer->sections;
- while (cur_section) {
- next = cur_section->next;
- mem_sys_free(cur_section);
- cur_section = next;
- }
- /* arena stuff */
- mem_sys_free(jit_info->arena.op_map);
- mem_free_executable(jit_info->arena.start, jit_info->arena.size);
- fixup = jit_info->arena.fixups;
- while (fixup) {
- next_f = fixup->next;
- mem_sys_free(fixup);
- fixup = next_f;
- }
- /* optimizer stuff */
- mem_sys_free(optimizer->map_branch);
- mem_sys_free(optimizer->branch_list);
- mem_sys_free(optimizer);
-
- free(jit_info);
-}
-
-/*
- * see TODO below
- * - locate Sub according to pc
- * - set register usage in context
- */
-static void
-set_reg_usage(PARROT_INTERP, const opcode_t *pc)
-{
- PackFile_ByteCode * const seg = interp->code;
- PackFile_FixupTable * const ft = seg->fixups;
- PackFile_ConstTable * const ct = seg->const_table;
-
- int i;
-
- if (!ft)
- return;
-
- if (!ct)
- return;
-
- for (i = 0; i < ft->fixup_count; i++) {
- if (ft->fixups[i]->type == enum_fixup_sub) {
- const int ci = ft->fixups[i]->offset;
- PMC * const sub_pmc = ct->constants[ci]->u.key;
- Parrot_Sub_attributes *sub;
- size_t offs;
- int i;
-
- PMC_get_sub(interp, sub_pmc, sub);
- offs = pc - sub->seg->base.data;
-
- if (offs >= sub->start_offs && offs < sub->end_offs) {
- for (i = 0; i < 4; i++)
- Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp),
- i, sub->n_regs_used[i]);
-
- return;
- }
- }
- }
-}
-
-/*
-
-=item C<Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP,
- opcode_t *code_start, opcode_t *code_end,
- void *objfile, enum_jit_code_type)>
-
-This is the main function of the JIT code generator.
-
-It loops over the bytecode, calling the code generating routines for
-each opcode.
-
-The information obtained is used to perform certain types of fixups on
-native code, as well as by the native code itself to convert bytecode
-program counters values to hardware program counter values.
-
-Finally this code here is used to generate native executables (or better
-object files that are linked to executables), if EXEC_CAPABLE is defined.
-This functionality is triggered by
-
- parrot -o foo.o foo.pir
-
-which uses the JIT engine to translate to native code inside the object
-file.
-
-=cut
-
-*/
-
-Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP, ARGIN(opcode_t *code_start), ARGIN(opcode_t *code_end),
- ARGIN(void *objfile), INTVAL jit_type)
-{
- int n;
- UINTVAL i;
- char *new_arena;
- Parrot_jit_info_t *jit_info = NULL;
- opcode_t cur_opcode_byte;
- opcode_t *cur_op;
- PackFile_Segment *jit_seg;
- char *map;
- Parrot_jit_fn_info_t *op_func;
- INTVAL n_regs_used[4]; /* INSP in PBC */
- op_info_t *op_info;
- const jit_arch_info *arch_info;
- int needs_fs; /* fetch/store */
-
- /* XXX
- * no longer referenced due to disabled code below
- char *name;
- */
-
- Parrot_jit_optimizer_section_ptr cur_section;
-
-#if EXEC_CAPABLE
- Parrot_exec_objfile_t *obj = (Parrot_exec_objfile_t *)objfile;
-#endif
-
- jit_info = interp->code->jit_info = mem_allocate_typed(Parrot_jit_info_t);
-
- jit_info->flags = jit_type & JIT_CODE_RECURSIVE;
- jit_type &= ~ JIT_CODE_RECURSIVE;
- jit_info->code_type = jit_type;
- needs_fs = jit_type
- != JIT_CODE_SUB_REGS_ONLY;
-
-#if EXEC_CAPABLE
- if (objfile) {
- op_func = op_exec;
- jit_info->objfile = obj;
- }
- else
-#endif
- {
- op_func = op_jit;
- jit_info->objfile = NULL;
- }
-
- /* reset some extcall bits - all is JITed
- */
- if (jit_type == JIT_CODE_SUB_REGS_ONLY) {
- op_func[PARROT_OP_set_returns_pc].extcall = 0;
- op_func[PARROT_OP_get_params_pc].extcall = 0;
- op_func[PARROT_OP_get_params_pc].extcall = 0;
- op_func[PARROT_OP_invokecc_p].extcall = 0;
- }
-
- /* get register mappings and such */
- arch_info = jit_info->arch_info = Parrot_jit_init(interp);
-
- /*
- * check if IMCC did all the work. If yes, we have a PF segment with
- * register allocation information inside.
- * See imcc/jit.c for more
- */
-#if JIT_SEGS
- /* RT #45055
- * JIT segs are currently not built
- * the find_segments also segfaults on PPC eval_2
- * maybe something not initialized correctly
- * - disabled --leo
- */
- name = mem_sys_allocate(strlen(interp->code->base.name) + 5);
- sprintf(name, "%s_JIT", interp->code->base.name);
- jit_seg = PackFile_find_segment(interp,
- interp->code->base.dir, name, 0);
- mem_sys_free(name);
-#else
- jit_seg = NULL;
-#endif
-
- /* remember register usage */
- for (i = 0; i < 4; i++)
- n_regs_used[i] = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), i);
-
- set_reg_usage(interp, code_start);
-
-#if JIT_SEGS
- optimize_imcc_jit(interp, jit_info, code_start, code_end, jit_seg);
-#else
- optimize_jit(interp, jit_info, code_start, code_end);
-#endif
-
- /* Byte code size in opcode_t's */
- jit_info->arena.map_size = (code_end - code_start) + 1;
- jit_info->arena.op_map =
- (Parrot_jit_opmap_t *)mem_sys_allocate_zeroed(
- jit_info->arena.map_size * sizeof (* (jit_info->arena.op_map)));
-
-#if REQUIRES_CONSTANT_POOL
- Parrot_jit_init_arenas(jit_info);
-#else
- jit_info->arena.size = 1024;
-
- /* estimate size needed
- * 10 times pbc code size seems to be enough for i386
- */
- if ((size_t)jit_info->arena.map_size * 20 > (size_t)jit_info->arena.size)
- jit_info->arena.size = jit_info->arena.map_size * 20;
- jit_info->native_ptr = jit_info->arena.start =
- (char *)mem_alloc_executable((size_t)jit_info->arena.size);
- if (! jit_info->native_ptr)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Cannot allocate executable memory");
-
-# if EXEC_CAPABLE
- if (obj)
- jit_info->objfile->text.code = jit_info->arena.start;
-# endif
-#endif
-
- jit_info->op_i = 0;
- jit_info->arena.fixups = NULL;
-
- /* The first section */
- cur_section = jit_info->optimizer->cur_section
- = jit_info->optimizer->sections;
- map = jit_info->optimizer->map_branch;
-
- /*
- * from C's ABI all the emitted code here is one (probably big)
- * function. So we have to generate an appropriate function
- * prologue, that makes all this look like a normal function ;)
- */
- jit_info->cur_op = cur_section->begin;
- (arch_info->regs[jit_type].jit_begin)(jit_info, interp);
-
- /*
- * op_map holds the offset from arena.start
- * of the parrot op at the given opcode index
- *
- * Set the offset of the first opcode
- */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /*
- * the function epilog can basically be anywhere, that's done
- * by the Parrot_end opcode somewhere in core.jit
- */
-
- while (jit_info->optimizer->cur_section) {
- /* the code emitting functions need cur_op and cur_section
- * so these vars are in jit_info too
- */
-
- /*
- * TODO
- *
- * Register offsets depend on n_regs_used, which is per
- * subroutine. JIT code is currently generated for a whole
- * PBC. We can either:
- * 1) create JIT per subroutine or
- * 2) track the sub we are currently in, set register usage
- * in the interpreter context and restore it at end
- *
- * for now we use 2) - longterm plan is 1)
- */
-
- /* The first opcode for this section */
- cur_op = jit_info->cur_op = cur_section->begin;
-
- set_reg_usage(interp, cur_op);
-
- /* Load mapped registers for this section, if JIT */
- if (!jit_seg && cur_section->isjit && needs_fs)
- Parrot_jit_load_registers(jit_info, interp, 0);
-
- /* The first opcode of each section doesn't have a previous one since
- * it's impossible to be sure which was it */
- jit_info->prev_op = NULL;
-
- while (cur_op <= cur_section->end) {
- /* Grow the arena early */
- if (jit_info->arena.size <
- (jit_info->arena.op_map[jit_info->op_i].offset + 200)) {
-#if REQUIRES_CONSTANT_POOL
- Parrot_jit_extend_arena(jit_info);
-#else
- new_arena = (char *)mem_realloc_executable(jit_info->arena.start,
- jit_info->arena.size, (size_t)jit_info->arena.size * 2);
- jit_info->arena.size *= 2;
- jit_info->native_ptr = new_arena +
- (jit_info->native_ptr - jit_info->arena.start);
- jit_info->arena.start = new_arena;
-# if EXEC_CAPABLE
- if (obj)
- obj->text.code = new_arena;
-# endif
-#endif
- }
-
- cur_opcode_byte = *cur_op;
-
- /* Need to save the registers if there is a branch and is not to
- * the same section, I admit I don't like this, and it should be
- * really checking if the target section has the same registers
- * mapped too.
- *
- * Yep so: TODO
- * during register allocation try to use the same registers, if
- * its a loop or a plain branch and if register usage doesn't
- * differ too much. This could save a lot of register reloads.
- *
- * --
- *
- * save also, if we have a jitted sections and encounter
- * an "end" opcode, e.g. in evaled code
- */
- if (needs_fs) {
- if ((((map[cur_op - code_start] == JIT_BRANCH_SOURCE) &&
- (cur_section->branch_target != cur_section)) ||
- !cur_opcode_byte) &&
- cur_section->isjit &&
- !jit_seg) {
- Parrot_jit_save_registers(jit_info, interp, 0);
- }
- else if (CALLS_C_CODE(cur_opcode_byte)) {
- /*
- * a JITted function with a function call, we have to
- * save volatile registers but
- * TODO not if the previous opcode was also one
- * that called C code
- */
- Parrot_jit_save_registers(jit_info, interp, 1);
- }
- }
-
- /*
- * for all opcodes that are dynamically loaded, we can't have
- * a JITted version, so we execute the function incarnation
- * via the wrapper opcode, which just runs one opcode
- * see ops/core.ops for more
- */
- if (cur_opcode_byte >= jit_op_count())
- cur_opcode_byte = CORE_OPS_wrapper__;
-
- (op_func[cur_opcode_byte].fn) (jit_info, interp);
-
- if (CALLS_C_CODE(cur_opcode_byte) && needs_fs) {
- /*
- * restore volatiles only - and TODO only if next
- * wouldn't load registers anyway
- */
- Parrot_jit_load_registers(jit_info, interp, 1);
- }
- /* Update the previous opcode */
- jit_info->prev_op = cur_op;
-
- op_info = &interp->op_info_table[*cur_op];
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
-
- /* update op_i and cur_op accordingly */
- jit_info->op_i += n;
- jit_info->cur_op += n;
-
- if (*jit_info->prev_op == PARROT_OP_set_args_pc &&
- jit_type == JIT_CODE_SUB_REGS_ONLY) {
- PARROT_ASSERT(*cur_op == PARROT_OP_set_p_pc);
-
- /* skip it */
- cur_op += 3;
- jit_info->op_i += 3;
- jit_info->cur_op += 3;
-
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- PARROT_ASSERT(*cur_op == PARROT_OP_get_results_pc);
-
- /* now emit the call - use special op for this */
- /* Don't want to fix it. JIT on chopping block.
- * (op_func[PARROT_OP_pic_callr___pc].fn)(jit_info, interp);
- */
-
- /* and the get_results */
- (op_func[*cur_op].fn)(jit_info, interp);
-
- op_info = &interp->op_info_table[*cur_op];
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
-
- cur_op += n;
-
- /* update op_i and cur_op accordingly */
- jit_info->op_i += n;
- jit_info->cur_op += n;
-
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /* now at invoke */
- PARROT_ASSERT(*cur_op == PARROT_OP_invokecc_p);
-
- cur_op += 2; /* skip it */
- jit_info->op_i += 2;
- jit_info->cur_op += 2;
- }
-
- /* if this is a branch target, align it */
-#ifdef jit_emit_noop
-# if JUMP_ALIGN
- if (((!cur_section->next && cur_op <= cur_section->end) ||
- cur_section->next) &&
- map[cur_op - code_start] == JIT_BRANCH_TARGET) {
- while ((long)jit_info->native_ptr & ((1<<JUMP_ALIGN) - 1))
- jit_emit_noop(jit_info->native_ptr);
- }
-# endif
-#endif
- /* set the offset */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
- }
-
- /* Save mapped registers back to the Parrot registers */
- if (!jit_seg && cur_section->isjit && needs_fs)
- Parrot_jit_save_registers(jit_info, interp, 0);
-
- /* update the offset for saved registers */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /* Move to the next section */
- cur_section = jit_info->optimizer->cur_section =
- cur_section->next;
- }
-
- /* restore register usage */
- for (i = 0; i < 4; i++)
- Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp), i, n_regs_used[i]);
-
- /* Do fixups before converting offsets */
- (arch_info->jit_dofixup)(jit_info, interp);
-
- /* Convert offsets to pointers */
- if (!objfile)
- for (i = 0; i < jit_info->arena.map_size; i++) {
-
- /* Assuming native code chunks contain some initialization code,
- * the first op (and every other op) is at an offset > 0
- */
- if (jit_info->arena.op_map[i].offset) {
- jit_info->arena.op_map[i].ptr = (char *)jit_info->arena.start +
- jit_info->arena.op_map[i].offset;
- }
- }
-
- jit_info->arena.size =
- (ptrdiff_t)(jit_info->native_ptr - jit_info->arena.start);
-#if JIT_DEBUG
- Parrot_io_eprintf(interp, "\nTotal size %u bytes\n",
- (unsigned int)(jit_info->native_ptr - jit_info->arena.start));
-#endif
-
- /*
- * sync data cache if needed - we are executing it as code in some usecs
- */
- if (arch_info->jit_flush_cache)
- (arch_info->jit_flush_cache)(jit_info, interp);
-
- /* assume gdb is available: generate symbol information */
-#if defined __GNUC__ || defined __IBMC__
- if (Interp_debug_TEST(interp, PARROT_JIT_DEBUG_FLAG)) {
- /*
- * TODO same like above here e.g. create ASM listing of code
- * if real debug support isn't available
- */
- if (jit_type == JIT_CODE_FILE) {
- interp->code->jit_info = jit_info;
- Parrot_jit_debug(interp);
- }
- }
-#endif
-
- return jit_info;
-}
-
-/*
-
-=item C<void
-Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)>
-
-Remember the current position in the native code for later update.
-
-=cut
-
-*/
-
-void
-Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)
-{
- Parrot_jit_fixup_t *fixup;
-
- fixup = mem_allocate_zeroed_typed(Parrot_jit_fixup_t);
-
- /* Insert fixup at the head of the list */
- fixup->next = jit_info->arena.fixups;
- jit_info->arena.fixups = fixup;
-
- /* Fill in the native code offset */
- fixup->native_offset =
- (ptrdiff_t)(jit_info->native_ptr - jit_info->arena.start);
-}
-
-/*
-
-=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
-
-This is a callback to implement the proper freeing semantics. It is called by
-the ManagedStruct PMC as it is garbage collected.
-
-=cut
-
-*/
-
-void
-Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
-{
- const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv;
- mem_free_executable(ptr, jit->size);
- free(priv);
-}
-
-/*
-
-=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
-
-This is a callback to implement the proper cloning semantics for jit buffers.
-It is called by the ManagedStruct PMC's clone() function.
-
-=cut
-
-*/
-
-PMC *
-Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
-{
- PMC * const rv = pmc_new(interp, pmc->vtable->base_type);
-
- VTABLE_init(interp, rv);
- /* copy the attributes */
- {
- void (*tmpfreefunc)(PARROT_INTERP, void*, void*);
- GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc);
- SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc);
- }
- {
- PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*);
- GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc);
- SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc);
- }
-
- {
- void *freepriv, *clonepriv;
- GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv);
- GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv);
- if (freepriv) {
- void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
- memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data));
- SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp);
- if (clonepriv == freepriv) {
- /* clonepriv is a copy of freepriv, make it a copy in the clone too. */
- SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
- clonepriv = NULL; /* disable the clonepriv copying below */
- }
- }
- if (clonepriv) {
- void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
- memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data));
- SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
- }
- }
-
- /* copy the execmem buffer */
- if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
- struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
- void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
- void *newptr = mem_alloc_executable(jit->size);
- if (!newptr)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Cannot allocate executable memory");
- memcpy(newptr, ptr, jit->size);
- PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
- }
-
- return rv;
-}
-
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit.h>, F<docs/jit.pod>, F<src/jit_debug.c>,
-F<src/jit/$jitcpuarch/jit_emit.h>, F<jit/$jitcpuarch/core.jit>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: branches/kill_jit/src/jit.h
==============================================================================
--- branches/kill_jit/src/jit.h Thu Sep 17 04:30:13 2009 (r41311)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2001-2007, Parrot Foundation.
- */
-
-/*
- * jit.h
- *
- * $Id$
- */
-
-#ifndef PARROT_JIT_H_GUARD
-#define PARROT_JIT_H_GUARD
-
-#if EXEC_CAPABLE
-# include "parrot/exec.h"
-#endif
-
-typedef void (*jit_f)(PARROT_INTERP, opcode_t *pc);
-
-
-void Parrot_destroy_jit(void *);
-
-/* Parrot_jit_fixup_t
- * Platform generic fixup information
- *
- * type: The type of fixup.
- * native_offset: Where to apply the fixup.
- * skip: Skip instructions after the target.
- * param: Fixup specific data.
- */
-
-typedef struct Parrot_jit_fixup *Parrot_jit_fixup_ptr;
-
-typedef struct Parrot_jit_fixup {
- int type;
- ptrdiff_t native_offset;
- char skip;
- char dummy[3]; /* For alignment ??? XXX */
- union { /* What has to align with what? */
- opcode_t opcode;
- void (*fptr)(void);
- } param;
-
- Parrot_jit_fixup_ptr next;
-} Parrot_jit_fixup_t;
-
-/* Parrot_jit_opmap_t
- * Hold native code offsets/addresses
- *
- * ptr: Pointer to native code
- * offset: Offset of native code from arena.start
- */
-
-typedef union {
- void *ptr;
- ptrdiff_t offset;
-} Parrot_jit_opmap_t;
-
-enum {
- JIT_BRANCH_NO, /* The opcode doesn't branch */
- JIT_BRANCH_TARGET, /* The opcode is a branch target */
- JIT_BRANCH_SOURCE /* The opcode is a branch source */
-};
-
-
-/* Parrot_jit_arena_t
- * Holds pointers to the native code of one or more sections.
- *
- * start: Start of current native code segment.
- * size: The size of the arena in bytes
- * op_map: Maps opcode offsets to native code.
- * map_size: The size of the map in bytes.
- * fixups: List of fixups.
- */
-
-typedef struct Parrot_jit_arena_t {
- char *start;
- ptrdiff_t size;
- Parrot_jit_opmap_t *op_map;
- unsigned long map_size;
- Parrot_jit_fixup_t *fixups;
-} Parrot_jit_arena_t;
-
-/* Parrot_jit_optimizer_section_t
- * The bytecode will be divided in sections depending on the
- * program structure.
- *
- * begin: Points where sections begins in the bytecode.
- * end: Points where sections ends in the bytecode.
- * arena: The first arena for this section, or NULL if the
- * section is in the arena inlined in jit_info.
- * ru[4]: register_usage_t per [IPSN]
- * maps: Total maps done.
- * jit_op_count: How many opcodes are jitted.
- * op_count: Opcodes in this section.
- * load_size: The size of the register load instructions to be
- * skipped in an in-section branch.
- * isjit: If this section is a jitted one or not.
- * block: block number of section
- * branch_target: The section where execution continues if this section
- * ends at a branch source the targeted section is used.
- */
-
-typedef struct Parrot_jit_optimizer_section *Parrot_jit_optimizer_section_ptr;
-
-/* reg_count: An array with one position for each register
- * holding the number of times each register is used in the
- * section.
- * reg_usage: An array with the registers sorted by the usage.
- * reg_dir: If the register needs to be loaded or saved.
- * registers_used: count of used registers
- */
-typedef struct Parrot_jit_register_usage_t {
- int reg_count[NUM_REGISTERS];
- unsigned int reg_usage[NUM_REGISTERS];
- char reg_dir[NUM_REGISTERS];
- int registers_used;
-} Parrot_jit_register_usage_t;
-
-typedef struct Parrot_jit_optimizer_section {
- opcode_t *begin;
- opcode_t *end;
- Parrot_jit_register_usage_t ru[4];
- Parrot_jit_arena_t *arena;
- unsigned int maps;
- unsigned int jit_op_count;
- unsigned int op_count;
- ptrdiff_t load_size;
- char isjit;
- char done;
- char ins_count;
- char dummy; /* For alignment ??? XXX */
- int block; /* What has to align with what? */
- Parrot_jit_optimizer_section_ptr branch_target;
- Parrot_jit_optimizer_section_ptr prev;
- Parrot_jit_optimizer_section_ptr next;
-} Parrot_jit_optimizer_section_t;
-
-/* Parrot_jit_optimizer_section_t
- * All the information related to optimizing the bytecode.
- *
- * sections: A pointer to the first section.
- * cur_section: Pointer to the current section.
- * map_branch: A pointer to an array with the size of the bytecode
- * where the positions of the opcodes will have a value
- * indicating if the opcode is a branch target, source
- * or isn't related with a control flow opcode at all,
- * and which register was allocated for each opcode
- * argument if any.
- * has_unpredictable_jump: XXX need to define how to handle this.
- */
-
-typedef struct Parrot_jit_optimizer_t {
- Parrot_jit_optimizer_section_t *sections;
- Parrot_jit_optimizer_section_t *cur_section;
- char *map_branch;
- opcode_t **branch_list;
- unsigned char has_unpredictable_jump;
- unsigned char dummy[3]; /* For alignment ??? XXX */
-} Parrot_jit_optimizer_t; /* What has to align with what? */
-
-/* Parrot_jit_constant_pool_t
- * Constants pool information.
- *
- */
-typedef struct Parrot_jit_constant_pool_t {
- long frames_used;
- long cur_used;
- char *cur_const;
- INTVAL *slot_ptr;
-} Parrot_jit_constant_pool_t;
-
-typedef enum {
- JIT_CODE_FILE,
- JIT_CODE_SUB,
- JIT_CODE_SUB_REGS_ONLY,
-
- /* size */
- JIT_CODE_TYPES,
- /* special cases */
- JIT_CODE_RECURSIVE = 0x10,
- JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
-} enum_jit_code_type;
-
-/* Parrot_jit_info_t
- * All the information needed to jit the bytecode will be here.
- *
- * prev_op: The previous opcode in this section.
- * cur_op: The current opcode during the build process.
- * op_i: Opcode index.
- * native_ptr: Current pointer to native code.
- * arena: The arena inlined, this will be the only one used in cases
- * where there is a way to load an immediate.
- * optimizer: Optimizer information.
- * constant_pool: The constant pool information.
- */
-
-typedef struct Parrot_jit_info_t {
- opcode_t *prev_op;
- opcode_t *cur_op;
- opcode_t op_i;
- char *native_ptr;
- Parrot_jit_arena_t arena;
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_constant_pool_t *constant_pool;
- INTVAL code_type;
- int flags;
- const struct jit_arch_info_t *arch_info;
- int n_args;
-#if EXEC_CAPABLE
- Parrot_exec_objfile_t *objfile;
-#else
- void *objfile;
-#endif /* EXEC_CAPABLE */
-} Parrot_jit_info_t;
-
-#define Parrot_jit_fixup_target(jit_info, fixup) \
- ((jit_info)->arena.start + (fixup)->native_offset)
-
-typedef void (*jit_fn_t)(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-/* Parrot_jit_fn_info_t
- * The table of opcodes.
- *
- * jit_fn_t: A pointer to the function that emits code for the opcode
- * or to the C funtion if the opcode is not jitted.
- * extcall: If the opcode makes an external call to a C funtion.
- * also used for vtable functions, extcall is #of vtable func
- */
-
-typedef struct Parrot_jit_fn_info_t {
- jit_fn_t fn;
- int extcall;
-} Parrot_jit_fn_info_t;
-
-PARROT_DATA Parrot_jit_fn_info_t *op_jit;
-extern Parrot_jit_fn_info_t op_exec[];
-
-PARROT_EXPORT void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info);
-
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-/*
- * interface functions for the register save/restore code
- * with offsets relative to the base register (obtained by
- * Parrot_jit_emit_get_base_reg_no)
- */
-void Parrot_jit_emit_mov_mr_n_offs(
- Interp *, int base_reg, size_t offs, int src_reg);
-void Parrot_jit_emit_mov_mr_offs(
- Interp *, int base_reg, size_t offs, int src_reg);
-void Parrot_jit_emit_mov_rm_n_offs(
- Interp *, int dst_reg, int base_reg, size_t offs);
-void Parrot_jit_emit_mov_rm_offs(
- Interp *, int dst_reg, int base_reg, size_t offs);
-
-/*
- * interface to architecture specific details
- */
-typedef void (*jit_arch_f)(Parrot_jit_info_t *, Interp *);
-
-typedef struct jit_arch_regs {
- /*
- * begin function - emit ABI call prologue
- */
- jit_arch_f jit_begin;
-
- int n_mapped_I;
- int n_preserved_I;
- const char *map_I;
- int n_mapped_F;
- int n_preserved_F;
- const char *map_F;
-} jit_arch_regs;
-
-typedef void (*mov_RM_f)(PARROT_INTERP, Parrot_jit_info_t *,
- int cpu_reg, int base_reg, INTVAL offs);
-typedef void (*mov_MR_f)(PARROT_INTERP, Parrot_jit_info_t *,
- int base_reg, INTVAL offs, int cpu_reg);
-
-typedef struct jit_arch_info_t {
- /* CPU <- Parrot reg move functions */
- mov_RM_f mov_RM_i;
- mov_RM_f mov_RM_n;
- /* Parrot <- CPU reg move functions */
- mov_MR_f mov_MR_i;
- mov_MR_f mov_MR_n;
-
- /* fixup branches and calls after codegen */
- jit_arch_f jit_dofixup;
- /* flush caches */
- jit_arch_f jit_flush_cache;
- /* register mapping info */
- const jit_arch_regs regs[JIT_CODE_TYPES];
-} jit_arch_info;
-
-/*
- * interface to create JIT code
- */
-Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP,
- opcode_t *code_start, opcode_t *code_end,
- void *objfile, INTVAL);
-/*
- * NCI interface
- */
-void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
-/* custom pmc callback functions */
-void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
-PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
-struct jit_buffer_private_data {
- int size;
-};
-
-#endif /* PARROT_JIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: branches/kill_jit/src/jit_debug.c
==============================================================================
--- branches/kill_jit/src/jit_debug.c Thu Sep 17 04:30:13 2009 (r41311)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,409 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit_debug.c - Write stabs file for JIT code
-
-=head1 SYNOPSIS
-
-When debugging JIT code with C<gdb>, do:
-
- add-symbol-file <file.o> 0
-
-=head1 DESCRIPTION
-
-Stabs is a file format for information that describes a program to a
-debugger.
-
-For more information see the stabs documentation at
-http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#include "parrot/exec.h"
-#include "jit.h"
-
-#define N_GSYM "32" /* global variable */
-#define N_FNAME "34"
-#define N_FUN "36"
-#define N_STSYM "38" /* variable in data section */
-#define N_LCSYM "40" /* bss section */
-#define N_MAIN "42"
-#define N_ROSYM "44"
-#define N_PC "48"
-#define N_NSYMS "50"
-#define N_NOMAP "52"
-#define N_OBJ "56"
-#define N_OPT "60"
-#define N_RSYM "64" /* register variable */
-#define N_M2C "66"
-#define N_SLINE "68"
-#define N_DSLINE "70"
-#define N_BSLINE "72"
-#define N_BROWS "72"
-#define N_DEFD "74"
-#define N_FLINE "76"
-#define N_EHDECL "80"
-#define N_MOD2 "80"
-#define N_CATCH "84"
-#define N_SSYM "96"
-#define N_ENDM "98"
-#define N_SO "100" /* filename */
-#define N_LSYM "128" /* stack variable */
-#define N_BINCL "130"
-#define N_SOL "132"
-#define N_PSYM "160" /* parameter */
-#define N_EINCL "162"
-#define N_ENTRY "164"
-#define N_LBRAC "192"
-#define N_EXCL "194"
-#define N_SCOPE "196"
-#define N_RBRAC "224"
-#define N_BCOMM "226"
-#define N_ECOMM "228"
-#define N_ECOML "232"
-#define N_WITH "234"
-#define N_NBTEXT "240"
-#define N_NBDATA "242"
-#define N_NBBSS "244"
-#define N_NBSTS "246"
-#define N_NBLCS "248"
-
-#ifdef __GNUC__
-void Parrot_jit_debug(PARROT_INTERP);
-
-# define BIT_SIZE(t) ((int)(sizeof (t)*8))
-# define BYTE_SIZE(t) ((int)sizeof (t))
-# define BIT_OFFSET(str, field) ((int)(offsetof(str, field) * 8))
-
-typedef struct BaseTypes {
- const char *name;
- const char *spec;
-} BaseTypes;
-
-/*
-
-=item C<static void write_types(FILE *stabs, PARROT_INTERP)>
-
-Writes the types to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_types(FILE *stabs, PARROT_INTERP)
-{
- /* It would be create if this function would be auto generated */
- int i, j;
- /* borrowed from mono */
- static BaseTypes base_types[] = {
- {"Void", "(0,1)"},
- {"Char", ";-128;127;"},
- {"Byte", ";0;255;"},
- {"Int16", ";-32768;32767;"},
- {"UInt16", ";0;65535;"},
- {"Int32", ";0020000000000;0017777777777;"}, /* 5 */
- {"UInt32", ";0000000000000;0037777777777;"},
- {"Int64", ";01000000000000000000000;0777777777777777777777;"},
- {"UInt64", ";0000000000000;01777777777777777777777;"},
- {"Single", "r(0,8);4;0;"},
- {"Double", "r(0,8);8;0;"}, /* 10 */
- {"LongDouble", "r(0,8);12;0;"},
-# if INTVAL_SIZE == 4
- {"INTVAL", "(0,5);"}, /* 12 */
-# else
- {"INTVAL", "(0,7);"},
-# endif
-# if NUMVAL_SIZE == 8
- {"FLOATVAL", "(0,10);"}, /* 13 */
-# else
- {"FLOATVAL", "(0,11);"},
-# endif
- {"Ptr", "*(0,0);"},
- {"CharPtr", "*(0,1);"}, /* 15 */
- {0, 0}
- };
- for (i = 0; base_types[i].name; ++i) {
- if (! base_types[i].spec)
- continue;
- fprintf(stabs, ".stabs \"%s:t(0,%d)=", base_types[i].name, i);
- if (base_types[i].spec [0] == ';') {
- fprintf(stabs, "r(0,%d)%s\"", i, base_types[i].spec);
- }
- else {
- fprintf(stabs, "%s\"", base_types[i].spec);
- }
- fprintf(stabs, "," N_LSYM ",0,0,0\n");
- }
- fprintf(stabs, ".stabs \"STRING:t(0,%d)=*(0,%d)\""
- "," N_LSYM ",0,0,0\n", i, i+1);
- ++i;
- fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d"
- "bufstart:(0,14),%d,%d;"
- "buflen:(0,6),%d,%d;"
- "flags:(0,12),%d,%d;"
- "bufused:(0,12),%d,%d;"
- "strstart:(0,15),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING),
- BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*),
- BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t),
- BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, strstart), BIT_SIZE(void*));
-
- fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++);
- for (j = 0; j < interp->n_vtable_max; ++j) {
- if (interp->vtables[j] && interp->vtables[j]->whoami) {
- STRING *name = interp->vtables[j]->whoami;
- size_t items = fwrite(name->strstart, name->strlen, 1, stabs);
- if (!items)
- fprintf(stderr, "Error writing stabs!\n");
- fprintf(stabs, ":%d,", j);
- }
- }
-
- fprintf(stabs, ";\"," N_LSYM ",0,0,0\n");
-
- fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d"
- "flags:(0,12),%d,%d;"
- "vtable:*(0,%d),%d,%d;"
- "data:(0,14),%d,%d;"
- "_metadata:*(0,%d),%d,%d;"
- "_next_for_GC:*(0,%d),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC),
- BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL),
- i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*),
- BIT_OFFSET(PMC, data), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*));
-
- i++;
-
- /* someone can add some field to this one */
- fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d"
- "base_type:(0,12),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable),
- BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL));
-
- i++;
-}
-
-/*
-
-=item C<static void
-write_vars(FILE *stabs, PARROT_INTERP)>
-
-Writes the contents of the registers to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_vars(FILE *stabs, PARROT_INTERP)
-{
- int i;
- /* fake static var stabs */
- for (i = 0; i < NUM_REGISTERS; i++) {
- fprintf(stabs, ".stabs \"I%d:S(0,12)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_INT(interp, i));
- fprintf(stabs, ".stabs \"N%d:S(0,13)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_NUM(interp, i));
- fprintf(stabs, ".stabs \"S%d:S(0,16)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_STR(interp, i));
- fprintf(stabs, ".stabs \"P%d:S*(0,19)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_PMC(interp, i));
- }
-}
-
-/*
-
-=item C<static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)>
-
-Returns C<file> with C<ext> appended.
-
-=cut
-
-*/
-
-static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)
-{
- STRING *ret;
- ret = Parrot_str_copy(interp, file);
- ret = Parrot_str_append(interp, ret,
- string_make(interp, ext, strlen(ext), NULL,
- PObj_external_FLAG));
- return ret;
-}
-
-/*
-
-=item C<static void
-Parrot_jit_debug_stabs(PARROT_INTERP)>
-
-Writes the JIT debugging stabs.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_debug_stabs(PARROT_INTERP)
-{
- Parrot_jit_info_t *jit_info = interp->code->jit_info;
- STRING *file = NULL;
- STRING *pasmfile, *stabsfile, *ofile, *cmd;
- FILE *stabs;
- size_t i;
- int line;
- opcode_t lc;
- PackFile_Debug *debug;
-
- if (interp->code->debugs) {
- char *ext;
- char * const src = Parrot_str_to_cstring(interp,
- Parrot_debug_pc_to_filename(interp,
- interp->code->debugs, 0));
- pasmfile = string_make(interp, src, strlen(src), NULL,
- PObj_external_FLAG);
- file = Parrot_str_copy(interp, pasmfile);
- /* chop pasm/pir */
-
- ext = strrchr(src, '.');
- if (ext && STREQ(ext, ".pasm"))
- Parrot_str_chopn_inplace(interp, file, 4);
- else if (ext && STREQ(ext, ".pir"))
- Parrot_str_chopn_inplace(interp, file, 3);
- else if (!ext) /* EVAL_n */
- file = Parrot_str_append(interp, file,
- string_make(interp, ".", 1, NULL, PObj_external_FLAG));
-
- Parrot_str_free_cstring(src);
- }
- else {
- /* chop pbc */
- Parrot_str_chopn_inplace(interp, file, 3);
- pasmfile = debug_file(interp, file, "pasm");
- }
- stabsfile = debug_file(interp, file, "stabs.s");
- ofile = debug_file(interp, file, "o");
- {
- char *const temp = Parrot_str_to_cstring(interp, stabsfile);
- stabs = fopen(temp, "w");
- Parrot_str_free_cstring(temp);
- }
- if (stabs == NULL)
- return;
-
- {
- char * const temp = Parrot_str_to_cstring(interp, pasmfile);
- /* filename info */
- fprintf(stabs, ".data\n.text\n"); /* darwin wants it */
- fprintf(stabs, ".stabs \"%s\"," N_SO ",0,0,0\n", temp);
- Parrot_str_free_cstring(temp);
- }
- /* jit_func start addr */
- fprintf(stabs, ".stabs \"jit_func:F(0,1)\"," N_FUN ",0,1,%p\n",
- jit_info->arena.start);
-
- write_types(stabs, interp);
- write_vars(stabs, interp);
- /* if we don't have line numbers, emit dummys, assuming there are
- * no comments and spaces in source for testing
- */
-
- /* jit_begin */
- fprintf(stabs, ".stabn " N_SLINE ",0,1,0\n");
- line = 1;
- lc = 0;
- debug = interp->code->debugs;
- for (i = 0; i < interp->code->base.size; i++) {
- if (jit_info->arena.op_map[i].ptr) {
- op_info_t* op = &interp->op_info_table[
- interp->code->base.data[i]];
- if (interp->code->debugs) {
- if (lc >= (int)(debug->base.size))
- break;
- line = (int)debug->base.data[lc++];
- }
- fprintf(stabs, ".stabn " N_SLINE ",0,%d,%d /* %s */\n", line,
- (int)((char *)jit_info->arena.op_map[i].ptr -
- (char *)jit_info->arena.start),
- op->full_name);
- line++;
- }
- }
- /* eof */
- fprintf(stabs, ".stabs \"\"," N_FUN ",0,1,%p\n",
- (char *) jit_info->arena.size);
- fclose(stabs);
-
- /* run the stabs file through C<as> generating file.o */
- cmd = Parrot_sprintf_c(interp, "as %Ss -o %Ss", stabsfile, ofile);
-
- {
- char * const temp = Parrot_str_to_cstring(interp, cmd);
- int status = system(temp);
- if (status)
- fprintf(stderr, "Assembly failed: %d\n%s\n", status, temp);
- Parrot_str_free_cstring(temp);
- }
-}
-
-/*
-
-=item C<void
-Parrot_jit_debug(PARROT_INTERP)>
-
-Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
-
-=cut
-
-*/
-
-void
-Parrot_jit_debug(PARROT_INTERP)
-{
- Parrot_jit_debug_stabs(interp);
-}
-
-
-#endif
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit.c>, F<include/parrot/jit.h>, F<docs/jit.pod>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: branches/kill_jit/src/jit_debug_xcoff.c
==============================================================================
--- branches/kill_jit/src/jit_debug_xcoff.c Thu Sep 17 04:30:13 2009 (r41311)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,375 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit_debug_xcoff.c - XCOFF stabs for JIT
-
-=head1 DESCRIPTION
-
-Write an XCOFF stabs file for JIT code. This file is based on
-F<src/jit_debug.c>.
-
-Stabs is a file format for information that describes a program to a
-debugger.
-
-For more information see the stabs documentation at
-http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#include "parrot/exec.h"
-#include "jit.h"
-
-#ifdef __IBMC__
-
-/* following from /usr/include/dbxstclass.h */
-# define C_GSYM "0x80" /* global variable */
-# define C_LSYM "0x81" /* stack variable */
-# define C_PSYM "0x82" /* parameter */
-# define C_RSYM "0x83" /* register variable */
-# define C_RPSYM "0x84"
-# define C_STSYM "0x85" /* variable in data section */
-# define C_TCSYM "0x86"
-# define C_BCOMM "0x87"
-# define C_ECOML "0x88"
-# define C_ECOMM "0x89"
-# define C_DECL "0x8c" /* type declaration */
-# define C_ENTRY "0x8d"
-# define C_FUN "0x8e"
-# define C_BSTAT "0x8f"
-# define C_ESTAT "0x90"
-
-void Parrot_jit_debug(PARROT_INTERP);
-
-# define BIT_SIZE(t) ((int)(sizeof (t)*8))
-# define BYTE_SIZE(t) ((int)sizeof (t))
-# define BIT_OFFSET(str, field) ((int)(offsetof((str), (field)) * 8))
-
-typedef struct BaseTypes {
- const char *name;
- const char *spec;
-} BaseTypes;
-
-/*
-
-=item C<static void write_types(FILE *stabs, PARROT_INTERP)>
-
-Writes the types to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_types(FILE *stabs, PARROT_INTERP)
-{
- int i, j;
- /* borrowed from mono */
- static BaseTypes base_types[] = {
- {"Char", "-6"},
- {"Byte", "-5"},
- {"Int16", "-3"},
- {"UInt16", "-7"},
- {"Int32", "-1"}, /* 5 */
- {"UInt32", "-8"},
- {"Int64", ";01000000000000000000000;0777777777777777777777;"},
- {"UInt64", ";0000000000000;01777777777777777777777;"},
- {"Single", "-12"},
- {"Double", "-13"}, /* 10 */
- {"LongDouble", "-14"},
-# if INTVAL_SIZE == 4
- {"INTVAL", "5;"}, /* 12 */
-# else
- {"INTVAL", "7;"},
-# endif
-# if NUMVAL_SIZE == 8
- {"FLOATVAL", "10;"}, /* 13 */
-# else
- {"FLOATVAL", "11;"},
-# endif
- {"Ptr", "*0;"},
- {"CharPtr", "*1;"}, /* 15 */
- {0, 0}
- };
- for (i = 0; base_types[i].name; ++i) {
- if (! base_types[i].spec)
- continue;
- fprintf(stabs, ".stabx \"%s:t%d=", base_types[i].name, i);
- if (base_types[i].spec [0] == ';') {
- fprintf(stabs, "r%d%s\"", i, base_types[i].spec);
- }
- else {
- fprintf(stabs, "%s\"", base_types[i].spec);
- }
- fprintf(stabs, ",0," C_DECL ",0\n");
- }
- fprintf(stabs, ".stabx \"STRING:t%d=*%d\""
- ",0," C_DECL ",0\n", i, i+1);
- ++i;
- fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d"
- "bufstart:(0,14),%d,%d;"
- "buflen:(0,6),%d,%d;"
- "flags:(0,12),%d,%d;"
- "bufused:(0,12),%d,%d;"
- "strstart:(0,15),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING),
- BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*),
- BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t),
- BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, strstart), BIT_SIZE(void*));
-
- fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++);
- for (j = 0; j < interp->n_vtable_max; ++j) {
- if (interp->vtables[j] && interp->vtables[j]->whoami) {
- STRING *name = interp->vtables[j]->whoami;
- size_t items = fwrite(name->strstart, name->strlen, 1, stabs);
- if (!items)
- fprintf(stderr, "Error writing stabs!\n");
- fprintf(stabs, ":%d,", j);
- }
- }
-
- fprintf(stabs, ";\"," N_LSYM ",0,0,0\n");
-
- fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d"
- "flags:(0,12),%d,%d;"
- "vtable:*(0,%d),%d,%d;"
- "data:(0,14),%d,%d;"
- "_metadata:*(0,%d),%d,%d;"
- "_next_for_GC:*(0,%d),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC),
- BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL),
- i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*),
- BIT_OFFSET(PMC, data), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*));
-
- i++;
-
- /* some one can add some field to this one */
- fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d"
- "base_type:(0,12),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable),
- BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL));
-
- i++;
-
-}
-
-/*
-
-=item C<static void
-write_vars(FILE *stabs, PARROT_INTERP)>
-
-Writes the contents of the registers to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_vars(FILE *stabs, PARROT_INTERP)
-{
- int i;
- /* fake static var stabs */
- fprintf(stabs, ".bs parrot_jit_vars\n");
- for (i = 0; i < NUM_REGISTERS; i++) {
- fprintf(stabs, ".stabx \"I%d:V12\",0x%p," C_STSYM ",0\n", i,
- (char*)®_INT(interp, i));
- fprintf(stabs, ".stabx \"N%d:V13\",0x%p," C_STSYM ",0\n", i,
- (char*)®_NUM(interp, i));
- fprintf(stabs, ".stabx \"S%d:V16\",0x%p," C_STSYM ",0\n", i,
- (char*)®_STR(interp, i));
- fprintf(stabs, ".stabx \"P%d:V19\",0x%p," C_STSYM ",0\n", i,
- (char*)®_PMC(interp, i));
- }
- fprintf(stabs, ".es\n");
-}
-
-/*
-
-=item C<static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)>
-
-Returns C<file> with C<ext> appended.
-
-=cut
-
-*/
-
-static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)
-{
- STRING *ret;
- ret = Parrot_str_copy(interp, file);
- ret = Parrot_str_append(interp, ret,
- string_make(interp, ext, strlen(ext), NULL,
- PObj_external_FLAG));
- return ret;
-}
-
-/*
-
-=item C<static void
-Parrot_jit_debug_stabs(PARROT_INTERP)>
-
-Writes the JIT debugging stabs.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_debug_stabs(PARROT_INTERP)
-{
- Parrot_jit_info_t *jit_info = interp->jit_info;
- STRING *file = NULL;
- STRING *pasmfile, *stabsfile, *ofile, *cmd;
- FILE *stabs;
- size_t i;
- int line;
- opcode_t lc;
-
- if (interp->code->debugs) {
- char *ext;
- char * const src = Parrot_str_to_cstring(interp,
- Parrot_debug_pc_to_filename(interp,
- interp->code->debugs, 0));
- pasmfile = string_make(interp, src, strlen(src), NULL,
- PObj_external_FLAG);
- file = Parrot_str_copy(interp, pasmfile);
- /* chop pasm/pir */
-
- ext = strrchr(src, '.');
- if (ext && STREQ(ext, ".pasm"))
- Parrot_str_chopn_inplace(interp, file, 4);
- else if (ext && STREQ(ext, ".pir"))
- Parrot_str_chopn_inplace(interp, file, 3);
- else if (!ext) /* EVAL_n */
- file = Parrot_str_append(interp, file,
- string_make(interp, ".", 1, NULL, PObj_external_FLAG));
- Parrot_str_free_cstring(src);
- }
- else {
- /* chop pbc */
- Parrot_str_chopn_inplace(interp, file, 3);
- pasmfile = debug_file(interp, file, "pasm");
- }
- stabsfile = debug_file(interp, file, "stabs.s");
- ofile = debug_file(interp, file, "o");
- {
- char * const temp = Parrot_str_to_cstring(interp, stabsfile);
- stabs = fopen(temp, "w");
- Parrot_str_free_cstring(temp);
- }
- if (stabs == NULL)
- return;
-
- {
- char * const temp = Parrot_str_to_cstring(interp, pasmfile);
- /* filename info */
- fprintf(stabs, ".file \"%s\"\n", temp);
- Parrot_str_free_cstring(temp);
- }
- /* declare function name */
- fprintf(stabs, ".jit_func:\n");
- /* jit_func start addr */
- fprintf(stabs, ".stabx \"jit_func:F1\",0x%p," C_FUN ",0\n",
- jit_info->arena.start);
- fprintf(stabs, ".function .jit_func,.jit_func,0,0\n");
- fprintf(stabs, ".bf 1\n");
-
- write_types(stabs, interp);
- write_vars(stabs, interp);
- /* if we don't have line numbers, emit dummys, assuming there are
- * no comments and spaces in source for testing
- */
-
- /* jit_begin */
- fprintf(stabs, ".line 1\n");
- line = 1;
- lc = 0;
- for (i = 0; i < interp->code->base.size; i++) {
- if (jit_info->arena.op_map[i].ptr) {
- op_info_t* op = &interp->op_info_table[
- interp->code->base.data[i]];
- if (interp->code->debugs) {
- line = (int)interp->code->debugs->base.data[lc++];
- }
- fprintf(stabs, ".line %d # 0x%p %s\n", line,
- (int)((char *)jit_info->arena.op_map[i].ptr -
- (char *)jit_info->arena.start),
- op->full_name);
- line++;
- }
- }
- /* eof */
- fprintf(stabs, ".stabx \"\",0x%p," C_FUN ",0\n",
- (char *) jit_info->arena.size);
- fprintf(stabs, ".ef %d\n", line);
- fclose(stabs);
- /* run the stabs file through C<as> generating file.o */
- cmd = Parrot_sprintf_c(interp, "as %Ss -o %Ss", stabsfile, ofile);
-
- {
- char * const temp = Parrot_str_to_cstring(interp, cmd);
- system(temp);
- Parrot_str_free_cstring(temp);
- }
-}
-
-/*
-
-=item C<void
-Parrot_jit_debug(PARROT_INTERP)>
-
-Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
-
-=cut
-
-*/
-
-void
-Parrot_jit_debug(PARROT_INTERP)
-{
- Parrot_jit_debug_stabs(interp);
-}
-
-#endif
-
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit_debug.c>, F<src/jit.c>, F<src/jit.h>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Modified: branches/kill_jit/src/packfile.c
==============================================================================
--- branches/kill_jit/src/packfile.c Thu Sep 17 03:08:51 2009 (r41311)
+++ branches/kill_jit/src/packfile.c Thu Sep 17 04:30:13 2009 (r41312)
@@ -29,7 +29,6 @@
#include "parrot/extend.h"
#include "parrot/packfile.h"
#include "parrot/runcore_api.h"
-#include "jit.h"
#include "../compilers/imcc/imc.h"
#include "packfile.str"
#include "pmc/pmc_sub.h"
Modified: branches/kill_jit/tools/build/nativecall.pl
==============================================================================
--- branches/kill_jit/tools/build/nativecall.pl Thu Sep 17 03:08:51 2009 (r41311)
+++ branches/kill_jit/tools/build/nativecall.pl Thu Sep 17 04:30:13 2009 (r41312)
@@ -219,7 +219,6 @@
#include "pmc/pmc_nci.h"
#include "pmc/pmc_pointer.h"
#include "nci.str"
-#include "jit.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER STOP */
@@ -235,117 +234,11 @@
# include "frame_builder.h"
#endif
-/*
- * helper funcs - get argument n
- */
-static INTVAL
-get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_int(st->val);
-}
-
-static FLOATVAL
-get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_num(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING*
-get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /* TODO or act like below? */
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_str(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC*
-get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /*
- * excessive args are passed as NULL
- * used by e.g. MMD infix like __add
- */
- if (n < st->src.n)
- Parrot_fetch_arg_nci(interp, st);
- else
- UVal_pmc(st->val) = PMCNULL;
-
- return UVal_pmc(st->val);
-}
-
#define GET_NCI_I(n) get_nci_I(interp, &st, n)
#define GET_NCI_S(n) get_nci_S(interp, &st, n)
#define GET_NCI_N(n) get_nci_N(interp, &st, n)
#define GET_NCI_P(n) get_nci_P(interp, &st, n)
-/*
- * set return value
- */
-static void
-set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
-{
- Parrot_init_ret_nci(interp, st, "I");
- if (st->dest.i < st->dest.n) {
- UVal_int(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
-{
- Parrot_init_ret_nci(interp, st, "N");
- if (st->dest.i < st->dest.n) {
- UVal_num(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
-{
- Parrot_init_ret_nci(interp, st, "S");
- if (st->dest.i < st->dest.n) {
- UVal_str(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
-{
- Parrot_init_ret_nci(interp, st, "P");
- if (st->dest.i < st->dest.n) {
- UVal_pmc(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
#ifndef CAN_BUILD_CALL_FRAMES
/* All our static functions that call in various ways. Yes, terribly
hackish, but that is just fine */
More information about the parrot-commits
mailing list