-
-
Save MasterDuke17/5541873da1f7ebfd201652d7a6d1ddda to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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