summaryrefslogtreecommitdiff
path: root/yjit_core.h
diff options
context:
space:
mode:
Diffstat (limited to 'yjit_core.h')
-rw-r--r--yjit_core.h306
1 files changed, 0 insertions, 306 deletions
diff --git a/yjit_core.h b/yjit_core.h
deleted file mode 100644
index 299dae81f5..0000000000
--- a/yjit_core.h
+++ /dev/null
@@ -1,306 +0,0 @@
-#ifndef YJIT_CORE_H
-#define YJIT_CORE_H 1
-
-#include <stddef.h>
-#include <stdint.h>
-#include "yjit_asm.h"
-
-// Callee-saved regs
-#define REG_CFP R13
-#define REG_EC R12
-#define REG_SP RBX
-
-// Scratch registers used by YJIT
-#define REG0 RAX
-#define REG0_32 EAX
-#define REG0_8 AL
-#define REG1 RCX
-#define REG1_32 ECX
-
-// Maximum number of temp value types we keep track of
-#define MAX_TEMP_TYPES 8
-
-// Maximum number of local variable types we keep track of
-#define MAX_LOCAL_TYPES 8
-
-// Default versioning context (no type information)
-#define DEFAULT_CTX ( (ctx_t){ 0 } )
-
-enum yjit_type_enum
-{
- ETYPE_UNKNOWN = 0,
- ETYPE_NIL,
- ETYPE_TRUE,
- ETYPE_FALSE,
- ETYPE_FIXNUM,
- ETYPE_FLONUM,
- ETYPE_ARRAY,
- ETYPE_HASH,
- ETYPE_SYMBOL,
- ETYPE_STRING
-};
-
-// Represent the type of a value (local/stack/self) in YJIT
-typedef struct yjit_type_struct
-{
- // Value is definitely a heap object
- uint8_t is_heap : 1;
-
- // Value is definitely an immediate
- uint8_t is_imm : 1;
-
- // Specific value type, if known
- uint8_t type : 4;
-
-} val_type_t;
-STATIC_ASSERT(val_type_size, sizeof(val_type_t) == 1);
-
-// Unknown type, could be anything, all zeroes
-#define TYPE_UNKNOWN ( (val_type_t){ 0 } )
-
-// Could be any heap object
-#define TYPE_HEAP ( (val_type_t){ .is_heap = 1 } )
-
-// Could be any immediate
-#define TYPE_IMM ( (val_type_t){ .is_imm = 1 } )
-
-#define TYPE_NIL ( (val_type_t){ .is_imm = 1, .type = ETYPE_NIL } )
-#define TYPE_TRUE ( (val_type_t){ .is_imm = 1, .type = ETYPE_TRUE } )
-#define TYPE_FALSE ( (val_type_t){ .is_imm = 1, .type = ETYPE_FALSE } )
-#define TYPE_FIXNUM ( (val_type_t){ .is_imm = 1, .type = ETYPE_FIXNUM } )
-#define TYPE_FLONUM ( (val_type_t){ .is_imm = 1, .type = ETYPE_FLONUM } )
-#define TYPE_STATIC_SYMBOL ( (val_type_t){ .is_imm = 1, .type = ETYPE_SYMBOL } )
-#define TYPE_ARRAY ( (val_type_t){ .is_heap = 1, .type = ETYPE_ARRAY } )
-#define TYPE_HASH ( (val_type_t){ .is_heap = 1, .type = ETYPE_HASH } )
-#define TYPE_STRING ( (val_type_t){ .is_heap = 1, .type = ETYPE_STRING } )
-
-enum yjit_temp_loc
-{
- TEMP_STACK = 0,
- TEMP_SELF,
- TEMP_LOCAL, // Local with index
- //TEMP_CONST, // Small constant (0, 1, 2, Qnil, Qfalse, Qtrue)
-};
-
-// Potential mapping of a value on the temporary stack to
-// self, a local variable or constant so that we can track its type
-typedef struct yjit_temp_mapping
-{
- // Where/how is the value stored?
- uint8_t kind: 2;
-
- // Index of the local variale,
- // or small non-negative constant in [0, 63]
- uint8_t idx : 6;
-
-} temp_mapping_t;
-STATIC_ASSERT(temp_mapping_size, sizeof(temp_mapping_t) == 1);
-
-// By default, temps are just temps on the stack.
-// Name conflict with an mmap flag. This is a struct instance,
-// so the compiler will check for wrong usage.
-#undef MAP_STACK
-#define MAP_STACK ( (temp_mapping_t) { 0 } )
-
-// Temp value is actually self
-#define MAP_SELF ( (temp_mapping_t) { .kind = TEMP_SELF } )
-
-// Represents both the type and mapping
-typedef struct {
- temp_mapping_t mapping;
- val_type_t type;
-} temp_type_mapping_t;
-STATIC_ASSERT(temp_type_mapping_size, sizeof(temp_type_mapping_t) == 2);
-
-// Operand to a bytecode instruction
-typedef struct yjit_insn_opnd
-{
- // Indicates if the value is self
- bool is_self;
-
- // Index on the temporary stack (for stack operands only)
- uint16_t idx;
-
-} insn_opnd_t;
-
-#define OPND_SELF ( (insn_opnd_t){ .is_self = true } )
-#define OPND_STACK(stack_idx) ( (insn_opnd_t){ .is_self = false, .idx = stack_idx } )
-
-/**
-Code generation context
-Contains information we can use to optimize code
-*/
-typedef struct yjit_context
-{
- // Number of values currently on the temporary stack
- uint16_t stack_size;
-
- // Offset of the JIT SP relative to the interpreter SP
- // This represents how far the JIT's SP is from the "real" SP
- int16_t sp_offset;
-
- // Depth of this block in the sidechain (eg: inline-cache chain)
- uint8_t chain_depth;
-
- // Local variable types we keepp track of
- val_type_t local_types[MAX_LOCAL_TYPES];
-
- // Temporary variable types we keep track of
- val_type_t temp_types[MAX_TEMP_TYPES];
-
- // Type we track for self
- val_type_t self_type;
-
- // Mapping of temp stack entries to types we track
- temp_mapping_t temp_mapping[MAX_TEMP_TYPES];
-
-} ctx_t;
-STATIC_ASSERT(yjit_ctx_size, sizeof(ctx_t) <= 32);
-
-// Tuple of (iseq, idx) used to identify basic blocks
-typedef struct BlockId
-{
- // Instruction sequence
- const rb_iseq_t *iseq;
-
- // Index in the iseq where the block starts
- uint32_t idx;
-
-} blockid_t;
-
-// Null block id constant
-static const blockid_t BLOCKID_NULL = { 0, 0 };
-
-/// Branch code shape enumeration
-typedef enum branch_shape
-{
- SHAPE_NEXT0, // Target 0 is next
- SHAPE_NEXT1, // Target 1 is next
- SHAPE_DEFAULT // Neither target is next
-} branch_shape_t;
-
-// Branch code generation function signature
-typedef void (*branchgen_fn)(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t shape);
-
-/**
-Store info about an outgoing branch in a code segment
-Note: care must be taken to minimize the size of branch_t objects
-*/
-typedef struct yjit_branch_entry
-{
- // Block this is attached to
- struct yjit_block_version *block;
-
- // Positions where the generated code starts and ends
- uint8_t *start_addr;
- uint8_t *end_addr;
-
- // Context right after the branch instruction
- ctx_t src_ctx;
-
- // Branch target blocks and their contexts
- blockid_t targets[2];
- ctx_t target_ctxs[2];
- struct yjit_block_version *blocks[2];
-
- // Jump target addresses
- uint8_t *dst_addrs[2];
-
- // Branch code generation function
- branchgen_fn gen_fn;
-
- // Shape of the branch
- branch_shape_t shape : 2;
-
-} branch_t;
-
-// In case this block is invalidated, these two pieces of info
-// help to remove all pointers to this block in the system.
-typedef struct {
- VALUE receiver_klass;
- VALUE callee_cme;
-} cme_dependency_t;
-
-typedef rb_darray(cme_dependency_t) cme_dependency_array_t;
-
-typedef rb_darray(branch_t*) branch_array_t;
-
-typedef rb_darray(uint32_t) int32_array_t;
-
-/**
-Basic block version
-Represents a portion of an iseq compiled with a given context
-Note: care must be taken to minimize the size of block_t objects
-*/
-typedef struct yjit_block_version
-{
- // Bytecode sequence (iseq, idx) this is a version of
- blockid_t blockid;
-
- // Context at the start of the block
- ctx_t ctx;
-
- // Positions where the generated code starts and ends
- uint8_t *start_addr;
- uint8_t *end_addr;
-
- // List of incoming branches (from predecessors)
- branch_array_t incoming;
-
- // List of outgoing branches (to successors)
- // Note: these are owned by this block version
- branch_array_t outgoing;
-
- // Offsets for GC managed objects in the mainline code block
- int32_array_t gc_object_offsets;
-
- // CME dependencies of this block, to help to remove all pointers to this
- // block in the system.
- cme_dependency_array_t cme_dependencies;
-
- // Code address of an exit for `ctx` and `blockid`. Used for block
- // invalidation.
- uint8_t *entry_exit;
-
- // Index one past the last instruction in the iseq
- uint32_t end_idx;
-
-} block_t;
-
-// Code generation state
-typedef struct JITState
-{
- // Inline and outlined code blocks we are
- // currently generating code into
- codeblock_t* cb;
- codeblock_t* ocb;
-
- // Block version being compiled
- block_t *block;
-
- // Instruction sequence this is associated with
- const rb_iseq_t *iseq;
-
- // Index of the current instruction being compiled
- uint32_t insn_idx;
-
- // Opcode for the instruction being compiled
- int opcode;
-
- // PC of the instruction being compiled
- VALUE *pc;
-
- // Side exit to the instruction being compiled. See :side-exit:.
- uint8_t *side_exit_for_pc;
-
- // Execution context when compilation started
- // This allows us to peek at run-time values
- rb_execution_context_t *ec;
-
- // Whether we need to record the code address at
- // the end of this bytecode instruction for global invalidation
- bool record_boundary_patch_point;
-
-} jitstate_t;
-
-#endif // #ifndef YJIT_CORE_H