github.com/moarvm/moarvm | IRC logs at colabti.org/irclogger/irclogger_logs/moarvm Set by AlexDaniel on 12 June 2018. |
|||
07:58
cog joined
08:02
cog__ left
|
|||
Geth | MoarVM/hash-delete-corner-case: b8663f53ae | (Nicholas Clark)++ | 2 files Fix a potential bug when all elements are individually deleted from a hash. Two optimisations were coming together in an unforeseen way, which could cause an assertion failure on a debugging build. There's a space optimisation for empty hashes which only allocates the control structure, and flags this with both `cur_items` and `max_items` ... (28 more lines) |
08:59 | |
09:15
Altai-man joined
|
|||
nwc10 | and *this* time the flappy tests pass | 09:36 | |
Geth | MoarVM: b8663f53ae | (Nicholas Clark)++ | 2 files Fix a potential bug when all elements are individually deleted from a hash. Two optimisations were coming together in an unforeseen way, which could cause an assertion failure on a debugging build. There's a space optimisation for empty hashes which only allocates the control structure, and flags this with both `cur_items` and `max_items` ... (28 more lines) |
09:37 | |
nwc10 | oh wait, er, good *, #moarvm | 09:38 | |
and once more ENOCOFFEE | |||
11:57
sena_kun joined
11:58
Altai-man left
|
|||
timotimo | oh hash yeah | 12:06 | |
15:56
Altai-man joined
15:58
sena_kun left
15:59
domidumont left,
domidumont joined
17:14
zakharyas joined
18:23
domidumont left
|
|||
MasterDuke | hm. i'm getting segvs about cand->body.jitcode. for some ridiculous reason 0x18020100000001 isn't considered accessible. in 2020, can you believe it? | 19:51 | |
timotimo | yeah, accessibility concerns have been on my mind lately | 19:54 | |
MasterDuke | so i've created a new `spesh->body.spesh_candidates` my memcpying the relevant parts of the previous one. the candidate i'm getting rid of i've set its body.discarded to 1, i've freed the old spesh_candidates, decremented `spesh->body.num_spesh_candidates`, and called MVM_spesh_arg_guard_regenerate | 19:55 | |
what else do i need to do? | |||
19:57
sena_kun joined
19:59
Altai-man left
|
|||
timotimo | phew | 19:59 | |
sorry, not sure | |||
the 0x....001 thing is probably bogus, yeah? | |||
MasterDuke | yeah, the cand it's from is bogus also | 20:00 | |
(gdb) p *spesh_cand$1 = {common = {header = {sc_forward_u = {forwarder = 0xffffffff00000004, sc = {sc_idx = 4, idx = 4294967295}, st = 0xffffffff00000004}, owner = 1, flags1 = 1 '\001', flags2 = 2 '\002', size = 24}, st = 0x5555555b5470}, body = { cs = 0xffffffff00000004, type_tuple = 0x18020100000001, discarded = 56 '8', bytecode_size = 21845, | |||
bytecode = 0xffffffff00000004 <error: Cannot access memory at address 0xffffffff00000004>, handlers = 0x18020100000001, spesh_slots = 0x5555555b5600, num_spesh_slots = 4, num_deopts = 4294967295, deopts = 0x18020100000001, deopt_count = 1432049352, deopt_named_used_bit_field = 18446744069414584324, deopt_pea = {materialize_info = | |||
0x18020100000001, materialize_info_num = 93824992630672, materialize_info_alloc = 18446744069414584324, deopt_point = 0x18020100000001, deopt_point_num = 93824992630872, deopt_point_alloc = 18446744069414584324}, num_inlines = 1, inlines = 0x5555555b59e8, local_types = 0xffffffff00000005, lexical_types = 0x18020100000001, num_locals = | |||
23216, num_lexicals = 21851, work_size = 21845, env_size = 5, num_handlers = 4294967295, jitcode = 0x18020100000001, deopt_usage_info = 0x5555555b5b78}} | |||
20:38
leont joined
|
|||
MasterDuke | doesn't seem to happen under valgrind. is there some sort of locking/etc i should be doing? | 20:57 | |
timotimo | hm, i think there might be a lock for spesh candidate handling actually? | 20:58 | |
nah, too performance-critical, must be a free-at-safepoint kind of thing | 20:59 | ||
which i believe i actually saw in the code | |||
jnthn | Spesh candidate is a delicate dance that even has a memory barrier in there for good measure | 21:01 | |
It gets everything set up in the candidate list and only then installs it into the spesh arg guard data structure | 21:02 | ||
MasterDuke | jnthn: up for seeing the current diff? | ||
jnthn | There's no lock needed for installing new candidates because only one thread ever does it (and that'd be true for removing too), however everything you do is in a race with all the other threads which want to look up spesh candidates | ||
Well, what you described above sounds problematic | 21:03 | ||
Because there's a period when the spesh arg guard still references a candidate that is gone | |||
MasterDuke | yep, i believe so | 21:04 | |
jnthn | I suspect the current design also draws on us only ever *adding* candidates | 21:05 | |
MasterDuke | assuming removing is infrequent, add a lock only for removing? | ||
jnthn | That won't help. Remove themselves aren't racing. Rather, changes are (by design) racing with the threads that want to read candidates, and we can't really afford a lock there | 21:06 | |
MasterDuke | ah, right | 21:07 | |
jnthn | iiuc, currently we have 1) the arg guards, 2) an array of pointers to MVMSpeshCand objects, which are the ones you made GC-able? | 21:08 | |
Assuming that, there's two approaches I can think of | 21:09 | ||
MasterDuke | yep | ||
timotimo | we could have the array have holes in it | ||
then at least old guard structures don't get outdated | |||
jnthn | 1) The boring one: add a level of indirection. Have a piece of memory that has pointers to current candidates and current guard tree. Only ever read that pointer once in any code path, and then use the consistent guard tree/candidate set pairing. | 21:10 | |
Then the usual update the point, and free at safepoint. | 21:11 | ||
I think this is probably bulletproof. | |||
MasterDuke | bulletproof is good | 21:12 | |
jnthn | 2) Try and retain something closer to the current approach to avoid the LoI, but don't renumber. Giving a "hole" that we can reuse later (after a safepoint, at least). I think the bookkeeping is scary. | ||
So I'd do 1 | |||
It's an iota more memory churn, and there's the LoI, but I think that's a drop in the water and perhaps optimizable later respectively (e.g. finding a way to allocate one blob of memory for candidates and guard tree) | 21:13 | ||
*drop in the ocean | 21:14 | ||
MasterDuke | so instead of MVMStaticFrameSpesh having a body.spesh_candidates, give it instead a body.spesh_candidates_and_their_associated_arg_guards_tree ? where spesh_candidates_and_their_associated_arg_guards_tree is something like `struct { MVMSpeshArgGuard *spesh_arg_guard; MVMSpeshCandidate **spesh_candidates; MVMuint32 num_spesh_candidates; }` | 21:18 | |
(extracted out from MVMStaticFrameSpeshBody) | |||
jnthn | Yes; to be clear, spesh_candidates_and_their_associated_arg_guards_tree must be a pointer to that struct, not just an inline struct | ||
MasterDuke | yeah | 21:19 | |
jnthn | (that's the magic LoI that we derive the safety from) | ||
MasterDuke | every problem in computer science can be solved by adding a layer of indirection | ||
jnthn | I don't know where num_spesh_candidates best goes; you don't need it for resolution iirc | ||
Except too many levels of indirection! | |||
.oO( That's the one you solve with caching... ) |
21:20 | ||
MasterDuke | too bad layers of indirection don't wrap around eventually... | ||
guess i'll start with leaving num_spesh_candidates where it is, fewer things to change | 21:21 | ||
21:22
sena_kun left
|
|||
jnthn | Yeah, if you don't have to move it, don't. | 21:22 | |
21:43
zakharyas left
|
|||
MasterDuke | jnthn:btw, nice advent post | 22:00 | |
23:18
rypervenche left
23:41
rypervenche joined
|
|||
jnthn | MasterDuke: Thanks :) | 23:42 | |
23:48
leont left
|