Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active December 26, 2020 19:16
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/3cb47c16cea41183ab1d0268b5343269 to your computer and use it in GitHub Desktop.
Save MasterDuke17/3cb47c16cea41183ab1d0268b5343269 to your computer and use it in GitHub Desktop.
diff --git src/6model/reprs/MVMSpeshCandidate.c src/6model/reprs/MVMSpeshCandidate.c
index 370571401..c67bcae5b 100644
--- src/6model/reprs/MVMSpeshCandidate.c
+++ src/6model/reprs/MVMSpeshCandidate.c
@@ -364,3 +364,42 @@ void MVM_spesh_candidate_discard_existing(MVMThreadContext *tc, MVMStaticFrame *
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) {
+ MVMuint32 i, new_num = spesh->body.num_spesh_candidates - 1;
+
+ for (i = 0; i < spesh->body.num_spesh_candidates; i++) {
+ MVMSpeshCandidate *sc = spesh->body.spesh_candidates[i];
+ if (sc == cand) {
+ spesh->body.num_spesh_candidates--;
+ //fprintf(stderr, "found the matching candidate at index %u\n", i);
+ break;
+ }
+ }
+
+ MVMSpeshCandidate **new_cands;
+ if (new_num > 0) {
+ new_cands = MVM_fixed_size_alloc(tc, tc->instance->fsa, new_num * sizeof(MVMSpeshCandidate *));
+ if (i == 0) {
+ memcpy(new_cands, spesh->body.spesh_candidates + sizeof(MVMSpeshCandidate *), new_num * sizeof(MVMSpeshCandidate *));
+ }
+ else if (i == new_num) {
+ memcpy(new_cands, spesh->body.spesh_candidates, new_num * sizeof(MVMSpeshCandidate *));
+ }
+ else {
+ memcpy(new_cands, spesh->body.spesh_candidates, i * sizeof(MVMSpeshCandidate *));
+ memcpy(new_cands + i * sizeof(MVMSpeshCandidate *), spesh->body.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 *),
+ spesh->body.spesh_candidates);
+
+ spesh->body.spesh_candidates = new_num > 0 ? new_cands : NULL;
+
+ MVM_spesh_arg_guard_discard(tc, sf);
+ }
+}
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/core/frame.c src/core/frame.c
index 0a866d540..ddd1498b8 100644
--- src/core/frame.c
+++ src/core/frame.c
@@ -506,7 +506,7 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame,
}
}
#endif
- if (spesh_cand >= 0) {
+ if (spesh_cand >= 0 && spesh_cand < spesh->body.num_spesh_candidates) {
MVMSpeshCandidate *chosen_cand = spesh->body.spesh_candidates[spesh_cand];
if (static_frame->body.allocate_on_heap) {
MVMROOT4(tc, static_frame, code_ref, outer, chosen_cand, {
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
[dan@alexandria nqp]$ gdb --args '/home/dan/Source/perl6/install/bin/moar' --libpath=src/vm/moar/stage0 src/vm/moar/stage0/nqp.moarvm --bootstrap --setting-path=gen/moar/stage1 --module-path=gen/moar/stage1 --no-regex-lib --target=mbc --setting=NQPCORE --stable-sc=stage1 --output=gen/moar/stage1/MASTOps.moarvm /home/dan/Source/perl6/install/share/nqp/lib/MAST/Ops.nqp
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/dan/Source/perl6/install/bin/moar...
MoarVM string pretty printer registered
moar-heap registered
diff-moar-heap registered
(gdb) r
Starting program: /home/dan/Source/perl6/install/bin/moar --libpath=src/vm/moar/stage0 src/vm/moar/stage0/nqp.moarvm --bootstrap --setting-path=gen/moar/stage1 --module-path=gen/moar/stage1 --no-regex-lib --target=mbc --setting=NQPCORE --stable-sc=stage1 --output=gen/moar/stage1/MASTOps.moarvm /home/dan/Source/perl6/install/share/nqp/lib/MAST/Ops.nqp
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff6d56640 (LWP 3733557)]
Thread 2 "spesh optimizer" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6d56640 (LWP 3733557)]
max_typed_nodes (cs=0x555555644970, types=0x200000001) at src/spesh/arg_guard.c:37
37 if (types[i].type)
(gdb) bt
#0 max_typed_nodes (cs=0x555555644970, types=0x200000001) at src/spesh/arg_guard.c:37
#1 0x00007ffff790bbd7 in MVM_spesh_arg_guard_regenerate (tc=0x5555555f5750, guard_ptr=0x555555c4ca00, candidates=0x7ffff013c540, num_spesh_candidates=2) at src/spesh/arg_guard.c:361
#2 0x00007ffff7915e2d in MVM_spesh_candidate_add (tc=0x5555555f5750, p=0x7ffff003eae0) at src/6model/reprs/MVMSpeshCandidate.c:336
#3 0x00007ffff7904a9b in worker (tc=0x5555555f5750, callsite=0x7ffff7f64800 <null_args_callsite>, args=0x0) at src/spesh/worker.c:24
#4 0x00007ffff788b787 in invoke_handler (tc=0x5555555f5750, invokee=0x5555555c5700, callsite=0x7ffff7f64800 <null_args_callsite>, args=0x0) at src/6model/reprs/MVMCFunction.c:9
#5 0x00007ffff782ffb6 in thread_initial_invoke (tc=0x5555555f5750, data=0x5555555f6ae0) at src/core/threads.c:58
#6 0x00007ffff77e699f in MVM_interp_run (tc=0x5555555f5750, initial_invoke=0x7ffff782ff2b <thread_initial_invoke>, invoke_data=0x5555555f6ae0, outer_runloop=0x0) at src/core/interp.c:159
#7 0x00007ffff7830083 in start_thread (data=0x5555555f6ae0) at src/core/threads.c:91
#8 0x00007ffff726a3e9 in start_thread () from /usr/lib/libpthread.so.0
#9 0x00007ffff74c9293 in clone () from /usr/lib/libc.so.6
[dan@alexandria nqp]$ valgrind '/home/dan/Source/perl6/install/bin/moar' --libpath=src/vm/moar/stage0 src/vm/moar/stage0/nqp.moarvm --bootstrap --setting-path=gen/moar/stage1 --module-path=gen/moar/stage1 --no-regex-lib --target=mbc --setting=NQPCORE --stable-sc=stage1 --output=gen/moar/stage1/MASTOps.moarvm /home/dan/Source/perl6/install/share/nqp/lib/MAST/Ops.nqp
==3759415== Memcheck, a memory error detector
==3759415== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3759415== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==3759415== Command: /home/dan/Source/perl6/install/bin/moar --libpath=src/vm/moar/stage0 src/vm/moar/stage0/nqp.moarvm --bootstrap --setting-path=gen/moar/stage1 --module-path=gen/moar/stage1 --no-regex-lib --target=mbc --setting=NQPCORE --stable-sc=stage1 --output=gen/moar/stage1/MASTOps.moarvm /home/dan/Source/perl6/install/share/nqp/lib/MAST/Ops.nqp
==3759415==
==3759415== Thread 2 spesh optimizer:
==3759415== Conditional jump or move depends on uninitialised value(s)
==3759415== at 0x4B70752: MVM_spesh_arg_guard_regenerate (arg_guard.c:333)
==3759415== by 0x4B7AE2C: MVM_spesh_candidate_add (MVMSpeshCandidate.c:336)
==3759415== by 0x4B69A9A: worker (worker.c:24)
==3759415== by 0x4AF0786: invoke_handler (MVMCFunction.c:9)
==3759415== by 0x4A94FB5: thread_initial_invoke (threads.c:58)
==3759415== by 0x4A4B99E: MVM_interp_run (interp.c:159)
==3759415== by 0x4A95082: start_thread (threads.c:91)
==3759415== by 0x55963E8: start_thread (in /usr/lib/libpthread-2.32.so)
==3759415== by 0x537E292: clone (in /usr/lib/libc-2.32.so)
==3759415==
==3759415==
==3759415== HEAP SUMMARY:
==3759415== in use at exit: 175,966,216 bytes in 256,075 blocks
==3759415== total heap usage: 3,585,319 allocs, 3,329,244 frees, 1,584,787,991 bytes allocated
==3759415==
==3759415== LEAK SUMMARY:
==3759415== definitely lost: 0 bytes in 0 blocks
==3759415== indirectly lost: 0 bytes in 0 blocks
==3759415== possibly lost: 1,488,536 bytes in 344 blocks
==3759415== still reachable: 174,477,680 bytes in 255,731 blocks
==3759415== suppressed: 0 bytes in 0 blocks
==3759415== Rerun with --leak-check=full to see details of leaked memory
==3759415==
==3759415== Use --track-origins=yes to see where uninitialised values come from
==3759415== For lists of detected and suppressed errors, rerun with: -s
==3759415== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment