Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active Feb 10, 2021
Embed
What would you like to do?
diff --git src/6model/reprs/MVMCode.c src/6model/reprs/MVMCode.c
index ebe6652ea..b670ed4c7 100644
--- src/6model/reprs/MVMCode.c
+++ src/6model/reprs/MVMCode.c
@@ -8,7 +8,7 @@ static void invoke_handler(MVMThreadContext *tc, MVMObject *invokee, MVMCallsite
if (IS_CONCRETE(invokee)) {
MVMCode *code = (MVMCode *)invokee;
MVM_frame_invoke(tc, code->body.sf, callsite, args,
- code->body.outer, invokee, -1);
+ code->body.outer, invokee, NULL);
}
else {
MVM_exception_throw_adhoc(tc, "Cannot invoke code type object");
diff --git src/6model/reprs/MVMSpeshCandidate.c src/6model/reprs/MVMSpeshCandidate.c
index 22e38b836..342107975 100644
--- src/6model/reprs/MVMSpeshCandidate.c
+++ src/6model/reprs/MVMSpeshCandidate.c
@@ -436,7 +436,7 @@ void MVM_spesh_candidate_discard_one(MVMThreadContext *tc, MVMStaticFrame *sf, M
/* Copy the existing candidates, minus the one to remove, and regenerate the arg guards. */
if (new_num > 0) {
- fprintf(stderr, "i = %u, new_num = %u\n", i, new_num);
+ //fprintf(stderr, "i = %u, new_num = %u\n", i, new_num);
new_cands_and_arg_guards = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, sizeof(MVMSpeshCandidatesAndArgGuards));
new_cands = MVM_fixed_size_alloc( tc, tc->instance->fsa, new_num * sizeof(MVMSpeshCandidate *));
@@ -461,7 +461,7 @@ void MVM_spesh_candidate_discard_one(MVMThreadContext *tc, MVMStaticFrame *sf, M
}
/* There was only one, so remove it and the arg guards. */
else {
- fprintf(stderr, "removing the only existing candidate\n");
+ //fprintf(stderr, "removing the only existing candidate\n");
MVM_spesh_arg_guard_discard(tc, sf);
MVM_barrier();
spesh->body.spesh_cands_and_arg_guards = NULL;
diff --git src/core/frame.c src/core/frame.c
index c2887373d..52feb8844 100644
--- src/core/frame.c
+++ src/core/frame.c
@@ -388,7 +388,7 @@ static MVMFrame * allocate_heap_frame(MVMThreadContext *tc, MVMStaticFrame *stat
/* This exists to reduce the amount of pointer-fiddling that has to be
* done by the JIT */
void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code,
- MVMCallsite *callsite, MVMint32 spesh_cand) {
+ MVMCallsite *callsite, MVMSpeshCandidate *spesh_cand) {
MVM_frame_invoke(tc, code->body.sf, callsite, tc->cur_frame->args,
code->body.outer, (MVMObject*)code, spesh_cand);
}
@@ -396,9 +396,10 @@ void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code,
/* Takes a static frame and a thread context. Invokes the static frame. */
void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
MVMCallsite *callsite, MVMRegister *args,
- MVMFrame *outer, MVMObject *code_ref, MVMint32 spesh_cand) {
+ MVMFrame *outer, MVMObject *code_ref, MVMSpeshCandidate *spesh_cand) {
MVMFrame *frame;
MVMuint8 *chosen_bytecode;
+ MVMint32 chosen_spesh_cand_index = -1;
MVMStaticFrameSpesh *spesh;
MVMSpeshCandidatesAndArgGuards *cands_and_arg_guards;
@@ -406,7 +407,7 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
* instrumentation level, we need to trigger the instrumentation level
* barrier. */
if (static_frame->body.instrumentation_level != tc->instance->instrumentation_level) {
- MVMROOT3(tc, static_frame, code_ref, outer, {
+ MVMROOT4(tc, static_frame, code_ref, outer, spesh_cand, {
instrumentation_level_barrier(tc, static_frame);
});
}
@@ -476,7 +477,7 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
}
else if (static_frame->body.outer) {
/* Auto-close, and cache it in the static frame. */
- MVMROOT3(tc, static_frame, code_ref, static_code, {
+ MVMROOT4(tc, static_frame, code_ref, static_code, spesh_cand, {
MVM_frame_force_to_heap(tc, tc->cur_frame);
outer = autoclose(tc, static_frame->body.outer);
MVM_ASSIGN_REF(tc, &(static_code->common.header),
@@ -491,43 +492,50 @@ 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 && cands_and_arg_guards)
- spesh_cand = MVM_spesh_arg_guard_run(tc, cands_and_arg_guards->spesh_arg_guard,
+ if (spesh_cand == NULL && cands_and_arg_guards)
+ chosen_spesh_cand_index = MVM_spesh_arg_guard_run(tc, cands_and_arg_guards->spesh_arg_guard,
callsite, args, NULL);
#if MVM_SPESH_CHECK_PRESELECTION
- else {
+ else if (cands_and_arg_guards) {
MVMint32 certain = -1;
+ for (MVMuint32 i = 0; i < spesh->body.num_spesh_candidates; i++) {
+ if (spesh_cand == cands_and_arg_guards->spesh_candidates[i]) {
+ chosen_spesh_cand_index = i;
+ break;
+ }
+ }
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) {
+ if (chosen_spesh_cand_index != correct && chosen_spesh_cand_index != certain) {
fprintf(stderr, "Inconsistent spesh preselection of '%s' (%s): got %d, not %d\n",
MVM_string_utf8_encode_C_string(tc, static_frame->body.name),
MVM_string_utf8_encode_C_string(tc, static_frame->body.cuuid),
- spesh_cand, correct);
+ chosen_spesh_cand_index, correct);
MVM_dump_backtrace(tc);
}
}
#endif
- if (spesh_cand >= 0 && spesh_cand < (MVMint32)spesh->body.num_spesh_candidates && cands_and_arg_guards) {
- MVMSpeshCandidate *chosen_cand = cands_and_arg_guards->spesh_candidates[spesh_cand];
+ if (spesh_cand || (chosen_spesh_cand_index >= 0 && chosen_spesh_cand_index < (MVMint32)spesh->body.num_spesh_candidates && cands_and_arg_guards)) {
+ if (!spesh_cand)
+ spesh_cand = cands_and_arg_guards->spesh_candidates[chosen_spesh_cand_index];
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);
+ MVMROOT4(tc, static_frame, code_ref, outer, spesh_cand, {
+ frame = allocate_frame(tc, static_frame, spesh_cand, 1);
});
}
else {
- frame = allocate_frame(tc, static_frame, chosen_cand, 0);
+ frame = allocate_frame(tc, static_frame, spesh_cand, 0);
frame->spesh_correlation_id = 0;
}
- if (chosen_cand->body.jitcode) {
- chosen_bytecode = chosen_cand->body.jitcode->bytecode;
- frame->jit_entry_label = chosen_cand->body.jitcode->labels[0];
+ if (spesh_cand->body.jitcode) {
+ chosen_bytecode = spesh_cand->body.jitcode->bytecode;
+ frame->jit_entry_label = spesh_cand->body.jitcode->labels[0];
}
else {
- chosen_bytecode = chosen_cand->body.bytecode;
+ chosen_bytecode = spesh_cand->body.bytecode;
}
- frame->effective_spesh_slots = chosen_cand->body.spesh_slots;
- MVM_ASSIGN_REF(tc, &(frame->header), frame->spesh_cand, chosen_cand);
+ frame->effective_spesh_slots = spesh_cand->body.spesh_slots;
+ MVM_ASSIGN_REF(tc, &(frame->header), frame->spesh_cand, spesh_cand);
}
else {
MVMint32 on_heap = static_frame->body.allocate_on_heap;
diff --git src/core/frame.h src/core/frame.h
index 3c3a629b0..2a5197768 100644
--- src/core/frame.h
+++ src/core/frame.h
@@ -206,10 +206,10 @@ MVMFrame * MVM_frame_debugserver_move_to_heap(MVMThreadContext *tc, MVMThreadCon
MVMRegister * MVM_frame_initial_work(MVMThreadContext *tc, MVMuint16 *local_types,
MVMuint16 num_locals);
void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code,
- MVMCallsite *callsite, MVMint32 spesh_cand);
+ MVMCallsite *callsite, MVMSpeshCandidate *spesh_cand);
void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
MVMCallsite *callsite, MVMRegister *args,
- MVMFrame *outer, MVMObject *code_ref, MVMint32 spesh_cand);
+ MVMFrame *outer, MVMObject *code_ref, MVMSpeshCandidate *spesh_cand);
MVMFrame * MVM_frame_create_context_only(MVMThreadContext *tc, MVMStaticFrame *static_frame,
MVMObject *code_ref);
MVMFrame * MVM_frame_create_for_deopt(MVMThreadContext *tc, MVMStaticFrame *static_frame,
diff --git src/core/interp.c src/core/interp.c
index 3ce41282f..ec2977c7f 100644
--- src/core/interp.c
+++ src/core/interp.c
@@ -5948,7 +5948,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(sp_fastinvoke_v): {
MVMCode *code = (MVMCode *)GET_REG(cur_op, 0).o;
MVMRegister *args = tc->cur_frame->args;
- MVMint32 spesh_cand = GET_UI16(cur_op, 2);
+ MVMSpeshCandidate *spesh_cand = (MVMSpeshCandidate *)tc->cur_frame->effective_spesh_slots[GET_UI16(cur_op, 2)];
tc->cur_frame->return_value = NULL;
tc->cur_frame->return_type = MVM_RETURN_VOID;
cur_op += 4;
@@ -5960,7 +5960,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(sp_fastinvoke_i): {
MVMCode *code = (MVMCode *)GET_REG(cur_op, 2).o;
MVMRegister *args = tc->cur_frame->args;
- MVMint32 spesh_cand = GET_UI16(cur_op, 4);
+ MVMSpeshCandidate *spesh_cand = (MVMSpeshCandidate *)tc->cur_frame->effective_spesh_slots[GET_UI16(cur_op, 4)];
tc->cur_frame->return_value = &GET_REG(cur_op, 0);
tc->cur_frame->return_type = MVM_RETURN_INT;
cur_op += 6;
@@ -5972,7 +5972,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(sp_fastinvoke_n): {
MVMCode *code = (MVMCode *)GET_REG(cur_op, 2).o;
MVMRegister *args = tc->cur_frame->args;
- MVMint32 spesh_cand = GET_UI16(cur_op, 4);
+ MVMSpeshCandidate *spesh_cand = (MVMSpeshCandidate *)tc->cur_frame->effective_spesh_slots[GET_UI16(cur_op, 4)];
tc->cur_frame->return_value = &GET_REG(cur_op, 0);
tc->cur_frame->return_type = MVM_RETURN_NUM;
cur_op += 6;
@@ -5984,7 +5984,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(sp_fastinvoke_s): {
MVMCode *code = (MVMCode *)GET_REG(cur_op, 2).o;
MVMRegister *args = tc->cur_frame->args;
- MVMint32 spesh_cand = GET_UI16(cur_op, 4);
+ MVMSpeshCandidate *spesh_cand = (MVMSpeshCandidate *)tc->cur_frame->effective_spesh_slots[GET_UI16(cur_op, 4)];
tc->cur_frame->return_value = &GET_REG(cur_op, 0);
tc->cur_frame->return_type = MVM_RETURN_STR;
cur_op += 6;
@@ -5996,7 +5996,7 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
OP(sp_fastinvoke_o): {
MVMCode *code = (MVMCode *)GET_REG(cur_op, 2).o;
MVMRegister *args = tc->cur_frame->args;
- MVMint32 spesh_cand = GET_UI16(cur_op, 4);
+ MVMSpeshCandidate *spesh_cand = (MVMSpeshCandidate *)tc->cur_frame->effective_spesh_slots[GET_UI16(cur_op, 4)];
tc->cur_frame->return_value = &GET_REG(cur_op, 0);
tc->cur_frame->return_type = MVM_RETURN_OBJ;
cur_op += 6;
diff --git src/core/loadbytecode.c src/core/loadbytecode.c
index 42b3cee1f..afe8e06b7 100644
--- src/core/loadbytecode.c
+++ src/core/loadbytecode.c
@@ -18,7 +18,7 @@ static void run_comp_unit(MVMThreadContext *tc, MVMCompUnit *cu) {
/* Invoke the deserialization frame and return to the runloop. */
MVM_frame_invoke(tc, cu->body.deserialize_frame, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS),
- NULL, NULL, NULL, -1);
+ NULL, NULL, NULL, NULL);
}
else {
/* No deserialize frame, so do load frame instead. */
@@ -82,7 +82,7 @@ void MVM_load_bytecode_buffer_to_cu(MVMThreadContext *tc, MVMObject *buf, MVMReg
/* Invoke the deserialization frame and return to the runloop. */
MVM_frame_invoke(tc, cu->body.deserialize_frame, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS),
- NULL, NULL, NULL, -1);
+ NULL, NULL, NULL, NULL);
}
}
void MVM_load_bytecode(MVMThreadContext *tc, MVMString *filename) {
@@ -153,6 +153,6 @@ static void run_load(MVMThreadContext *tc, void *sr_data) {
/* Invoke the load frame and return to the runloop. */
MVM_frame_invoke(tc, cu->body.load_frame, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS),
- NULL, NULL, NULL, -1);
+ NULL, NULL, NULL, NULL);
}
}
diff --git src/gc/debug.h src/gc/debug.h
index e2ecd01b5..91d833abd 100644
--- src/gc/debug.h
+++ src/gc/debug.h
@@ -4,7 +4,7 @@
* 2 = Checks on every object register access (slow)
* 3 = Collects garbage on every allocation
*/
-#define MVM_GC_DEBUG 3
+#define MVM_GC_DEBUG 0
#if MVM_GC_DEBUG
#define MVM_ASSERT_NOT_FROMSPACE(tc, c) do { \
diff --git src/jit/x64/emit.dasc src/jit/x64/emit.dasc
index a26d40a78..70d674adc 100644
--- src/jit/x64/emit.dasc
+++ src/jit/x64/emit.dasc
@@ -3370,6 +3370,7 @@ void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitG
}
if (invoke->is_fast) {
+ fprintf(stderr, "in is_fast\n");
/* call MVM_frame_invoke_code */
| mov ARG1, TC;
| mov ARG2, WORK[invoke->code_register_or_name];
@@ -3377,6 +3378,7 @@ void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitG
| mov ARG4, invoke->spesh_cand_or_sf_slot;
| callp &MVM_frame_invoke_code;
} else if (invoke->is_resolve) {
+ fprintf(stderr, "in is_resolve\n");
/* call MVM_spesh_plugin_resolve_jit, which will trampoline out of
* the JIT-compiled code if need be */
| mov ARG1, TC;
diff --git src/moar.c src/moar.c
index 836852a95..69c2a28ca 100644
--- src/moar.c
+++ src/moar.c
@@ -470,7 +470,7 @@ static void setup_std_handles(MVMThreadContext *tc) {
* the initial invocation. */
static void toplevel_initial_invoke(MVMThreadContext *tc, void *data) {
/* Create initial frame, which sets up all of the interpreter state also. */
- MVM_frame_invoke(tc, (MVMStaticFrame *)data, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), NULL, NULL, NULL, -1);
+ MVM_frame_invoke(tc, (MVMStaticFrame *)data, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), NULL, NULL, NULL, NULL);
}
/* Run deserialization frame, if there is one. Disable specialization
diff --git src/spesh/optimize.c src/spesh/optimize.c
index dc623176a..121168a18 100644
--- src/spesh/optimize.c
+++ src/spesh/optimize.c
@@ -2111,16 +2111,17 @@ static void optimize_call(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb
else {
/* Can't inline, so just identify candidate. */
MVMSpeshOperand *new_operands = MVM_spesh_alloc(tc, g, 3 * sizeof(MVMSpeshOperand));
+ MVMuint16 spesh_cand_slot = MVM_spesh_add_spesh_slot_try_reuse(tc, g, (MVMCollectable *)cands_and_arg_guards->spesh_candidates[spesh_cand]);
if (ins->info->opcode == MVM_OP_invoke_v) {
new_operands[0] = ins->operands[0];
- new_operands[1].lit_i16 = spesh_cand;
+ new_operands[1].lit_i16 = spesh_cand_slot;
ins->operands = new_operands;
ins->info = MVM_op_get_op(MVM_OP_sp_fastinvoke_v);
}
else {
new_operands[0] = ins->operands[0];
new_operands[1] = ins->operands[1];
- new_operands[2].lit_i16 = spesh_cand;
+ new_operands[2].lit_i16 = spesh_cand_slot;
ins->operands = new_operands;
switch (ins->info->opcode) {
case MVM_OP_invoke_i:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment