-
-
Save MasterDuke17/a2f24b384dbef490295b661e8d54455f 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 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