Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Created September 7, 2020 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/5541873da1f7ebfd201652d7a6d1ddda to your computer and use it in GitHub Desktop.
Save MasterDuke17/5541873da1f7ebfd201652d7a6d1ddda to your computer and use it in GitHub Desktop.
diff --git build/Makefile.in build/Makefile.in
index cd334f776..057877762 100644
--- build/Makefile.in
+++ build/Makefile.in
@@ -198,7 +198,6 @@ OBJECTS2 = src/6model/reprs/MVMDLLSym@obj@ \
src/spesh/dump@obj@ \
src/spesh/graph@obj@ \
src/spesh/codegen@obj@ \
- src/spesh/candidate@obj@ \
src/spesh/manipulate@obj@ \
src/spesh/args@obj@ \
src/spesh/usages@obj@ \
@@ -221,6 +220,7 @@ OBJECTS2 = src/6model/reprs/MVMDLLSym@obj@ \
src/spesh/plugin@obj@ \
src/spesh/frame_walker@obj@ \
src/spesh/pea@obj@ \
+ src/6model/reprs/MVMSpeshCandidate@obj@ \
src/strings/decode_stream@obj@ \
src/strings/ascii@obj@ \
src/strings/parse_num@obj@ \
@@ -376,7 +376,6 @@ HEADERS = src/moar.h \
src/spesh/debug.h \
src/spesh/graph.h \
src/spesh/codegen.h \
- src/spesh/candidate.h \
src/spesh/manipulate.h \
src/spesh/args.h \
src/spesh/usages.h \
@@ -397,6 +396,7 @@ HEADERS = src/moar.h \
src/spesh/plugin.h \
src/spesh/frame_walker.h \
src/spesh/pea.h \
+ src/6model/reprs/MVMSpeshCandidate.h \
src/strings/unicode_gen.h \
src/strings/normalize.h \
src/strings/decode_stream.h \
diff --git src/6model/bootstrap.c src/6model/bootstrap.c
index 46020e0c1..689fa5860 100644
--- src/6model/bootstrap.c
+++ src/6model/bootstrap.c
@@ -642,6 +642,7 @@ void MVM_6model_bootstrap(MVMThreadContext *tc) {
create_stub_boot_type(tc, MVM_REPR_ID_MVMSpeshLog, SpeshLog, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
create_stub_boot_type(tc, MVM_REPR_ID_MVMStaticFrameSpesh, StaticFrameSpesh, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
create_stub_boot_type(tc, MVM_REPR_ID_MVMSpeshPluginState, SpeshPluginState, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
+ //create_stub_boot_type(tc, MVM_REPR_ID_MVMSpeshCandidate, SpeshCandidate, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
/* Bootstrap the KnowHOW type, giving it a meta-object. */
bootstrap_KnowHOW(tc);
@@ -678,6 +679,7 @@ void MVM_6model_bootstrap(MVMThreadContext *tc) {
meta_objectifier(tc, SpeshLog, "SpeshLog");
meta_objectifier(tc, StaticFrameSpesh, "StaticFrameSpesh");
meta_objectifier(tc, SpeshPluginState, "SpeshPluginState");
+ //meta_objectifier(tc, SpeshCandidate, "SpeshCandidate");
/* Create the KnowHOWAttribute type. */
create_KnowHOWAttribute(tc);
diff --git src/6model/reprs.c src/6model/reprs.c
index 23f28cf08..bf2ff14bf 100644
--- src/6model/reprs.c
+++ src/6model/reprs.c
@@ -288,6 +288,7 @@ void MVM_repr_initialize_registry(MVMThreadContext *tc) {
register_core_repr(Decoder);
register_core_repr(StaticFrameSpesh);
register_core_repr(SpeshPluginState);
+ register_core_repr(SpeshCandidate);
assert(tc->instance->num_reprs == MVM_REPR_CORE_COUNT);
}
diff --git src/6model/reprs.h src/6model/reprs.h
index f2e4acdf8..677012fcf 100644
--- src/6model/reprs.h
+++ src/6model/reprs.h
@@ -45,6 +45,7 @@
#include "6model/reprs/MVMSpeshLog.h"
#include "6model/reprs/MVMStaticFrameSpesh.h"
#include "6model/reprs/MVMSpeshPluginState.h"
+#include "6model/reprs/MVMSpeshCandidate.h"
/* REPR related functions. */
void MVM_repr_initialize_registry(MVMThreadContext *tc);
@@ -100,8 +101,9 @@ const MVMREPROps * MVM_repr_get_by_name(MVMThreadContext *tc, MVMString *name);
#define MVM_REPR_ID_Decoder 43
#define MVM_REPR_ID_MVMStaticFrameSpesh 44
#define MVM_REPR_ID_MVMSpeshPluginState 45
+#define MVM_REPR_ID_MVMSpeshCandidate 46
-#define MVM_REPR_CORE_COUNT 46
+#define MVM_REPR_CORE_COUNT 47
#define MVM_REPR_MAX_COUNT 64
/* Default attribute functions for a REPR that lacks them. */
diff --git src/6model/reprs/MVMContext.c src/6model/reprs/MVMContext.c
index 0b9e99d8f..1e1f20022 100644
--- src/6model/reprs/MVMContext.c
+++ src/6model/reprs/MVMContext.c
@@ -275,11 +275,11 @@ static void snapshot_frame_callees(MVMThreadContext *tc, MVMFrame *f) {
MVMSpeshCandidate *cand = f->caller->spesh_cand;
MVMFrameExtra *extra = MVM_frame_extra(tc, f);
extra->caller_info_needed = 1;
- if (cand && cand->num_inlines) {
- if (cand->jitcode) {
+ if (cand && cand->body.num_inlines) {
+ if (cand->body.jitcode) {
if (extra->caller_jit_position)
return;
- extra->caller_jit_position = MVM_jit_code_get_current_position(tc, cand->jitcode, f->caller);
+ extra->caller_jit_position = MVM_jit_code_get_current_position(tc, cand->body.jitcode, f->caller);
}
else {
if (extra->caller_deopt_idx)
diff --git src/6model/reprs/MVMStaticFrameSpesh.c src/6model/reprs/MVMStaticFrameSpesh.c
index 7fe4127c4..86d5432b1 100644
--- src/6model/reprs/MVMStaticFrameSpesh.c
+++ src/6model/reprs/MVMStaticFrameSpesh.c
@@ -28,20 +28,9 @@ static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorkli
MVM_spesh_stats_gc_mark(tc, body->spesh_stats, worklist);
MVM_spesh_arg_guard_gc_mark(tc, body->spesh_arg_guard, worklist);
if (body->num_spesh_candidates) {
- MVMuint32 i, j;
+ MVMuint32 i;
for (i = 0; i < body->num_spesh_candidates; i++) {
- if (body->spesh_candidates[i]->type_tuple) {
- for (j = 0; j < body->spesh_candidates[i]->cs->flag_count; j++) {
- MVM_gc_worklist_add(tc, worklist,
- &body->spesh_candidates[i]->type_tuple[j].type);
- MVM_gc_worklist_add(tc, worklist,
- &body->spesh_candidates[i]->type_tuple[j].decont_type);
- }
- }
- for (j = 0; j < body->spesh_candidates[i]->num_spesh_slots; j++)
- MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]->spesh_slots[j]);
- for (j = 0; j < body->spesh_candidates[i]->num_inlines; j++)
- MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]->inlines[j].sf);
+ MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]);
}
}
MVM_gc_worklist_add(tc, worklist, &body->plugin_state);
@@ -50,16 +39,9 @@ static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorkli
/* Called by the VM in order to free memory associated with this object. */
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
MVMStaticFrameSpesh *sfs = (MVMStaticFrameSpesh *)obj;
- MVMuint32 i;
MVM_spesh_stats_destroy(tc, sfs->body.spesh_stats);
MVM_free(sfs->body.spesh_stats);
MVM_spesh_arg_guard_destroy(tc, sfs->body.spesh_arg_guard, 0);
- for (i = 0; i < sfs->body.num_spesh_candidates; i++)
- MVM_spesh_candidate_destroy(tc, sfs->body.spesh_candidates[i]);
- if (sfs->body.spesh_candidates)
- MVM_fixed_size_free(tc, tc->instance->fsa,
- sfs->body.num_spesh_candidates * sizeof(MVMSpeshCandidate *),
- sfs->body.spesh_candidates);
}
static const MVMStorageSpec storage_spec = {
@@ -95,25 +77,25 @@ static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data)
for (spesh_idx = 0; spesh_idx < body->num_spesh_candidates; spesh_idx++) {
MVMSpeshCandidate *cand = body->spesh_candidates[spesh_idx];
- size += cand->bytecode_size;
+ size += cand->body.bytecode_size;
- size += sizeof(MVMFrameHandler) * cand->num_handlers;
+ size += sizeof(MVMFrameHandler) * cand->body.num_handlers;
- size += sizeof(MVMCollectable *) * cand->num_spesh_slots;
+ size += sizeof(MVMCollectable *) * cand->body.num_spesh_slots;
- size += sizeof(MVMint32) * cand->num_deopts;
+ size += sizeof(MVMint32) * cand->body.num_deopts;
- size += sizeof(MVMSpeshInline) * cand->num_inlines;
+ size += sizeof(MVMSpeshInline) * cand->body.num_inlines;
- size += sizeof(MVMuint16) * (cand->num_locals + cand->num_lexicals);
+ size += sizeof(MVMuint16) * (cand->body.num_locals + cand->body.num_lexicals);
/* XXX probably don't need to measure the bytecode size here,
* as it's probably just a pointer to the same bytecode we have in
* the static frame anyway. */
/* Dive into the jit code */
- if (cand->jitcode) {
- MVMJitCode *code = cand->jitcode;
+ if (cand->body.jitcode) {
+ MVMJitCode *code = cand->body.jitcode;
size += sizeof(MVMJitCode);
@@ -138,13 +120,13 @@ static void describe_refs(MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSTa
if (body->num_spesh_candidates) {
MVMuint32 i, j;
for (i = 0; i < body->num_spesh_candidates; i++) {
- for (j = 0; j < body->spesh_candidates[i]->num_spesh_slots; j++)
+ for (j = 0; j < body->spesh_candidates[i]->body.num_spesh_slots; j++)
MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
- (MVMCollectable *)body->spesh_candidates[i]->spesh_slots[j],
+ (MVMCollectable *)body->spesh_candidates[i]->body.spesh_slots[j],
"Spesh slot entry");
- for (j = 0; j < body->spesh_candidates[i]->num_inlines; j++)
+ for (j = 0; j < body->spesh_candidates[i]->body.num_inlines; j++)
MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
- (MVMCollectable *)body->spesh_candidates[i]->inlines[j].sf,
+ (MVMCollectable *)body->spesh_candidates[i]->body.inlines[j].sf,
"Spesh inlined static frame");
}
}
diff --git src/6model/reprs/NativeRef.c src/6model/reprs/NativeRef.c
index e6c09f00a..9aa5c939d 100644
--- src/6model/reprs/NativeRef.c
+++ src/6model/reprs/NativeRef.c
@@ -226,8 +226,8 @@ MVMObject * MVM_nativeref_lex_i(MVMThreadContext *tc, MVMuint16 outers, MVMuint1
ref_type = MVM_hll_current(tc)->int_lex_ref;
if (ref_type) {
MVMFrame *f = get_lexical_outer(tc, outers);
- MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->lexical_types
- ? f->spesh_cand->lexical_types
+ MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->body.lexical_types
+ ? f->spesh_cand->body.lexical_types
: f->static_info->body.lexical_types;
MVMuint16 type = lexical_types[idx];
if (type != MVM_reg_int64 && type != MVM_reg_int32 &&
@@ -245,8 +245,8 @@ MVMObject * MVM_nativeref_lex_n(MVMThreadContext *tc, MVMuint16 outers, MVMuint1
ref_type = MVM_hll_current(tc)->num_lex_ref;
if (ref_type) {
MVMFrame *f = get_lexical_outer(tc, outers);
- MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->lexical_types
- ? f->spesh_cand->lexical_types
+ MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->body.lexical_types
+ ? f->spesh_cand->body.lexical_types
: f->static_info->body.lexical_types;
MVMuint16 type = lexical_types[idx];
if (type != MVM_reg_num64 && type != MVM_reg_num32)
@@ -261,8 +261,8 @@ MVMObject * MVM_nativeref_lex_s(MVMThreadContext *tc, MVMuint16 outers, MVMuint1
ref_type = MVM_hll_current(tc)->str_lex_ref;
if (ref_type) {
MVMFrame *f = get_lexical_outer(tc, outers);
- MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->lexical_types
- ? f->spesh_cand->lexical_types
+ MVMuint16 *lexical_types = f->spesh_cand && f->spesh_cand->body.lexical_types
+ ? f->spesh_cand->body.lexical_types
: f->static_info->body.lexical_types;
if (lexical_types[idx] != MVM_reg_str)
MVM_exception_throw_adhoc(tc, "getlexref_s: lexical is not a str (%d, %d)", outers, idx);
diff --git src/core/bytecodedump.c src/core/bytecodedump.c
index 8b900cdf4..9197927af 100644
--- src/core/bytecodedump.c
+++ src/core/bytecodedump.c
@@ -73,8 +73,8 @@ static void bytecode_dump_frame_internal(MVMThreadContext *tc, MVMStaticFrame *f
/* mostly stolen from validation.c */
MVMStaticFrame *static_frame = frame;
- MVMuint32 bytecode_size = maybe_candidate ? maybe_candidate->bytecode_size : static_frame->body.bytecode_size;
- MVMuint8 *bytecode_start = maybe_candidate ? maybe_candidate->bytecode : static_frame->body.bytecode;
+ MVMuint32 bytecode_size = maybe_candidate ? maybe_candidate->body.bytecode_size : static_frame->body.bytecode_size;
+ MVMuint8 *bytecode_start = maybe_candidate ? maybe_candidate->body.bytecode : static_frame->body.bytecode;
MVMuint8 *bytecode_end = bytecode_start + bytecode_size;
/* current position in the bytestream */
MVMuint8 *cur_op = bytecode_start;
@@ -257,8 +257,8 @@ static void bytecode_dump_frame_internal(MVMThreadContext *tc, MVMStaticFrame *f
}
else if (op_rw == MVM_operand_read_reg || op_rw == MVM_operand_write_reg) {
/* register operand */
- MVMuint8 frame_has_inlines = maybe_candidate && maybe_candidate->num_inlines ? 1 : 0;
- MVMuint16 *local_types = frame_has_inlines ? maybe_candidate->local_types : frame->body.local_types;
+ MVMuint8 frame_has_inlines = maybe_candidate && maybe_candidate->body.num_inlines ? 1 : 0;
+ MVMuint16 *local_types = frame_has_inlines ? maybe_candidate->body.local_types : frame->body.local_types;
operand_size = 2;
a("loc_%u_%s", GET_REG(cur_op, 0),
local_types ? get_typename(local_types[GET_REG(cur_op, 0)]) : "unknown");
@@ -536,7 +536,7 @@ void MVM_dump_bytecode(MVMThreadContext *tc) {
/*MVMuint8 found = 0;*/
/*for (spesh_cand_idx = 0; spesh_cand_idx < sf->body.num_spesh_candidates; spesh_cand_idx++) {*/
/*MVMSpeshCandidate *cand = sf->body.spesh_candidates[spesh_cand_idx];*/
- /*if (cand->bytecode == effective_bytecode) {*/
+ /*if (cand->body.bytecode == effective_bytecode) {*/
/*MVM_dump_bytecode_of(tc, tc->cur_frame, cand);*/
/*found = 1;*/
/*}*/
@@ -564,7 +564,7 @@ void MVM_dump_bytecode_stackframe(MVMThreadContext *tc, MVMint32 depth) {
MVMStaticFrameSpesh *spesh = sf->body.spesh;
for (spesh_cand_idx = 0; spesh_cand_idx < spesh->body.num_spesh_candidates; spesh_cand_idx++) {
MVMSpeshCandidate *cand = spesh->body.spesh_candidates[spesh_cand_idx];
- if (cand->bytecode == effective_bytecode) {
+ if (cand->body.bytecode == effective_bytecode) {
MVM_dump_bytecode_of(tc, frame, cand);
}
}
diff --git src/core/exceptions.c src/core/exceptions.c
index f5429fbc1..1b3cdfb60 100644
--- src/core/exceptions.c
+++ src/core/exceptions.c
@@ -10,7 +10,7 @@ static int crash_on_error = 0;
/* Function for getting effective (specialized or not) frame handlers. */
MVM_STATIC_INLINE MVMFrameHandler * MVM_frame_effective_handlers(MVMFrame *f) {
MVMSpeshCandidate *spesh_cand = f->spesh_cand;
- return spesh_cand ? spesh_cand->handlers : f->static_info->body.handlers;
+ return spesh_cand ? spesh_cand->body.handlers : f->static_info->body.handlers;
}
/* Maps ID of exception category to its name. */
@@ -100,10 +100,10 @@ static MVMint32 search_frame_handlers_dyn(MVMThreadContext *tc, MVMFrame *f,
MVMuint32 cat, MVMObject *payload,
LocatedHandler *lh) {
MVMuint32 i;
- if (f->spesh_cand && f->spesh_cand->jitcode && f->jit_entry_label) {
- MVMJitCode *jitcode = f->spesh_cand->jitcode;
+ if (f->spesh_cand && f->spesh_cand->body.jitcode && f->jit_entry_label) {
+ MVMJitCode *jitcode = f->spesh_cand->body.jitcode;
void *current_position = MVM_jit_code_get_current_position(tc, jitcode, f);
- MVMJitHandler *jhs = f->spesh_cand->jitcode->handlers;
+ MVMJitHandler *jhs = f->spesh_cand->body.jitcode->handlers;
MVMFrameHandler *fhs = MVM_frame_effective_handlers(f);
for (i = MVM_jit_code_get_active_handlers(tc, jitcode, current_position, 0);
i < jitcode->num_handlers;
@@ -117,7 +117,7 @@ static MVMint32 search_frame_handlers_dyn(MVMThreadContext *tc, MVMFrame *f,
}
} else {
MVMuint32 num_handlers = f->spesh_cand
- ? f->spesh_cand->num_handlers
+ ? f->spesh_cand->body.num_handlers
: f->static_info->body.num_handlers;
MVMuint32 pc;
if (f == tc->cur_frame)
@@ -175,8 +175,8 @@ static MVMint32 search_frame_handlers_lex(MVMThreadContext *tc, MVMFrame *f,
MVMuint32 i;
MVMuint32 skipping = *skip_first_inlinee;
MVMFrameHandler *fhs = MVM_frame_effective_handlers(f);
- if (f->spesh_cand && f->spesh_cand->jitcode && f->jit_entry_label) {
- MVMJitCode *jitcode = f->spesh_cand->jitcode;
+ if (f->spesh_cand && f->spesh_cand->body.jitcode && f->jit_entry_label) {
+ MVMJitCode *jitcode = f->spesh_cand->body.jitcode;
void *current_position = MVM_jit_code_get_current_position(tc, jitcode, f);
MVMJitHandler *jhs = jitcode->handlers;
for (i = MVM_jit_code_get_active_handlers(tc, jitcode, current_position, 0);
@@ -191,7 +191,7 @@ static MVMint32 search_frame_handlers_lex(MVMThreadContext *tc, MVMFrame *f,
*skip_first_inlinee = 0;
}
else {
- MVMuint16 cr_reg = f->spesh_cand->inlines[fh->inlinee].code_ref_reg;
+ MVMuint16 cr_reg = f->spesh_cand->body.inlines[fh->inlinee].code_ref_reg;
MVMFrame *inline_outer = ((MVMCode *)f->work[cr_reg].o)->body.outer;
if (inline_outer == f) {
skip_all_inlinees = 1;
@@ -215,7 +215,7 @@ static MVMint32 search_frame_handlers_lex(MVMThreadContext *tc, MVMFrame *f,
}
else {
MVMuint32 num_handlers = f->spesh_cand
- ? f->spesh_cand->num_handlers
+ ? f->spesh_cand->body.num_handlers
: f->static_info->body.num_handlers;
MVMuint32 pc;
if (f == tc->cur_frame)
@@ -233,7 +233,7 @@ static MVMint32 search_frame_handlers_lex(MVMThreadContext *tc, MVMFrame *f,
*skip_first_inlinee = 0;
}
else {
- MVMuint16 cr_reg = f->spesh_cand->inlines[fh->inlinee].code_ref_reg;
+ MVMuint16 cr_reg = f->spesh_cand->body.inlines[fh->inlinee].code_ref_reg;
MVMFrame *inline_outer = ((MVMCode *)f->work[cr_reg].o)->body.outer;
if (inline_outer == f) {
skip_all_inlinees = 1;
@@ -348,8 +348,8 @@ static void run_handler(MVMThreadContext *tc, LocatedHandler lh, MVMObject *ex_o
case MVM_EX_ACTION_GOTO:
if (lh.jit_handler) {
- void **labels = lh.frame->spesh_cand->jitcode->labels;
- MVMuint8 *pc = lh.frame->spesh_cand->jitcode->bytecode;
+ void **labels = lh.frame->spesh_cand->body.jitcode->labels;
+ MVMuint8 *pc = lh.frame->spesh_cand->body.jitcode->bytecode;
MVM_frame_unwind_to(tc, lh.frame, pc, 0, NULL, labels[lh.jit_handler->goto_label]);
} else {
MVM_frame_unwind_to(tc, lh.frame, NULL, lh.handler->goto_offset, NULL, NULL);
@@ -428,9 +428,9 @@ static void unwind_after_handler(MVMThreadContext *tc, void *sr_data) {
frame = ah->frame;
exception = (MVMException *)ah->ex_obj;
if (ah->jit_handler) {
- void **labels = frame->spesh_cand->jitcode->labels;
+ void **labels = frame->spesh_cand->body.jitcode->labels;
jit_return_label = labels[ah->jit_handler->goto_label];
- abs_address = frame->spesh_cand->jitcode->bytecode;
+ abs_address = frame->spesh_cand->body.jitcode->bytecode;
goto_offset = 0;
}
else {
@@ -762,7 +762,7 @@ void MVM_exception_throwobj(MVMThreadContext *tc, MVMuint8 mode, MVMObject *ex_o
ex->body.resume_addr = *tc->interp_cur_op;
/* Ensure that we store label where the JIT should return, if any */
if (tc->jit_return_address != NULL) {
- ex->body.jit_resume_label = MVM_jit_code_get_current_position(tc, tc->cur_frame->spesh_cand->jitcode, tc->cur_frame);
+ ex->body.jit_resume_label = MVM_jit_code_get_current_position(tc, tc->cur_frame->spesh_cand->body.jitcode, tc->cur_frame);
}
}
lh = search_for_handler_from(tc, tc->cur_frame, mode, ex->body.category, ex->body.payload);
diff --git src/core/frame.c src/core/frame.c
index abf13949b..986f99a1a 100644
--- src/core/frame.c
+++ src/core/frame.c
@@ -294,11 +294,11 @@ static MVMFrame * allocate_frame(MVMThreadContext *tc, MVMStaticFrame *static_fr
/* Allocate space for lexicals and work area. */
static_frame_body = &(static_frame->body);
- env_size = spesh_cand ? spesh_cand->env_size : static_frame_body->env_size;
+ env_size = spesh_cand ? spesh_cand->body.env_size : static_frame_body->env_size;
- jitcode = spesh_cand ? spesh_cand->jitcode : NULL;
+ jitcode = spesh_cand ? spesh_cand->body.jitcode : NULL;
num_locals = jitcode && jitcode->local_types ? jitcode->num_locals :
- (spesh_cand ? spesh_cand->num_locals : static_frame_body->num_locals);
+ (spesh_cand ? spesh_cand->body.num_locals : static_frame_body->num_locals);
if (env_size) {
frame->env = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, env_size);
frame->allocd_env = env_size;
@@ -307,7 +307,7 @@ static MVMFrame * allocate_frame(MVMThreadContext *tc, MVMStaticFrame *static_fr
frame->env = NULL;
frame->allocd_env = 0;
}
- work_size = spesh_cand ? spesh_cand->work_size : static_frame_body->work_size;
+ work_size = spesh_cand ? spesh_cand->body.work_size : static_frame_body->work_size;
if (work_size) {
if (spesh_cand) {
/* Allocate zeroed memory. Spesh makes sure we have VMNull setup in
@@ -355,12 +355,12 @@ static MVMFrame * allocate_heap_frame(MVMThreadContext *tc, MVMStaticFrame *stat
/* Allocate space for lexicals and work area. */
static_frame_body = &(static_frame->body);
- env_size = spesh_cand ? spesh_cand->env_size : static_frame_body->env_size;
+ env_size = spesh_cand ? spesh_cand->body.env_size : static_frame_body->env_size;
if (env_size) {
frame->env = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, env_size);
frame->allocd_env = env_size;
}
- work_size = spesh_cand ? spesh_cand->work_size : static_frame_body->work_size;
+ work_size = spesh_cand ? spesh_cand->body.work_size : static_frame_body->work_size;
if (work_size) {
if (spesh_cand) {
/* We make sure to initialize anything that can be read before
@@ -378,7 +378,7 @@ static MVMFrame * allocate_heap_frame(MVMThreadContext *tc, MVMStaticFrame *stat
/* Calculate args buffer position. */
frame->args = frame->work + (spesh_cand
- ? spesh_cand->num_locals
+ ? spesh_cand->body.num_locals
: static_frame_body->num_locals);
}
@@ -517,14 +517,14 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
frame = allocate_frame(tc, static_frame, chosen_cand, 0);
frame->spesh_correlation_id = 0;
}
- if (chosen_cand->jitcode) {
- chosen_bytecode = chosen_cand->jitcode->bytecode;
- frame->jit_entry_label = chosen_cand->jitcode->labels[0];
+ if (chosen_cand->body.jitcode) {
+ chosen_bytecode = chosen_cand->body.jitcode->bytecode;
+ frame->jit_entry_label = chosen_cand->body.jitcode->labels[0];
}
else {
- chosen_bytecode = chosen_cand->bytecode;
+ chosen_bytecode = chosen_cand->body.bytecode;
}
- frame->effective_spesh_slots = chosen_cand->spesh_slots;
+ frame->effective_spesh_slots = chosen_cand->body.spesh_slots;
frame->spesh_cand = chosen_cand;
}
else {
@@ -923,7 +923,7 @@ static MVMuint64 remove_one_frame(MVMThreadContext *tc, MVMuint8 unwind) {
if (tc->jit_return_address != NULL) {
/* on a JIT frame, exit to interpreter afterwards */
- MVMJitCode *jitcode = returner->spesh_cand->jitcode;
+ MVMJitCode *jitcode = returner->spesh_cand->body.jitcode;
MVM_jit_code_set_current_position(tc, jitcode, returner, jitcode->exit_label);
/* given that we might throw in the special-return, act as if we've
* left the current frame (which is true) */
@@ -1140,7 +1140,7 @@ void MVM_frame_unwind_to(MVMThreadContext *tc, MVMFrame *frame, MVMuint8 *abs_ad
*tc->interp_cur_op = *tc->interp_bytecode_start + rel_addr;
if (jit_return_label) {
- MVM_jit_code_set_current_position(tc, tc->cur_frame->spesh_cand->jitcode, tc->cur_frame, jit_return_label);
+ MVM_jit_code_set_current_position(tc, tc->cur_frame->spesh_cand->body.jitcode, tc->cur_frame, jit_return_label);
}
if (return_value)
@@ -1259,9 +1259,9 @@ MVMObject * MVM_frame_vivify_lexical(MVMThreadContext *tc, MVMFrame *f, MVMuint1
else if (f->spesh_cand) {
MVMuint32 i;
flags = NULL;
- for (i = 0; i < f->spesh_cand->num_inlines; i++) {
- MVMStaticFrame *isf = f->spesh_cand->inlines[i].sf;
- effective_idx = idx - f->spesh_cand->inlines[i].lexicals_start;
+ for (i = 0; i < f->spesh_cand->body.num_inlines; i++) {
+ MVMStaticFrame *isf = f->spesh_cand->body.inlines[i].sf;
+ effective_idx = idx - f->spesh_cand->body.inlines[i].lexicals_start;
if (effective_idx < isf->body.num_lexicals) {
flags = isf->body.static_env_flags;
static_env = isf->body.static_env;
diff --git src/core/interp.c src/core/interp.c
index 0421653bf..a5acd0f4b 100644
--- src/core/interp.c
+++ src/core/interp.c
@@ -370,8 +370,8 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
f = f->outer;
outers--;
}
- lexical_types = f->spesh_cand && f->spesh_cand->lexical_types
- ? f->spesh_cand->lexical_types
+ lexical_types = f->spesh_cand && f->spesh_cand->body.lexical_types
+ ? f->spesh_cand->body.lexical_types
: f->static_info->body.lexical_types;
if (lexical_types[idx] == MVM_reg_obj) {
MVMRegister found = GET_LEX(cur_op, 2, f);
@@ -391,8 +391,8 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(bindlex): {
MVMFrame *f = tc->cur_frame;
MVMuint16 outers = GET_UI16(cur_op, 2);
- MVMuint16 kind = f->spesh_cand && f->spesh_cand->local_types
- ? f->spesh_cand->local_types[GET_UI16(cur_op, 4)]
+ MVMuint16 kind = f->spesh_cand && f->spesh_cand->body.local_types
+ ? f->spesh_cand->body.local_types[GET_UI16(cur_op, 4)]
: f->static_info->body.local_types[GET_UI16(cur_op, 4)];
while (outers) {
if (!f->outer)
@@ -6410,7 +6410,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
goto NEXT;
}
OP(sp_jit_enter): {
- MVMJitCode *jc = tc->cur_frame->spesh_cand->jitcode;
+ MVMJitCode *jc = tc->cur_frame->spesh_cand->body.jitcode;
if (MVM_UNLIKELY(jc == NULL)) {
MVM_exception_throw_adhoc(tc, "Try to enter NULL jitcode");
}
diff --git src/gc/roots.c src/gc/roots.c
index c3a761379..7136bb378 100644
--- src/gc/roots.c
+++ src/gc/roots.c
@@ -450,13 +450,13 @@ void MVM_gc_root_add_frame_registers_to_worklist(MVMThreadContext *tc, MVMGCWork
/* Scan locals. */
MVMSpeshCandidate *spesh_cand = frame->spesh_cand;
- MVMJitCode *jitcode = spesh_cand ? spesh_cand->jitcode : NULL;
+ MVMJitCode *jitcode = spesh_cand ? spesh_cand->body.jitcode : NULL;
if (jitcode && jitcode->local_types) {
type_map = jitcode->local_types;
count = jitcode->num_locals;
- } else if (frame->spesh_cand && frame->spesh_cand->local_types) {
- type_map = frame->spesh_cand->local_types;
- count = frame->spesh_cand->num_locals;
+ } else if (spesh_cand && spesh_cand->body.local_types) {
+ type_map = spesh_cand->body.local_types;
+ count = spesh_cand->body.num_locals;
}
else {
type_map = frame->static_info->body.local_types;
@@ -505,9 +505,9 @@ static void scan_lexicals(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMFram
if (frame->env) {
MVMuint16 i, count;
MVMuint16 *type_map;
- if (frame->spesh_cand && frame->spesh_cand->lexical_types) {
- type_map = frame->spesh_cand->lexical_types;
- count = frame->spesh_cand->num_lexicals;
+ if (frame->spesh_cand && frame->spesh_cand->body.lexical_types) {
+ type_map = frame->spesh_cand->body.lexical_types;
+ count = frame->spesh_cand->body.num_lexicals;
}
else {
type_map = frame->static_info->body.lexical_types;
diff --git src/jit/interface.h src/jit/interface.h
index 5bee1d5ec..c766980cc 100644
--- src/jit/interface.h
+++ src/jit/interface.h
@@ -2,7 +2,7 @@
MVM_STATIC_INLINE MVMuint8 * MVM_frame_effective_bytecode(MVMFrame *f) {
MVMSpeshCandidate *spesh_cand = f->spesh_cand;
if (spesh_cand)
- return spesh_cand->jitcode ? spesh_cand->jitcode->bytecode : spesh_cand->bytecode;
+ return spesh_cand->body.jitcode ? spesh_cand->body.jitcode->bytecode : spesh_cand->body.bytecode;
return f->static_info->body.bytecode;
}
diff --git src/moar.h src/moar.h
index 176fdec5f..006fa8367 100644
--- src/moar.h
+++ src/moar.h
@@ -142,6 +142,7 @@ MVM_PUBLIC MVMint32 MVM_jit_support(void);
#include "core/dll.h"
#include "core/continuation.h"
#include "debug/debugserver.h"
+#include "spesh/pea.h"
#include "6model/reprs.h"
#include "6model/reprconv.h"
#include "6model/bootstrap.h"
@@ -159,10 +160,8 @@ MVM_PUBLIC MVMint32 MVM_jit_support(void);
#include "core/regionalloc.h"
#include "spesh/dump.h"
#include "spesh/debug.h"
-#include "spesh/pea.h"
#include "spesh/graph.h"
#include "spesh/codegen.h"
-#include "spesh/candidate.h"
#include "spesh/manipulate.h"
#include "spesh/args.h"
#include "spesh/usages.h"
diff --git src/spesh/arg_guard.c src/spesh/arg_guard.c
index d31787a3f..8c114d24d 100644
--- src/spesh/arg_guard.c
+++ src/spesh/arg_guard.c
@@ -156,7 +156,7 @@ static MVMuint32 add_nodes_for_typed_argument(MVMThreadContext *tc,
for (i = 0; i < num_valid_candidates; i++) {
/* See if we already have a type for this. */
MVMint32 found = -1;
- MVMSpeshStatsType type_info = candidates[valid_candidates[i]]->type_tuple[type_index];
+ MVMSpeshStatsType type_info = candidates[valid_candidates[i]]->body.type_tuple[type_index];
MVMObject *search_type = consider_decont_type
? type_info.decont_type
: type_info.type;
@@ -330,12 +330,12 @@ void MVM_spesh_arg_guard_regenerate(MVMThreadContext *tc, MVMSpeshArgGuard **gua
/* Skip discarded candidates. */
MVMSpeshCandidate *cand = candidates[i];
MVMint32 found = -1;
- if (cand->discarded)
+ if (cand->body.discarded)
continue;
/* See if we already have a candidate for this. */
for (j = 0; j < MVM_VECTOR_ELEMS(by_callsite); j++) {
- if (by_callsite[j].cs == cand->cs) {
+ if (by_callsite[j].cs == cand->body.cs) {
found = j;
break;
}
@@ -345,7 +345,7 @@ void MVM_spesh_arg_guard_regenerate(MVMThreadContext *tc, MVMSpeshArgGuard **gua
if (found == -1) {
/* Create the entry. */
CallsiteCandidates cc;
- cc.cs = cand->cs;
+ cc.cs = cand->body.cs;
cc.certain_idx = -1;
MVM_VECTOR_INIT(cc.typed_idxs, num_spesh_candidates);
found = MVM_VECTOR_ELEMS(by_callsite);
@@ -356,9 +356,9 @@ void MVM_spesh_arg_guard_regenerate(MVMThreadContext *tc, MVMSpeshArgGuard **gua
}
/* Add this specialization to it. */
- if (cand->type_tuple) {
+ if (cand->body.type_tuple) {
MVM_VECTOR_PUSH(by_callsite[found].typed_idxs, i);
- tree_size += max_typed_nodes(cand->cs, cand->type_tuple);
+ tree_size += max_typed_nodes(cand->body.cs, cand->body.type_tuple);
}
else {
by_callsite[found].certain_idx = i;
diff --git src/spesh/candidate.c src/spesh/candidate.c
deleted file mode 100644
index 26789606c..000000000
--- src/spesh/candidate.c
+++ /dev/null
@@ -1,241 +0,0 @@
-#include "moar.h"
-
-/* Calculates the work and env sizes based on the number of locals and
- * lexicals. */
-static void calculate_work_env_sizes(MVMThreadContext *tc, MVMStaticFrame *sf,
- MVMSpeshCandidate *c) {
- MVMuint32 max_callsite_size, jit_spill_size;
- MVMuint32 i;
-
- max_callsite_size = sf->body.cu->body.max_callsite_size;
- jit_spill_size = (c->jitcode ? c->jitcode->spill_size: 0);
- for (i = 0; i < c->num_inlines; i++) {
- MVMuint32 cs = c->inlines[i].sf->body.cu->body.max_callsite_size;
- if (cs > max_callsite_size)
- max_callsite_size = cs;
- }
-
- c->work_size = (c->num_locals + max_callsite_size + jit_spill_size) * sizeof(MVMRegister);
- c->env_size = c->num_lexicals * sizeof(MVMRegister);
-}
-
-/* Called at points where we can GC safely during specialization. */
-static void spesh_gc_point(MVMThreadContext *tc) {
-#if MVM_GC_DEBUG
- tc->in_spesh = 0;
-#endif
- GC_SYNC_POINT(tc);
-#if MVM_GC_DEBUG
- tc->in_spesh = 1;
-#endif
-}
-
-/* Produces and installs a specialized version of the code, according to the
- * specified plan. */
-void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
- MVMSpeshGraph *sg;
- MVMSpeshCode *sc;
- MVMSpeshCandidate *candidate;
- MVMSpeshCandidate **new_candidate_list;
- MVMStaticFrameSpesh *spesh;
- MVMuint64 start_time = 0, spesh_time = 0, jit_time = 0, end_time;
-
- /* If we've reached our specialization limit, don't continue. */
- MVMint32 spesh_produced = ++tc->instance->spesh_produced;
- if (tc->instance->spesh_limit)
- if (spesh_produced > tc->instance->spesh_limit)
- return;
-
- /* Produce the specialization graph and, if we're logging, dump it out
- * pre-transformation. */
-#if MVM_GC_DEBUG
- tc->in_spesh = 1;
-#endif
- sg = MVM_spesh_graph_create(tc, p->sf, 0, 1);
- if (MVM_spesh_debug_enabled(tc)) {
- char *c_name = MVM_string_utf8_encode_C_string(tc, p->sf->body.name);
- char *c_cuid = MVM_string_utf8_encode_C_string(tc, p->sf->body.cuuid);
- MVMSpeshFacts **facts = sg->facts;
- char *before;
- sg->facts = NULL;
- before = MVM_spesh_dump(tc, sg);
- sg->facts = facts;
- MVM_spesh_debug_printf(tc,
- "Specialization of '%s' (cuid: %s)\n\n", c_name, c_cuid);
- MVM_spesh_debug_printf(tc, "Before:\n%s", before);
- MVM_free(c_name);
- MVM_free(c_cuid);
- MVM_free(before);
- fflush(tc->instance->spesh_log_fh);
- start_time = uv_hrtime();
- }
-
- /* Attach the graph so we will be able to mark it during optimization,
- * allowing us to stick GC sync points at various places and so not let
- * the optimization work block GC for too long. */
- tc->spesh_active_graph = sg;
- spesh_gc_point(tc);
-
- /* Perform the optimization and, if we're logging, dump out the result. */
- if (p->cs_stats->cs)
- MVM_spesh_args(tc, sg, p->cs_stats->cs, p->type_tuple);
- spesh_gc_point(tc);
- MVM_spesh_facts_discover(tc, sg, p, 0);
- spesh_gc_point(tc);
- MVM_spesh_optimize(tc, sg, p);
- spesh_gc_point(tc);
-
- /* Clear active graph; beyond this point, no more GC syncs. */
- tc->spesh_active_graph = NULL;
-
- if (MVM_spesh_debug_enabled(tc))
- spesh_time = uv_hrtime();
-
- /* Generate code and install it into the candidate. */
- sc = MVM_spesh_codegen(tc, sg);
- candidate = MVM_calloc(1, sizeof(MVMSpeshCandidate));
- candidate->cs = p->cs_stats->cs;
- candidate->type_tuple = p->type_tuple
- ? MVM_spesh_plan_copy_type_tuple(tc, candidate->cs, p->type_tuple)
- : NULL;
- candidate->bytecode = sc->bytecode;
- candidate->bytecode_size = sc->bytecode_size;
- candidate->handlers = sc->handlers;
- candidate->deopt_usage_info = sc->deopt_usage_info;
- candidate->num_handlers = sg->num_handlers;
- candidate->num_deopts = sg->num_deopt_addrs;
- candidate->deopts = sg->deopt_addrs;
- candidate->deopt_named_used_bit_field = sg->deopt_named_used_bit_field;
- candidate->deopt_pea = sg->deopt_pea;
- candidate->num_locals = sg->num_locals;
- candidate->num_lexicals = sg->num_lexicals;
- candidate->num_inlines = sg->num_inlines;
- candidate->inlines = sg->inlines;
- candidate->local_types = sg->local_types;
- candidate->lexical_types = sg->lexical_types;
-
- MVM_free(sc);
-
- /* Try to JIT compile the optimised graph. The JIT graph hangs from
- * the spesh graph and can safely be deleted with it. */
- if (tc->instance->jit_enabled) {
- MVMJitGraph *jg;
- if (MVM_spesh_debug_enabled(tc))
- jit_time = uv_hrtime();
-
- jg = MVM_jit_try_make_graph(tc, sg);
- if (jg != NULL) {
- candidate->jitcode = MVM_jit_compile_graph(tc, jg);
- MVM_jit_graph_destroy(tc, jg);
- }
- }
-
- if (MVM_spesh_debug_enabled(tc)) {
- char *after = MVM_spesh_dump(tc, sg);
- end_time = uv_hrtime();
- MVM_spesh_debug_printf(tc, "After:\n%s", after);
- MVM_spesh_debug_printf(tc,
- "Specialization took %" PRIu64 "us (total %" PRIu64"us)\n",
- (spesh_time - start_time) / 1000,
- (end_time - start_time) / 1000);
-
- if (tc->instance->jit_enabled) {
- MVM_spesh_debug_printf(tc,
- "JIT was %ssuccessful and compilation took %" PRIu64 "us\n",
- candidate->jitcode ? "" : "not ", (end_time - jit_time) / 1000);
- if (candidate->jitcode) {
- MVM_spesh_debug_printf(tc, " Bytecode size: %" PRIu64 " byte\n",
- candidate->jitcode->size);
- }
- }
- MVM_spesh_debug_printf(tc, "\n========\n\n");
- MVM_free(after);
- fflush(tc->instance->spesh_log_fh);
- }
-
- /* calculate work environment taking JIT spill area into account */
- calculate_work_env_sizes(tc, sg->sf, candidate);
-
- /* Update spesh slots. */
- candidate->num_spesh_slots = sg->num_spesh_slots;
- candidate->spesh_slots = sg->spesh_slots;
-
- /* Claim ownership of allocated memory assigned to the candidate */
- sg->cand = candidate;
- MVM_spesh_graph_destroy(tc, sg);
-
- /* Create a new candidate list and copy any existing ones. Free memory
- * using the FSA safepoint mechanism. */
- spesh = p->sf->body.spesh;
- new_candidate_list = MVM_fixed_size_alloc(tc, tc->instance->fsa,
- (spesh->body.num_spesh_candidates + 1) * sizeof(MVMSpeshCandidate *));
- if (spesh->body.num_spesh_candidates) {
- size_t orig_size = spesh->body.num_spesh_candidates * sizeof(MVMSpeshCandidate *);
- memcpy(new_candidate_list, spesh->body.spesh_candidates, orig_size);
- MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, orig_size,
- spesh->body.spesh_candidates);
- }
- new_candidate_list[spesh->body.num_spesh_candidates] = candidate;
- spesh->body.spesh_candidates = new_candidate_list;
-
- /* May now be referencing nursery objects, so barrier just in case. */
- if (spesh->common.header.flags2 & MVM_CF_SECOND_GEN)
- MVM_gc_write_barrier_hit(tc, (MVMCollectable *)spesh);
-
- /* Regenerate the guards, and bump the candidate count only after they
- * are installed. This means there is a period when we can read, in
- * another thread, a candidate ahead of the count being updated. Since
- * we set it up above, that's fine enough. The updating of the count
- * *after* this, plus the barrier, is to make sure the guards are in
- * place before the count is bumped, since OSR will watch the number
- * of candidates to see if there's one for it to try and jump in to,
- * and if the guards aren't in place first will see there is not, and
- * not bother checking again. */
- MVM_spesh_arg_guard_regenerate(tc, &(spesh->body.spesh_arg_guard),
- spesh->body.spesh_candidates, spesh->body.num_spesh_candidates + 1);
- MVM_barrier();
- spesh->body.num_spesh_candidates++;
-
- /* If we're logging, dump the upadated arg guards also. */
- if (MVM_spesh_debug_enabled(tc)) {
- char *guard_dump = MVM_spesh_dump_arg_guard(tc, p->sf,
- p->sf->body.spesh->body.spesh_arg_guard);
- MVM_spesh_debug_printf(tc, "%s========\n\n", guard_dump);
- fflush(tc->instance->spesh_log_fh);
- MVM_free(guard_dump);
- }
-
-#if MVM_GC_DEBUG
- tc->in_spesh = 0;
-#endif
-}
-
-/* Frees the memory associated with a spesh candidate. */
-void MVM_spesh_candidate_destroy(MVMThreadContext *tc, MVMSpeshCandidate *candidate) {
- MVM_free(candidate->type_tuple);
- MVM_free(candidate->bytecode);
- MVM_free(candidate->handlers);
- MVM_free(candidate->spesh_slots);
- MVM_free(candidate->deopts);
- MVM_spesh_pea_destroy_deopt_info(tc, &(candidate->deopt_pea));
- MVM_free(candidate->inlines);
- MVM_free(candidate->local_types);
- MVM_free(candidate->lexical_types);
- if (candidate->jitcode)
- MVM_jit_code_destroy(tc, candidate->jitcode);
- MVM_free(candidate->deopt_usage_info);
- MVM_free(candidate);
-}
-
-/* Discards existing candidates. Used when we instrument bytecode, and so
- * need to ignore these ones from here on. */
-void MVM_spesh_candidate_discard_existing(MVMThreadContext *tc, MVMStaticFrame *sf) {
- MVMStaticFrameSpesh *spesh = sf->body.spesh;
- if (spesh) {
- MVMuint32 num_candidates = spesh->body.num_spesh_candidates;
- MVMuint32 i;
- for (i = 0; i < num_candidates; i++)
- spesh->body.spesh_candidates[i]->discarded = 1;
- MVM_spesh_arg_guard_discard(tc, sf);
- }
-}
diff --git src/spesh/candidate.h src/spesh/candidate.h
deleted file mode 100644
index ad53df32d..000000000
--- src/spesh/candidate.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* A specialization candidate. */
-struct MVMSpeshCandidate {
- /* The callsite that this specialization is for. */
- MVMCallsite *cs;
-
- /* The type type that this specialization is for, or NULL if it's a
- * certian specialization. */
- MVMSpeshStatsType *type_tuple;
-
- /* Has the candidated been discarded? */
- MVMuint8 discarded;
-
- /* Length of the specialized bytecode in bytes. */
- MVMuint32 bytecode_size;
-
- /* The specialized bytecode. */
- MVMuint8 *bytecode;
-
- /* Frame handlers for this specialization. */
- MVMFrameHandler *handlers;
-
- /* Spesh slots, used to hold information for fast access. */
- MVMCollectable **spesh_slots;
-
- /* Number of spesh slots. */
- MVMuint32 num_spesh_slots;
-
- /* The number of deoptimization mappings we have. */
- MVMuint32 num_deopts;
-
- /* Deoptimization mappings. */
- MVMint32 *deopts;
-
- /* Bit field of named args used to put in place during deopt, since we
- * typically don't update the array in specialized code. */
- MVMuint64 deopt_named_used_bit_field;
-
- /* Deopt information produced by escape analysis and scalar replacement. */
- MVMSpeshPEADeopt deopt_pea;
-
- /* Number of inlines and inlines table; see graph.h for description of
- * the table format. */
- MVMuint32 num_inlines;
- MVMSpeshInline *inlines;
-
- /* The list of local types (only set up if we do inlines). */
- MVMuint16 *local_types;
-
- /* The list of lexical types (only set up if we do inlines). */
- MVMuint16 *lexical_types;
-
- /* Number of locals the specialized code has (may be different from the
- * original frame thanks to inlining). */
- MVMuint16 num_locals;
-
- /* Number of lexicals the specialized code has. */
- MVMuint16 num_lexicals;
-
- /* Memory sizes to allocate for work/env, taking into account inlining. */
- MVMuint32 work_size;
- MVMuint32 env_size;
-
- /* Number of handlers. */
- MVMuint32 num_handlers;
-
- /* JIT-code structure. */
- MVMJitCode *jitcode;
-
- /* Information used to reconstruct deoptimization usage info should we do
- * an inline of this candidate. It's stored as a sequence of integers of
- * the form:
- * - Bytecode offset of writing instruction
- * - Number of deopt indices that follow
- * - The deopt indices
- * There is a trailing -1 bytecode offset to mark the end of the data.
- */
- MVMint32 *deopt_usage_info;
-};
-
-/* Functions for creating and clearing up specializations. */
-void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p);
-void MVM_spesh_candidate_destroy(MVMThreadContext *tc, MVMSpeshCandidate *candidate);
-void MVM_spesh_candidate_discard_existing(MVMThreadContext *tc, MVMStaticFrame *sf);
diff --git src/spesh/deopt.c src/spesh/deopt.c
index 42a19a102..a74a7f5c7 100644
--- src/spesh/deopt.c
+++ src/spesh/deopt.c
@@ -28,11 +28,11 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
MVMReturnType last_res_type = 0;
MVMuint32 last_return_deopt_idx = 0;
MVMuint32 i;
- for (i = 0; i < cand->num_inlines; i++) {
- if (offset > cand->inlines[i].start && offset <= cand->inlines[i].end) {
+ for (i = 0; i < cand->body.num_inlines; i++) {
+ if (offset > cand->body.inlines[i].start && offset <= cand->body.inlines[i].end) {
/* Create the frame. */
- MVMCode *ucode = (MVMCode *)f->work[cand->inlines[i].code_ref_reg].o;
- MVMStaticFrame *usf = cand->inlines[i].sf;
+ MVMCode *ucode = (MVMCode *)f->work[cand->body.inlines[i].code_ref_reg].o;
+ MVMStaticFrame *usf = cand->body.inlines[i].sf;
MVMFrame *uf;
if (REPR(ucode)->ID != MVM_REPR_ID_MVMCode)
MVM_panic(1, "Deopt: did not find code object when uninlining");
@@ -47,21 +47,21 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
/* Copy the locals and lexicals into place. */
if (usf->body.num_locals)
- memcpy(uf->work, f->work + cand->inlines[i].locals_start,
+ memcpy(uf->work, f->work + cand->body.inlines[i].locals_start,
usf->body.num_locals * sizeof(MVMRegister));
if (usf->body.num_lexicals)
- memcpy(uf->env, f->env + cand->inlines[i].lexicals_start,
+ memcpy(uf->env, f->env + cand->body.inlines[i].lexicals_start,
usf->body.num_lexicals * sizeof(MVMRegister));
/* Store the callsite, in case we need it for further processing
* of arguments. (TODO may need to consider the rest of the arg
* processing context too.) */
- uf->params.callsite = cand->inlines[i].cs;
+ uf->params.callsite = cand->body.inlines[i].cs;
/* Store the named argument used bit field, since if we deopt in
* argument handling code we may have missed some. */
- if (cand->inlines[i].deopt_named_used_bit_field)
- uf->params.named_used.bit_field = cand->inlines[i].deopt_named_used_bit_field;
+ if (cand->body.inlines[i].deopt_named_used_bit_field)
+ uf->params.named_used.bit_field = cand->body.inlines[i].deopt_named_used_bit_field;
/* Did we already uninline a frame? */
if (last_uninlined) {
@@ -72,7 +72,7 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
/* Set up the return location. */
uf->return_address = usf->body.bytecode +
- cand->deopts[2 * last_return_deopt_idx];
+ cand->body.deopts[2 * last_return_deopt_idx];
/* Set result type and register. */
uf->return_type = last_res_type;
@@ -104,7 +104,7 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
}
else {
MVMuint16 orig_reg = (MVMuint16)(f->return_value - f->work);
- MVMuint16 ret_reg = orig_reg - cand->inlines[i].locals_start;
+ MVMuint16 ret_reg = orig_reg - cand->body.inlines[i].locals_start;
uf->return_value = uf->work + ret_reg;
}
}
@@ -122,15 +122,15 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
/* Update tracking variables for last uninline. */
last_uninlined = uf;
- last_res_reg = cand->inlines[i].res_reg;
- last_res_type = cand->inlines[i].res_type;
- last_return_deopt_idx = cand->inlines[i].return_deopt_idx;
+ last_res_reg = cand->body.inlines[i].res_reg;
+ last_res_type = cand->body.inlines[i].res_type;
+ last_return_deopt_idx = cand->body.inlines[i].return_deopt_idx;
}
}
if (last_uninlined) {
/* Set return address, which we need to resolve to the deopt'd one. */
f->return_address = f->static_info->body.bytecode +
- cand->deopts[2 * last_return_deopt_idx];
+ cand->body.deopts[2 * last_return_deopt_idx];
/* Set result type and register. */
f->return_type = last_res_type;
@@ -162,8 +162,8 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand,
}
static void deopt_named_args_used(MVMThreadContext *tc, MVMFrame *f) {
- if (f->spesh_cand->deopt_named_used_bit_field)
- f->params.named_used.bit_field = f->spesh_cand->deopt_named_used_bit_field;
+ if (f->spesh_cand->body.deopt_named_used_bit_field)
+ f->params.named_used.bit_field = f->spesh_cand->body.deopt_named_used_bit_field;
}
/* Materialize an individual replaced object. */
@@ -171,10 +171,10 @@ static void materialize_object(MVMThreadContext *tc, MVMFrame *f, MVMObject ***m
MVMuint16 info_idx, MVMuint16 target_reg) {
MVMSpeshCandidate *cand = f->spesh_cand;
if (!*materialized)
- *materialized = MVM_calloc(MVM_VECTOR_ELEMS(cand->deopt_pea.materialize_info), sizeof(MVMObject *));
+ *materialized = MVM_calloc(MVM_VECTOR_ELEMS(cand->body.deopt_pea.materialize_info), sizeof(MVMObject *));
if (!(*materialized)[info_idx]) {
- MVMSpeshPEAMaterializeInfo *mi = &(cand->deopt_pea.materialize_info[info_idx]);
- MVMSTable *st = (MVMSTable *)cand->spesh_slots[mi->stable_sslot];
+ MVMSpeshPEAMaterializeInfo *mi = &(cand->body.deopt_pea.materialize_info[info_idx]);
+ MVMSTable *st = (MVMSTable *)cand->body.spesh_slots[mi->stable_sslot];
MVMP6opaqueREPRData *repr_data = (MVMP6opaqueREPRData *)st->REPR_data;
MVMROOT(tc, f, {
MVMObject *obj = MVM_gc_allocate_object(tc, st);
@@ -221,11 +221,11 @@ static void materialize_object(MVMThreadContext *tc, MVMFrame *f, MVMObject ***m
static void materialize_replaced_objects(MVMThreadContext *tc, MVMFrame *f, MVMint32 deopt_index) {
MVMuint32 i;
MVMSpeshCandidate *cand = f->spesh_cand;
- MVMuint32 num_deopt_points = MVM_VECTOR_ELEMS(cand->deopt_pea.deopt_point);
+ MVMuint32 num_deopt_points = MVM_VECTOR_ELEMS(cand->body.deopt_pea.deopt_point);
MVMObject **materialized = NULL;
MVMROOT(tc, f, {
for (i = 0; i < num_deopt_points; i++) {
- MVMSpeshPEADeoptPoint *dp = &(cand->deopt_pea.deopt_point[i]);
+ MVMSpeshPEADeoptPoint *dp = &(cand->body.deopt_pea.deopt_point[i]);
if (dp->deopt_point_idx == deopt_index)
materialize_object(tc, f, &materialized, dp->materialize_info_idx, dp->target_reg);
}
@@ -244,7 +244,7 @@ static void deopt_frame(MVMThreadContext *tc, MVMFrame *f, MVMuint32 deopt_idx,
});
/* Check if we have inlines. */
- if (f->spesh_cand->inlines) {
+ if (f->spesh_cand->body.inlines) {
/* Yes, going to have to re-create the frames; uninline
* moves the interpreter, so we can just tweak the last
* frame. For the moment, uninlining creates its frames
@@ -290,10 +290,10 @@ void MVM_spesh_deopt_one(MVMThreadContext *tc, MVMuint32 deopt_idx) {
#endif
clear_dynlex_cache(tc, f);
assert(f->spesh_cand != NULL);
- assert(deopt_idx < f->spesh_cand->num_deopts);
+ assert(deopt_idx < f->spesh_cand->body.num_deopts);
if (f->spesh_cand) {
- MVMuint32 deopt_target = f->spesh_cand->deopts[deopt_idx * 2];
- MVMuint32 deopt_offset = f->spesh_cand->deopts[deopt_idx * 2 + 1];
+ MVMuint32 deopt_target = f->spesh_cand->body.deopts[deopt_idx * 2];
+ MVMuint32 deopt_offset = f->spesh_cand->body.deopts[deopt_idx * 2 + 1];
#if MVM_LOG_DEOPTS
fprintf(stderr, " Will deopt %u -> %u\n", deopt_offset, deopt_target);
#endif
@@ -314,8 +314,8 @@ void MVM_spesh_deopt_one(MVMThreadContext *tc, MVMuint32 deopt_idx) {
* the point of its latest call. Returns -1 if none can be resolved. */
MVMint32 MVM_spesh_deopt_find_inactive_frame_deopt_idx(MVMThreadContext *tc, MVMFrame *f) {
/* Is it JITted code? */
- if (f->spesh_cand->jitcode) {
- MVMJitCode *jitcode = f->spesh_cand->jitcode;
+ if (f->spesh_cand->body.jitcode) {
+ MVMJitCode *jitcode = f->spesh_cand->body.jitcode;
MVMuint32 idx = MVM_jit_code_get_active_deopt_idx(tc, jitcode, f);
if (idx < jitcode->num_deopts) {
MVMint32 deopt_idx = jitcode->deopts[idx].idx;
@@ -327,11 +327,11 @@ MVMint32 MVM_spesh_deopt_find_inactive_frame_deopt_idx(MVMThreadContext *tc, MVM
}
else {
/* Not JITted; see if we can find the return address in the deopt table. */
- MVMint32 ret_offset = f->return_address - f->spesh_cand->bytecode;
- MVMint32 n = f->spesh_cand->num_deopts * 2;
+ MVMint32 ret_offset = f->return_address - f->spesh_cand->body.bytecode;
+ MVMint32 n = f->spesh_cand->body.num_deopts * 2;
MVMint32 i;
for (i = 0; i < n; i += 2) {
- if (f->spesh_cand->deopts[i + 1] == ret_offset) {
+ if (f->spesh_cand->body.deopts[i + 1] == ret_offset) {
MVMint32 deopt_idx = i / 2;
#if MVM_LOG_DEOPTS
fprintf(stderr, " Found deopt index for interpeter (idx %d)\n", deopt_idx);
@@ -368,12 +368,12 @@ void MVM_spesh_deopt_all(MVMThreadContext *tc) {
if (deopt_idx >= 0) {
/* Re-create any frames needed if we're in an inline; if not,
* just update return address. */
- MVMint32 deopt_offset = f->spesh_cand->deopts[2 * deopt_idx + 1];
- MVMint32 deopt_target = f->spesh_cand->deopts[2 * deopt_idx];
+ MVMint32 deopt_offset = f->spesh_cand->body.deopts[2 * deopt_idx + 1];
+ MVMint32 deopt_target = f->spesh_cand->body.deopts[2 * deopt_idx];
MVMROOT2(tc, f, l, {
materialize_replaced_objects(tc, f, deopt_idx);
});
- if (f->spesh_cand->inlines) {
+ if (f->spesh_cand->body.inlines) {
MVMROOT2(tc, f, l, {
uninline(tc, f, f->spesh_cand, deopt_offset, deopt_target, l);
});
@@ -395,7 +395,7 @@ void MVM_spesh_deopt_all(MVMThreadContext *tc) {
/* No spesh cand/slots needed now. */
deopt_named_args_used(tc, f);
f->effective_spesh_slots = NULL;
- if (f->spesh_cand->jitcode) {
+ if (f->spesh_cand->body.jitcode) {
f->spesh_cand = NULL;
f->jit_entry_label = NULL;
/* XXX This break is wrong and hides a bug. */
diff --git src/spesh/frame_walker.c src/spesh/frame_walker.c
index d4d13a26c..4c410d1c4 100644
--- src/spesh/frame_walker.c
+++ src/spesh/frame_walker.c
@@ -48,7 +48,7 @@ static void go_to_next_inline(MVMThreadContext *tc, MVMSpeshFrameWalker *fw) {
fw->inline_idx = NO_INLINE;
return;
}
- MVMJitCode *jitcode = cand->jitcode;
+ MVMJitCode *jitcode = cand->body.jitcode;
if (jitcode) {
MVMuint32 idx = MVM_jit_code_get_active_inlines(tc, jitcode, fw->jit_position, fw->inline_idx + 1);
if (idx < jitcode->num_inlines) {
@@ -58,8 +58,8 @@ static void go_to_next_inline(MVMThreadContext *tc, MVMSpeshFrameWalker *fw) {
}
else {
MVMuint32 i;
- for (i = fw->inline_idx + 1; i < cand->num_inlines; i++) {
- if (fw->deopt_offset > cand->inlines[i].start && fw->deopt_offset <= cand->inlines[i].end) {
+ for (i = fw->inline_idx + 1; i < cand->body.num_inlines; i++) {
+ if (fw->deopt_offset > cand->body.inlines[i].start && fw->deopt_offset <= cand->body.inlines[i].end) {
/* Found an applicable inline. */
fw->inline_idx = i;
return;
@@ -76,8 +76,8 @@ static void go_to_next_inline(MVMThreadContext *tc, MVMSpeshFrameWalker *fw) {
static void go_to_first_inline(MVMThreadContext *tc, MVMSpeshFrameWalker *fw, MVMFrame *prev) {
MVMFrame *f = fw->cur_caller_frame;
MVMSpeshCandidate *spesh_cand = f->spesh_cand;
- if (spesh_cand && spesh_cand->inlines) {
- MVMJitCode *jitcode = spesh_cand->jitcode;
+ if (spesh_cand && spesh_cand->body.inlines) {
+ MVMJitCode *jitcode = spesh_cand->body.jitcode;
if (jitcode && f->jit_entry_label) {
void *current_position = prev && prev->extra && prev->extra->caller_jit_position
? prev->extra->caller_jit_position
@@ -94,7 +94,7 @@ static void go_to_first_inline(MVMThreadContext *tc, MVMSpeshFrameWalker *fw, MV
? prev->extra->caller_deopt_idx - 1
: MVM_spesh_deopt_find_inactive_frame_deopt_idx(tc, f);
if (deopt_idx >= 0) {
- fw->deopt_offset = spesh_cand->deopts[2 * deopt_idx + 1];
+ fw->deopt_offset = spesh_cand->body.deopts[2 * deopt_idx + 1];
fw->inline_idx = -1;
go_to_next_inline(tc, fw);
return;
@@ -169,7 +169,7 @@ MVMuint32 MVM_spesh_frame_walker_next(MVMThreadContext *tc, MVMSpeshFrameWalker
outer = fw->cur_caller_frame->outer;
}
else {
- MVMSpeshInline *i = &(spesh_cand->inlines[fw->inline_idx]);
+ MVMSpeshInline *i = &(spesh_cand->body.inlines[fw->inline_idx]);
MVMCode *code = (MVMCode *)fw->cur_caller_frame->work[i->code_ref_reg].o;
outer = code ? code->body.outer : NULL;
}
@@ -214,8 +214,8 @@ static void find_lex_info(MVMThreadContext *tc, MVMSpeshFrameWalker *fw, MVMFram
*base_index_out = 0;
}
else {
- *sf_out = spesh_cand->inlines[fw->inline_idx].sf;
- *base_index_out = spesh_cand->inlines[fw->inline_idx].lexicals_start;
+ *sf_out = spesh_cand->body.inlines[fw->inline_idx].sf;
+ *base_index_out = spesh_cand->body.inlines[fw->inline_idx].lexicals_start;
}
}
}
@@ -259,7 +259,7 @@ MVMuint32 MVM_spesh_frame_walker_move_outer(MVMThreadContext *tc, MVMSpeshFrameW
outer = fw->cur_caller_frame->outer;
}
else {
- MVMSpeshInline *i = &(spesh_cand->inlines[fw->inline_idx]);
+ MVMSpeshInline *i = &(spesh_cand->body.inlines[fw->inline_idx]);
MVMCode *code = (MVMCode *)fw->cur_caller_frame->work[i->code_ref_reg].o;
outer = code ? code->body.outer : NULL;
}
@@ -306,7 +306,7 @@ MVMuint32 MVM_spesh_frame_walker_move_caller_skip_thunks(MVMThreadContext *tc,
MVMSpeshCandidate *spesh_cand = fw->cur_caller_frame->spesh_cand;
MVMStaticFrame *sf = (fw->inline_idx == NO_INLINE || !spesh_cand)
? fw->cur_caller_frame->static_info
- : spesh_cand->inlines[fw->inline_idx].sf;
+ : spesh_cand->body.inlines[fw->inline_idx].sf;
if (!sf->body.is_thunk)
return 1;
}
@@ -443,7 +443,7 @@ MVMObject * MVM_spesh_frame_walker_get_code(MVMThreadContext *tc, MVMSpeshFrameW
if (fw->inline_idx == NO_INLINE || !spesh_cand)
return fw->cur_caller_frame->code_ref;
return fw->cur_caller_frame->work[
- spesh_cand->inlines[fw->inline_idx].code_ref_reg
+ spesh_cand->body.inlines[fw->inline_idx].code_ref_reg
].o;
}
diff --git src/spesh/graph.c src/spesh/graph.c
index 65a0d25c7..a4b3f187c 100644
--- src/spesh/graph.c
+++ src/spesh/graph.c
@@ -1315,29 +1315,29 @@ MVMSpeshGraph * MVM_spesh_graph_create_from_cand(MVMThreadContext *tc, MVMStatic
/* Create top-level graph object. */
MVMSpeshGraph *g = MVM_calloc(1, sizeof(MVMSpeshGraph));
g->sf = sf;
- g->bytecode = cand->bytecode;
- g->bytecode_size = cand->bytecode_size;
- g->handlers = cand->handlers;
- g->num_handlers = cand->num_handlers;
- g->num_locals = cand->num_locals;
- g->num_lexicals = cand->num_lexicals;
- g->inlines = cand->inlines;
- g->num_inlines = cand->num_inlines;
- g->deopt_addrs = cand->deopts;
- g->num_deopt_addrs = cand->num_deopts;
- g->alloc_deopt_addrs = cand->num_deopts;
- g->deopt_named_used_bit_field = cand->deopt_named_used_bit_field;
- g->deopt_pea = cand->deopt_pea;
- g->local_types = cand->local_types;
- g->lexical_types = cand->lexical_types;
- g->num_spesh_slots = cand->num_spesh_slots;
- g->alloc_spesh_slots = cand->num_spesh_slots;
+ g->bytecode = cand->body.bytecode;
+ g->bytecode_size = cand->body.bytecode_size;
+ g->handlers = cand->body.handlers;
+ g->num_handlers = cand->body.num_handlers;
+ g->num_locals = cand->body.num_locals;
+ g->num_lexicals = cand->body.num_lexicals;
+ g->inlines = cand->body.inlines;
+ g->num_inlines = cand->body.num_inlines;
+ g->deopt_addrs = cand->body.deopts;
+ g->num_deopt_addrs = cand->body.num_deopts;
+ g->alloc_deopt_addrs = cand->body.num_deopts;
+ g->deopt_named_used_bit_field = cand->body.deopt_named_used_bit_field;
+ g->deopt_pea = cand->body.deopt_pea;
+ g->local_types = cand->body.local_types;
+ g->lexical_types = cand->body.lexical_types;
+ g->num_spesh_slots = cand->body.num_spesh_slots;
+ g->alloc_spesh_slots = cand->body.num_spesh_slots;
g->phi_infos = MVM_spesh_alloc(tc, g, MVMPhiNodeCacheSize * sizeof(MVMOpInfo));
g->cand = cand;
g->spesh_slots = MVM_malloc(g->alloc_spesh_slots * sizeof(MVMCollectable *));
- memcpy(g->spesh_slots, cand->spesh_slots, sizeof(MVMCollectable *) * g->num_spesh_slots);
+ memcpy(g->spesh_slots, cand->body.spesh_slots, sizeof(MVMCollectable *) * g->num_spesh_slots);
/* Ensure the frame is validated, since we'll rely on this. */
if (sf->body.instrumentation_level == 0) {
@@ -1346,7 +1346,7 @@ MVMSpeshGraph * MVM_spesh_graph_create_from_cand(MVMThreadContext *tc, MVMStatic
}
/* Build the CFG out of the static frame, and transform it to SSA. */
- build_cfg(tc, g, sf, cand->deopts, cand->num_deopts, cand->deopt_usage_info,
+ build_cfg(tc, g, sf, cand->body.deopts, cand->body.num_deopts, cand->body.deopt_usage_info,
deopt_usage_ins_out);
if (!cfg_only) {
MVM_spesh_eliminate_dead_bbs(tc, g, 0);
@@ -1463,21 +1463,21 @@ void MVM_spesh_graph_destroy(MVMThreadContext *tc, MVMSpeshGraph *g) {
/* If there is a candidate that we either generated or that this graph was
* generated from, it has ownership of the malloc'd memory. If not, then we
* need to clean up */
- if (g->spesh_slots && (!g->cand || g->cand->spesh_slots != g->spesh_slots))
+ if (g->spesh_slots && (!g->cand || g->cand->body.spesh_slots != g->spesh_slots))
MVM_free(g->spesh_slots);
- if (g->deopt_addrs && (!g->cand || g->cand->deopts != g->deopt_addrs))
+ if (g->deopt_addrs && (!g->cand || g->cand->body.deopts != g->deopt_addrs))
MVM_free(g->deopt_addrs);
- if (g->inlines && (!g->cand || g->cand->inlines != g->inlines))
+ if (g->inlines && (!g->cand || g->cand->body.inlines != g->inlines))
MVM_free(g->inlines);
- if (g->local_types && (!g->cand || g->cand->local_types != g->local_types))
+ if (g->local_types && (!g->cand || g->cand->body.local_types != g->local_types))
MVM_free(g->local_types);
- if (g->lexical_types && (!g->cand || g->cand->lexical_types != g->lexical_types))
+ if (g->lexical_types && (!g->cand || g->cand->body.lexical_types != g->lexical_types))
MVM_free(g->lexical_types);
/* Handlers can come directly from static frame, from spesh candidate, and
* from malloc/realloc. We only free it in the last case */
if (g->handlers && g->handlers != g->sf->body.handlers &&
- (!g->cand || g->cand->handlers != g->handlers))
+ (!g->cand || g->cand->body.handlers != g->handlers))
MVM_free(g->handlers);
/* Free the graph itself. */
diff --git src/spesh/inline.c src/spesh/inline.c
index 12185a099..24d04b226 100644
--- src/spesh/inline.c
+++ src/spesh/inline.c
@@ -208,10 +208,10 @@ static int is_graph_inlineable(MVMThreadContext *tc, MVMSpeshGraph *inliner,
/* Gets the effective size for inlining considerations of a specialization,
* which is its code size minus the code size of its inlines. */
static MVMint32 get_effective_size(MVMThreadContext *tc, MVMSpeshCandidate *cand) {
- MVMint32 result = cand->bytecode_size;
+ MVMint32 result = cand->body.bytecode_size;
MVMuint32 i;
- for (i = 0; i < cand->num_inlines; i++)
- result -= cand->inlines[i].bytecode_size;
+ for (i = 0; i < cand->body.num_inlines; i++)
+ result -= cand->body.inlines[i].bytecode_size;
if (result < 0)
result = 0;
return (MVMuint32)result;
@@ -277,7 +277,7 @@ MVMSpeshGraph * MVM_spesh_inline_try_get_graph(MVMThreadContext *tc, MVMSpeshGra
* sure it stays available for deopt. */
MVMuint32 i;
MVM_spesh_facts_discover(tc, ig, NULL, 1);
- add_deopt_usages(tc, ig, cand->deopt_usage_info, deopt_usage_ins);
+ add_deopt_usages(tc, ig, cand->body.deopt_usage_info, deopt_usage_ins);
for (i = 0; i < ig->num_inlines; i++) {
/* We can't be very precise about this, because we don't know the
* SSA version in effect. So bump usages of all version of the
diff --git src/spesh/optimize.c src/spesh/optimize.c
index bb56f8448..11d01dec7 100644
--- src/spesh/optimize.c
+++ src/spesh/optimize.c
@@ -2075,7 +2075,7 @@ static void optimize_call(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb
MVM_spesh_usages_add_unconditional_deopt_usage_by_reg(tc, g, code_ref_reg);
MVM_spesh_inline(tc, g, arg_info, bb, ins, inline_graph, target_sf,
code_ref_reg, prepargs_deopt_idx,
- (MVMuint16)target_sf->body.spesh->body.spesh_candidates[spesh_cand]->bytecode_size);
+ (MVMuint16)target_sf->body.spesh->body.spesh_candidates[spesh_cand]->body.bytecode_size);
optimize_bb(tc, g, optimize_from_bb, NULL);
if (MVM_spesh_debug_enabled(tc)) {
diff --git src/spesh/osr.c src/spesh/osr.c
index 5323eb2a0..18fb93c01 100644
--- src/spesh/osr.c
+++ src/spesh/osr.c
@@ -10,8 +10,8 @@ static MVMint32 get_osr_deopt_index(MVMThreadContext *tc, MVMSpeshCandidate *can
/* Locate it in the deopt table. */
MVMuint32 i;
- for (i = 0; i < cand->num_deopts; i++)
- if (cand->deopts[2 * i] == offset)
+ for (i = 0; i < cand->body.num_deopts; i++)
+ if (cand->body.deopts[2 * i] == offset)
return i;
/* If we couldn't locate it, something is really very wrong. */
@@ -31,15 +31,15 @@ void perform_osr(MVMThreadContext *tc, MVMSpeshCandidate *specialized) {
osr_index);
#endif
- jit_code = specialized->jitcode;
+ jit_code = specialized->body.jitcode;
num_locals = jit_code && jit_code->local_types ?
- jit_code->num_locals : specialized->num_locals;
+ jit_code->num_locals : specialized->body.num_locals;
/* Resize work area if needed. */
- if (specialized->work_size > tc->cur_frame->allocd_work) {
+ if (specialized->body.work_size > tc->cur_frame->allocd_work) {
/* Resize work area. */
MVMRegister *new_work = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa,
- specialized->work_size);
+ specialized->body.work_size);
MVMRegister *new_args = new_work + num_locals;
memcpy(new_work, tc->cur_frame->work,
tc->cur_frame->static_info->body.num_locals * sizeof(MVMRegister));
@@ -49,7 +49,7 @@ void perform_osr(MVMThreadContext *tc, MVMSpeshCandidate *specialized) {
MVM_fixed_size_free(tc, tc->instance->fsa, tc->cur_frame->allocd_work,
tc->cur_frame->work);
tc->cur_frame->work = new_work;
- tc->cur_frame->allocd_work = specialized->work_size;
+ tc->cur_frame->allocd_work = specialized->body.work_size;
tc->cur_frame->args = new_args;
#if MVM_LOG_OSR
fprintf(stderr, "OSR resized work area of frame '%s' (cuid: %s)\n",
@@ -57,16 +57,16 @@ void perform_osr(MVMThreadContext *tc, MVMSpeshCandidate *specialized) {
MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid));
#endif
}
- else if (specialized->work_size > tc->cur_frame->static_info->body.work_size) {
+ else if (specialized->body.work_size > tc->cur_frame->static_info->body.work_size) {
size_t keep_bytes = tc->cur_frame->static_info->body.num_locals * sizeof(MVMRegister);
- size_t to_null = specialized->work_size - keep_bytes;
+ size_t to_null = specialized->body.work_size - keep_bytes;
memset((char *)tc->cur_frame->work + keep_bytes, 0, to_null);
}
/* Resize environment if needed. */
- if (specialized->num_lexicals > tc->cur_frame->static_info->body.num_lexicals) {
+ if (specialized->body.num_lexicals > tc->cur_frame->static_info->body.num_lexicals) {
MVMRegister *new_env = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa,
- specialized->env_size);
+ specialized->body.env_size);
if (tc->cur_frame->allocd_env) {
memcpy(new_env, tc->cur_frame->env,
tc->cur_frame->static_info->body.num_lexicals * sizeof(MVMRegister));
@@ -74,21 +74,21 @@ void perform_osr(MVMThreadContext *tc, MVMSpeshCandidate *specialized) {
tc->cur_frame->env);
}
tc->cur_frame->env = new_env;
- tc->cur_frame->allocd_env = specialized->env_size;
+ tc->cur_frame->allocd_env = specialized->body.env_size;
#if MVM_LOG_OSR
fprintf(stderr, "OSR resized environment of frame '%s' (cuid: %s)\n",
MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.name),
MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid));
#endif
}
- else if (specialized->env_size > tc->cur_frame->static_info->body.env_size) {
+ else if (specialized->body.env_size > tc->cur_frame->static_info->body.env_size) {
size_t keep_bytes = tc->cur_frame->static_info->body.num_lexicals * sizeof(MVMRegister);
- size_t to_null = specialized->env_size - keep_bytes;
+ size_t to_null = specialized->body.env_size - keep_bytes;
memset((char *)tc->cur_frame->env + keep_bytes, 0, to_null);
}
/* Set up frame to point to spesh candidate/slots. */
- tc->cur_frame->effective_spesh_slots = specialized->spesh_slots;
+ tc->cur_frame->effective_spesh_slots = specialized->body.spesh_slots;
tc->cur_frame->spesh_cand = specialized;
/* Move into the optimized (and maybe JIT-compiled) code. */
@@ -109,9 +109,9 @@ void perform_osr(MVMThreadContext *tc, MVMSpeshCandidate *specialized) {
if (tc->instance->profiling)
MVM_profiler_log_osr(tc, 1);
} else {
- *(tc->interp_bytecode_start) = specialized->bytecode;
- *(tc->interp_cur_op) = specialized->bytecode +
- specialized->deopts[2 * osr_index + 1];
+ *(tc->interp_bytecode_start) = specialized->body.bytecode;
+ *(tc->interp_cur_op) = specialized->body.bytecode +
+ specialized->body.deopts[2 * osr_index + 1];
if (tc->instance->profiling)
MVM_profiler_log_osr(tc, 0);
}
diff --git src/spesh/plan.c src/spesh/plan.c
index b729f0bd3..bf700ab8b 100644
--- src/spesh/plan.c
+++ src/spesh/plan.c
@@ -6,9 +6,9 @@ MVMint32 have_existing_specialization(MVMThreadContext *tc, MVMStaticFrame *sf,
MVMStaticFrameSpesh *sfs = sf->body.spesh;
MVMuint32 i;
for (i = 0; i < sfs->body.num_spesh_candidates; i++) {
- if (sfs->body.spesh_candidates[i]->cs == cs) {
+ if (sfs->body.spesh_candidates[i]->body.cs == cs) {
/* Callsite matches. Is it a matching certain specialization? */
- MVMSpeshStatsType *cand_type_tuple = sfs->body.spesh_candidates[i]->type_tuple;
+ MVMSpeshStatsType *cand_type_tuple = sfs->body.spesh_candidates[i]->body.type_tuple;
if (type_tuple == NULL && cand_type_tuple == NULL) {
/* Yes, so we're done. */
return 1;
diff --git src/types.h src/types.h
index b2481db1d..1ee0eb820 100644
--- src/types.h
+++ src/types.h
@@ -166,6 +166,7 @@ typedef struct MVMSpeshAnn MVMSpeshAnn;
typedef struct MVMSpeshFacts MVMSpeshFacts;
typedef struct MVMSpeshCode MVMSpeshCode;
typedef struct MVMSpeshCandidate MVMSpeshCandidate;
+typedef struct MVMSpeshCandidateBody MVMSpeshCandidateBody;
typedef struct MVMSpeshLogGuard MVMSpeshLogGuard;
typedef struct MVMSpeshCallInfo MVMSpeshCallInfo;
typedef struct MVMSpeshInline MVMSpeshInline;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment