Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Created December 28, 2020 17:00
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/a2f24b384dbef490295b661e8d54455f to your computer and use it in GitHub Desktop.
Save MasterDuke17/a2f24b384dbef490295b661e8d54455f to your computer and use it in GitHub Desktop.
diff --git src/6model/reprs/MVMSpeshCandidate.c src/6model/reprs/MVMSpeshCandidate.c
index 370571401..306cca36f 100644
--- src/6model/reprs/MVMSpeshCandidate.c
+++ src/6model/reprs/MVMSpeshCandidate.c
@@ -170,6 +170,8 @@ void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
MVMSpeshCandidate *candidate;
MVMSpeshCandidate **new_candidate_list;
MVMStaticFrameSpesh *spesh;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards;
+ MVMSpeshCandidatesAndArgGuards *new_cands_and_arg_guards;
MVMuint64 start_time = 0, spesh_time = 0, jit_time = 0, end_time;
/* If we've reached our specialization limit, don't continue. */
@@ -309,16 +311,23 @@ void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
/* Create a new candidate list and copy any existing ones. Free memory
* using the FSA safepoint mechanism. */
spesh = p->sf->body.spesh;
+ cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
+ new_cands_and_arg_guards = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ sizeof(MVMSpeshCandidatesAndArgGuards));
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);
+ memcpy(new_candidate_list, cands_and_arg_guards->spesh_candidates, orig_size);
MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, orig_size,
- spesh->body.spesh_candidates);
+ cands_and_arg_guards->spesh_candidates);
+ new_cands_and_arg_guards->spesh_arg_guard = cands_and_arg_guards->spesh_arg_guard;
+ MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, sizeof(MVMSpeshCandidatesAndArgGuards),
+ cands_and_arg_guards);
}
MVM_ASSIGN_REF(tc, &(spesh->common.header), new_candidate_list[spesh->body.num_spesh_candidates], candidate);
- spesh->body.spesh_candidates = new_candidate_list;
+ new_cands_and_arg_guards->spesh_candidates = new_candidate_list;
+ spesh->body.spesh_cands_and_arg_guards = new_cands_and_arg_guards;
/* May now be referencing nursery objects, so barrier just in case. */
//if (spesh->common.header.flags2 & MVM_CF_SECOND_GEN)
@@ -333,15 +342,15 @@ void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
* 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_spesh_arg_guard_regenerate(tc, (cands_and_arg_guards ? &(cands_and_arg_guards->spesh_arg_guard) : NULL),
+ (cands_and_arg_guards ? cands_and_arg_guards->spesh_candidates : NULL), spesh->body.num_spesh_candidates + 1);
MVM_barrier();
spesh->body.num_spesh_candidates++;
/* If we're logging, dump the updated 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);
+ p->sf->body.spesh->body.spesh_cands_and_arg_guards->spesh_arg_guard);
MVM_spesh_debug_printf(tc, "%s========\n\n", guard_dump);
fflush(tc->instance->spesh_log_fh);
MVM_free(guard_dump);
@@ -357,10 +366,69 @@ void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
void MVM_spesh_candidate_discard_existing(MVMThreadContext *tc, MVMStaticFrame *sf) {
MVMStaticFrameSpesh *spesh = sf->body.spesh;
if (spesh) {
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
MVMuint32 num_candidates = spesh->body.num_spesh_candidates;
MVMuint32 i;
for (i = 0; i < num_candidates; i++)
- spesh->body.spesh_candidates[i]->body.discarded = 1;
+ cands_and_arg_guards->spesh_candidates[i]->body.discarded = 1;
MVM_spesh_arg_guard_discard(tc, sf);
}
}
+
+/* Discards one candidates. */
+void MVM_spesh_candidate_discard_one(MVMThreadContext *tc, MVMStaticFrame *sf, MVMSpeshCandidate *cand) {
+ MVMStaticFrameSpesh *spesh = sf->body.spesh;
+ if (spesh) {
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
+ MVMSpeshCandidatesAndArgGuards *new_cands_and_arg_guards;
+ MVMuint32 i, found = 0, new_num = spesh->body.num_spesh_candidates - 1;
+
+ for (i = 0; i < spesh->body.num_spesh_candidates; i++) {
+ MVMSpeshCandidate *sc = cands_and_arg_guards->spesh_candidates[i];
+ if (sc == cand) {
+ cand->body.discarded = 1;
+ found = 1;
+ //fprintf(stderr, "found the matching candidate at index %u\n", i);
+ break;
+ }
+ }
+
+ if (!found) {
+ fprintf(stderr, "no matching cand found?! Didn't think this was going to happen.\n");
+ return;
+ }
+
+ MVMSpeshCandidate **new_cands;
+ if (new_num > 0) {
+ fprintf(stderr, "i = %u, new_num = %u\n", i, new_num);
+ new_cands = MVM_fixed_size_alloc(tc, tc->instance->fsa, new_num * sizeof(MVMSpeshCandidate *));
+ new_cands_and_arg_guards = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMSpeshCandidatesAndArgGuards));
+ if (i == 0) {
+ memcpy(new_cands, cands_and_arg_guards->spesh_candidates + sizeof(MVMSpeshCandidate *), new_num * sizeof(MVMSpeshCandidate *));
+ }
+ else if (i == new_num) {
+ memcpy(new_cands, cands_and_arg_guards->spesh_candidates, new_num * sizeof(MVMSpeshCandidate *));
+ }
+ else {
+ memcpy(new_cands, cands_and_arg_guards->spesh_candidates, i * sizeof(MVMSpeshCandidate *));
+ memcpy(new_cands + i * sizeof(MVMSpeshCandidate *), cands_and_arg_guards->spesh_candidates + (i + 1) * sizeof(MVMSpeshCandidate *), (new_num - i) * sizeof(MVMSpeshCandidate *));
+ }
+ }
+
+ MVM_fixed_size_free_at_safepoint(tc, tc->instance->fsa, (new_num + 1) * sizeof(MVMSpeshCandidate *),
+ cands_and_arg_guards->spesh_candidates);
+
+ if (new_num > 0) {
+ new_cands_and_arg_guards->spesh_candidates = new_cands;
+ MVM_spesh_arg_guard_regenerate(tc, &(new_cands_and_arg_guards->spesh_arg_guard),
+ new_cands_and_arg_guards->spesh_candidates, new_num);
+ }
+ else {
+ new_cands_and_arg_guards->spesh_candidates = NULL;
+ MVM_spesh_arg_guard_discard(tc, sf);
+ }
+
+ spesh->body.num_spesh_candidates--;
+ spesh->body.spesh_cands_and_arg_guards = new_cands_and_arg_guards;
+ }
+}
diff --git src/6model/reprs/MVMSpeshCandidate.h src/6model/reprs/MVMSpeshCandidate.h
index e0b189990..f3b70bbed 100644
--- src/6model/reprs/MVMSpeshCandidate.h
+++ src/6model/reprs/MVMSpeshCandidate.h
@@ -31,6 +31,9 @@ struct MVMSpeshCandidateBody {
/* Deoptimization mappings. */
MVMint32 *deopts;
+ /* Count of times an optimization was deopted. */
+ MVMuint32 deopt_count;
+
/* 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;
@@ -88,3 +91,4 @@ const MVMREPROps * MVMSpeshCandidate_initialize(MVMThreadContext *tc);
/* Functions for creating and clearing up specializations. */
void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p);
void MVM_spesh_candidate_discard_existing(MVMThreadContext *tc, MVMStaticFrame *sf);
+void MVM_spesh_candidate_discard_one(MVMThreadContext *tc, MVMStaticFrame *sf, MVMSpeshCandidate *cand);
diff --git src/6model/reprs/MVMStaticFrameSpesh.c src/6model/reprs/MVMStaticFrameSpesh.c
index 86d5432b1..df513d444 100644
--- src/6model/reprs/MVMStaticFrameSpesh.c
+++ src/6model/reprs/MVMStaticFrameSpesh.c
@@ -25,12 +25,13 @@ static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *d
/* Called by the VM to mark any GCable items. */
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = body->spesh_cands_and_arg_guards;
MVM_spesh_stats_gc_mark(tc, body->spesh_stats, worklist);
- MVM_spesh_arg_guard_gc_mark(tc, body->spesh_arg_guard, worklist);
+ MVM_spesh_arg_guard_gc_mark(tc, cands_and_arg_guards->spesh_arg_guard, worklist);
if (body->num_spesh_candidates) {
MVMuint32 i;
for (i = 0; i < body->num_spesh_candidates; i++) {
- MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]);
+ MVM_gc_worklist_add(tc, worklist, &cands_and_arg_guards->spesh_candidates[i]);
}
}
MVM_gc_worklist_add(tc, worklist, &body->plugin_state);
@@ -39,9 +40,10 @@ 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;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = sfs->body.spesh_cands_and_arg_guards;
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);
+ MVM_spesh_arg_guard_destroy(tc, cands_and_arg_guards->spesh_arg_guard, 0);
}
static const MVMStorageSpec storage_spec = {
@@ -72,10 +74,11 @@ static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSeri
/* Calculates the non-GC-managed memory we hold on to. */
static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data) {
MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = body->spesh_cands_and_arg_guards;
MVMuint64 size = 0;
MVMuint32 spesh_idx;
for (spesh_idx = 0; spesh_idx < body->num_spesh_candidates; spesh_idx++) {
- MVMSpeshCandidate *cand = body->spesh_candidates[spesh_idx];
+ MVMSpeshCandidate *cand = cands_and_arg_guards->spesh_candidates[spesh_idx];
size += cand->body.bytecode_size;
@@ -113,20 +116,21 @@ static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data)
static void describe_refs(MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSTable *st, void *data) {
MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = body->spesh_cands_and_arg_guards;
MVM_spesh_stats_gc_describe(tc, ss, body->spesh_stats);
- MVM_spesh_arg_guard_gc_describe(tc, ss, body->spesh_arg_guard);
+ MVM_spesh_arg_guard_gc_describe(tc, ss, cands_and_arg_guards->spesh_arg_guard);
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]->body.num_spesh_slots; j++)
+ for (j = 0; j < cands_and_arg_guards->spesh_candidates[i]->body.num_spesh_slots; j++)
MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
- (MVMCollectable *)body->spesh_candidates[i]->body.spesh_slots[j],
+ (MVMCollectable *)cands_and_arg_guards->spesh_candidates[i]->body.spesh_slots[j],
"Spesh slot entry");
- for (j = 0; j < body->spesh_candidates[i]->body.num_inlines; j++)
+ for (j = 0; j < cands_and_arg_guards->spesh_candidates[i]->body.num_inlines; j++)
MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
- (MVMCollectable *)body->spesh_candidates[i]->body.inlines[j].sf,
+ (MVMCollectable *)cands_and_arg_guards->spesh_candidates[i]->body.inlines[j].sf,
"Spesh inlined static frame");
}
}
diff --git src/6model/reprs/MVMStaticFrameSpesh.h src/6model/reprs/MVMStaticFrameSpesh.h
index f2e6f16b1..dbd3ffe88 100644
--- src/6model/reprs/MVMStaticFrameSpesh.h
+++ src/6model/reprs/MVMStaticFrameSpesh.h
@@ -2,7 +2,7 @@
* about a static frame (logged statistics, generated specializations, and
* so forth). */
-struct MVMStaticFrameSpeshBody {
+struct MVMSpeshCandidatesAndArgGuards {
/* Specialization argument guard tree, for selecting a specialization. */
MVMSpeshArgGuard *spesh_arg_guard;
@@ -10,6 +10,11 @@ struct MVMStaticFrameSpeshBody {
* move in memory; the array of pointers to them is managed using the
* fixed size allocator and freed at the next safepoint. */
MVMSpeshCandidate **spesh_candidates;
+};
+
+struct MVMStaticFrameSpeshBody {
+ MVMSpeshCandidatesAndArgGuards *spesh_cands_and_arg_guards;
+
MVMuint32 num_spesh_candidates;
/* Recorded count for data recording for the specializer. Incremented
diff --git src/core/bytecodedump.c src/core/bytecodedump.c
index 9197927af..7a5f4b0f0 100644
--- src/core/bytecodedump.c
+++ src/core/bytecodedump.c
@@ -562,8 +562,9 @@ void MVM_dump_bytecode_stackframe(MVMThreadContext *tc, MVMint32 depth) {
} else {
MVMuint32 spesh_cand_idx;
MVMStaticFrameSpesh *spesh = sf->body.spesh;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
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];
+ MVMSpeshCandidate *cand = cands_and_arg_guards->spesh_candidates[spesh_cand_idx];
if (cand->body.bytecode == effective_bytecode) {
MVM_dump_bytecode_of(tc, frame, cand);
}
diff --git src/core/frame.c src/core/frame.c
index 0a866d540..c7b8821c2 100644
--- src/core/frame.c
+++ src/core/frame.c
@@ -400,6 +400,7 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
MVMFrame *frame;
MVMuint8 *chosen_bytecode;
MVMStaticFrameSpesh *spesh;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards;
/* If the frame was never invoked before, or never before at the current
* instrumentation level, we need to trigger the instrumentation level
@@ -489,13 +490,14 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
/* See if any specializations apply. */
spesh = static_frame->body.spesh;
+ cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
if (spesh_cand < 0)
- spesh_cand = MVM_spesh_arg_guard_run(tc, spesh->body.spesh_arg_guard,
+ spesh_cand = MVM_spesh_arg_guard_run(tc, (cands_and_arg_guards ? cands_and_arg_guards->spesh_arg_guard : NULL),
callsite, args, NULL);
#if MVM_SPESH_CHECK_PRESELECTION
else {
MVMint32 certain = -1;
- MVMint32 correct = MVM_spesh_arg_guard_run(tc, spesh->body.spesh_arg_guard,
+ MVMint32 correct = MVM_spesh_arg_guard_run(tc, cands_and_arg_guards->spesh_arg_guard,
callsite, args, &certain);
if (spesh_cand != correct && spesh_cand != certain) {
fprintf(stderr, "Inconsistent spesh preselection of '%s' (%s): got %d, not %d\n",
@@ -506,8 +508,8 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
}
}
#endif
- if (spesh_cand >= 0) {
- MVMSpeshCandidate *chosen_cand = spesh->body.spesh_candidates[spesh_cand];
+ if (spesh_cand >= 0 && spesh_cand < spesh->body.num_spesh_candidates) {
+ MVMSpeshCandidate *chosen_cand = cands_and_arg_guards->spesh_candidates[spesh_cand];
if (static_frame->body.allocate_on_heap) {
MVMROOT4(tc, static_frame, code_ref, outer, chosen_cand, {
frame = allocate_frame(tc, static_frame, chosen_cand, 1);
diff --git src/spesh/arg_guard.c src/spesh/arg_guard.c
index 8c114d24d..b7dd4e5ea 100644
--- src/spesh/arg_guard.c
+++ src/spesh/arg_guard.c
@@ -651,8 +651,11 @@ void MVM_spesh_arg_guard_destroy(MVMThreadContext *tc, MVMSpeshArgGuard *ag, MVM
* candidates will no longer be reachable. */
void MVM_spesh_arg_guard_discard(MVMThreadContext *tc, MVMStaticFrame *sf) {
MVMStaticFrameSpesh *spesh = sf->body.spesh;
- if (spesh && spesh->body.spesh_arg_guard) {
- MVM_spesh_arg_guard_destroy(tc, spesh->body.spesh_arg_guard, 1);
- spesh->body.spesh_arg_guard = NULL;
+ if (spesh) {
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
+ if (cands_and_arg_guards->spesh_arg_guard) {
+ MVM_spesh_arg_guard_destroy(tc, cands_and_arg_guards->spesh_arg_guard, 1);
+ cands_and_arg_guards->spesh_arg_guard = NULL;
+ }
}
}
diff --git src/spesh/deopt.c src/spesh/deopt.c
index 87a408de3..f12326dff 100644
--- src/spesh/deopt.c
+++ src/spesh/deopt.c
@@ -243,6 +243,13 @@ static void deopt_frame(MVMThreadContext *tc, MVMFrame *f, MVMuint32 deopt_idx,
materialize_replaced_objects(tc, f, deopt_idx);
});
+ /* Log that this opt was deopted, we want to undo the
+ * optimization if this happens too many times. */
+ if (f->spesh_cand->body.deopt_count++ > 100) {
+ //fprintf(stderr, "uh, lots of deopts for %p, maybe it should be removed\n", f->spesh_cand);
+ MVM_spesh_candidate_discard_one(tc, f->static_info, f->spesh_cand);
+ }
+
/* Check if we have inlines. */
if (f->spesh_cand->body.inlines) {
/* Yes, going to have to re-create the frames; uninline
diff --git src/spesh/optimize.c src/spesh/optimize.c
index 599ed0956..955dc7d0d 100644
--- src/spesh/optimize.c
+++ src/spesh/optimize.c
@@ -1555,7 +1555,8 @@ static void optimize_getlex_per_invocant(MVMThreadContext *tc, MVMSpeshGraph *g,
static MVMint32 try_find_spesh_candidate(MVMThreadContext *tc, MVMStaticFrame *sf,
MVMSpeshCallInfo *arg_info,
MVMSpeshStatsType *type_tuple) {
- MVMSpeshArgGuard *ag = sf->body.spesh->body.spesh_arg_guard;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = sf->body.spesh->body.spesh_cands_and_arg_guards;
+ MVMSpeshArgGuard *ag = cands_and_arg_guards ? cands_and_arg_guards->spesh_arg_guard : NULL;
return type_tuple
? MVM_spesh_arg_guard_run_types(tc, ag, arg_info->cs, type_tuple)
: MVM_spesh_arg_guard_run_callinfo(tc, ag, arg_info);
@@ -2071,8 +2072,9 @@ static void optimize_call(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb
char *no_inline_reason = NULL;
const MVMOpInfo *no_inline_info = NULL;
MVMuint32 effective_size;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = target_sf->body.spesh->body.spesh_cands_and_arg_guards;
MVMSpeshGraph *inline_graph = MVM_spesh_inline_try_get_graph(tc, g,
- target_sf, target_sf->body.spesh->body.spesh_candidates[spesh_cand],
+ target_sf, cands_and_arg_guards->spesh_candidates[spesh_cand],
ins, &no_inline_reason, &effective_size, &no_inline_info);
log_inline(tc, g, target_sf, inline_graph, effective_size, no_inline_reason, 0, no_inline_info);
if (inline_graph) {
@@ -2086,7 +2088,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]->body.bytecode_size);
+ (MVMuint16)cands_and_arg_guards->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 d414baea4..a546c2e63 100644
--- src/spesh/osr.c
+++ src/spesh/osr.c
@@ -155,6 +155,7 @@ MVMCallsite * find_callsite_and_args(MVMThreadContext *tc, MVMRegister **args) {
/* Polls for an optimization and, when one is produced, jumps into it. */
void MVM_spesh_osr_poll_for_result(MVMThreadContext *tc) {
MVMStaticFrameSpesh *spesh = tc->cur_frame->static_info->body.spesh;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = spesh->body.spesh_cands_and_arg_guards;
MVMint32 num_cands = spesh->body.num_spesh_candidates;
MVMint32 seq_nr = tc->cur_frame->sequence_nr;
if (seq_nr != tc->osr_hunt_frame_nr || num_cands != tc->osr_hunt_num_spesh_candidates) {
@@ -164,11 +165,11 @@ void MVM_spesh_osr_poll_for_result(MVMThreadContext *tc) {
MVMRegister *args;
MVMCallsite *cs = find_callsite_and_args(tc, &args);
MVMint32 ag_result = MVM_spesh_arg_guard_run(tc,
- spesh->body.spesh_arg_guard,
+ (cands_and_arg_guards ? cands_and_arg_guards->spesh_arg_guard : NULL),
(cs && cs->is_interned ? cs : NULL),
args, NULL);
if (ag_result >= 0)
- perform_osr(tc, spesh->body.spesh_candidates[ag_result]);
+ perform_osr(tc, cands_and_arg_guards->spesh_candidates[ag_result]);
}
/* Update state for avoiding checks in the common case. */
diff --git src/spesh/plan.c src/spesh/plan.c
index bf700ab8b..660b54322 100644
--- src/spesh/plan.c
+++ src/spesh/plan.c
@@ -4,11 +4,12 @@
MVMint32 have_existing_specialization(MVMThreadContext *tc, MVMStaticFrame *sf,
MVMCallsite *cs, MVMSpeshStatsType *type_tuple) {
MVMStaticFrameSpesh *sfs = sf->body.spesh;
+ MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards = sfs->body.spesh_cands_and_arg_guards;
MVMuint32 i;
for (i = 0; i < sfs->body.num_spesh_candidates; i++) {
- if (sfs->body.spesh_candidates[i]->body.cs == cs) {
+ if (cands_and_arg_guards->spesh_candidates[i]->body.cs == cs) {
/* Callsite matches. Is it a matching certain specialization? */
- MVMSpeshStatsType *cand_type_tuple = sfs->body.spesh_candidates[i]->body.type_tuple;
+ MVMSpeshStatsType *cand_type_tuple = cands_and_arg_guards->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 1ee0eb820..8329429d3 100644
--- src/types.h
+++ src/types.h
@@ -213,6 +213,7 @@ typedef struct MVMStaticFrameInstrumentation MVMStaticFrameInstrumentation;
typedef struct MVMStaticFrameDebugLocal MVMStaticFrameDebugLocal;
typedef struct MVMStaticFrameSpesh MVMStaticFrameSpesh;
typedef struct MVMStaticFrameSpeshBody MVMStaticFrameSpeshBody;
+typedef struct MVMSpeshCandidatesAndArgGuards MVMSpeshCandidatesAndArgGuards;
typedef struct MVMStorageSpec MVMStorageSpec;
typedef struct MVMString MVMString;
typedef struct MVMStringBody MVMStringBody;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment