00:23
tgt joined
00:41
cognominal joined
00:48
tgt joined
01:32
jnap joined
01:48
tgt joined
02:03
jnap joined
02:21
FROGGS_ joined
02:31
benabik joined
02:49
tgt joined
03:06
krunen joined
03:50
tgt joined
04:15
dagurval joined
04:51
tgt joined
05:51
tgt joined
07:22
camelia joined
07:33
camelia joined
07:37
FROGGS joined
08:02
tgt joined
08:26
odc joined
|
|||
timotimo | could it be that storing a flag where a pointer used to be is a Very Bad Idea if you don't tell the GC about that quirk? | 09:23 | |
i'm looking at a segfault i'm getting and my first suspicion is that there's a smallbigint inlined into a P6opaque and the gc is being told "follow this pointer and clean up stuff there!" | 09:24 | ||
but i'm not sure | |||
i'd like to wait for jnthn or diakopter to give an opinion on that | 09:26 | ||
but maybe in the mean time i can just make P6bigint uninlinable | |||
"This type cannot box a native integer" :\ | 09:27 | ||
09:28
krunen joined
|
|||
timotimo | i think it *might* be a better idea to re-use the "sign" integer for a flag and alloc or used for the number data | 09:33 | |
and leave the pointer alone, or set it to 0? | |||
er, wait | 09:34 | ||
what am i saying. | |||
the pointer only gets the flag, not the data | |||
ah, "this type cannot box a native integer" was coming from not cleaning the serialized data | 09:49 | ||
somehow 0x4000000009 lands in whatever "data" is | 09:55 | ||
that is, a pointer to that address | |||
the offset is "8", so the original data value has got to be 0x4000...0001 | 09:56 | ||
which could conceivably be a too-wide reading of data followed by the flag | 09:57 | ||
i think get_boxed_ref returning (mp_int *)&(data->body.i) might be problematic for that reason? | 09:58 | ||
hm. maybe the data is just being serialized wrong? that could be a possibility | 10:03 | ||
hoelzro | parallel conversations! | 10:04 | |
timotimo | hm. the data remains at that curious value | 10:05 | |
i think i may very well be barking up the wrong tree. | |||
dalek | arVM/small_big_ints: dfd5e77 | (Timo Paulssen)++ | src/ (3 files): trying more things to make this work. segfaults. |
||
timotimo | maybe someone else can step in? | ||
10:23
ggoebel1113 joined
|
|||
jnthn | timotimo: What does the P6bigintBody structure look like now? | 11:15 | |
timotimo: uh...I didn't want you to inline mp_int... | 11:29 | ||
That wsa meant to stay as mp_int * | |||
So that Int doesn't get any bigger memory wise than it is today on 64-bit... | 11:30 | ||
So the small bigint body is just a 32-bit flag set to 0xFFFFFFFF and then the 32-bit int storage. | |||
teaching & | |||
timotimo | oh, but wasnt mp_int always inlined | 12:55 | |
timotimo reviews his patches | 12:58 | ||
jnthn: github.com/MoarVM/MoarVM/compare/s...91aeebaR17 | 12:59 | ||
moritz patches his reviews | 13:01 | ||
13:25
krunen joined
|
|||
timotimo | ah, i think one of the mistakes that lead to my stuff not working at all is that i don't create bigints to store the results of ops into at all. | 13:44 | |
so i'll have to rethink the way i allocate p6bigint or the way i handle the result objects | 13:45 | ||
diakopter | timotimo: but.. | 14:02 | |
timotimo: but the union doesn't save any storage | 14:03 | ||
timotimo: what's the goal of the branch | 14:12 | ||
timotimo | it does not? | ||
why not? | |||
diakopter | I retract that assertion until I understand what you aim to do | 14:15 | |
mp_int is 3 ints and a pointer | |||
timotimo | i am supposed to store the flag in the lowest bits of the pointer | 14:16 | |
and a 32 bit value somewhere in there | 14:17 | ||
diakopter | so just do that with the mp_int directly | ||
timotimo | it was very hard to write a literal 1 into the pointer. | 14:19 | |
diakopter | why.. *(ptr) = 1 works | 14:21 | |
timotimo | if you can tell me exactly how to treat mp_digit *dp as if it were a number i can change | ||
i'm pretty sure that would write a 1 to where the pointer points | |||
diakopter | er, right. | ||
timotimo | you see my problem now? :)) | ||
diakopter | *kickself* | ||
tadzik | what about ptr = 1? :P | ||
diakopter | yes, what I meant | ||
timotimo | tadzik: i have no idea. | ||
tadzik | that should work alright | ||
diakopter | yes, ptr = 1 is fine | ||
timotimo | if that's all i have to do, then i can make my code a bit simpler, aye. | 14:22 | |
tadzik | I can't imagine a platform where 1 is outside the address space :P | ||
diakopter | but since jnthn thought that mp_int was a pointer and not already inlined | ||
then your "I was supposed to" understand is probably invalid | |||
*understanding | 14:23 | ||
when did jnthn say that's what you were supposed to do | 14:24 | ||
dalek | arVM/little_big_int: ce20922 | (Timo Paulssen)++ | src/ (7 files): get rid of unhelpful union, s/small/little/ |
14:26 | |
timotimo | uh | ||
not sure? | |||
tadzik | haha, that's like a civil war outcome | 14:27 | |
get rid of unhelpful union | |||
timotimo | the way it is now will still save storage and cpu time, because we don't have the indirect pointer and malloc/free workload | ||
at least if we are dealing with little big ints only | |||
if we have mixtures, we won't get around that after all. | |||
14:28
jnap joined
|
|||
dalek | arVM/little_big_int: 6d10d0a | (Timo Paulssen)++ | build/Makefile.in: one more small->little rename i missed. |
14:30 | |
timotimo | that branch will get a cleanup before it gets merged to get rid of the back&forth | 14:31 | |
hoelzro | timotimo++ # rename to LBI | ||
moritz | if it's small enough, you can merge it with --squash to create a single commit | 14:32 | |
timotimo | it'll be a bit bigger than that | 14:34 | |
i'll make sensible commits that individually not-break the build hopefully | |||
diakopter | if (0 && ( | 14:38 | |
timotimo | yeah, that'd not break the build :) | 14:39 | |
diakopter | ? | 14:40 | |
timotimo | if it's turned off, it wouldn't break the build | 14:41 | |
diakopter | I know what you meant, I was saying it's turned off | 14:42 | |
also the branch mentions MVMP6littlebigintBody | |||
timotimo | yes, i'm fixing as we speak | ||
i'm not immediately pushing my stuff | |||
i'm a bit distracted at the moment, so i'm not working at full speed | |||
interestingly i'm getting a few outputs of "get_int on a SBI" where that really shouldn't happen since i don't build any SBIs at the moment | 14:46 | ||
ah, of course | 14:47 | ||
i'm thinking of starting from scratch now %) | 14:51 | ||
i wonder how i got to "'0' is not a valid number" | 14:53 | ||
14:55
benabik joined
|
|||
diakopter | if (!IS_SBI(src)) | 14:56 | |
why is that in copy_to | |||
timotimo | i just looked at that, too | 14:57 | |
it's not executed yet when i hit that point | |||
it's because i thought it was only for copying the dp | |||
when in fact it's supposed to copy all of the struct as well as the dp | |||
i'm pretty sure i have a much improved clarity of the whole situation now | 14:59 | ||
thank you, diakopter :) | |||
diakopter | what's the purpose of CLEANUP_* | ||
jnthn | timotimo: um, I didn't realize we didn't store mp_int*... | ||
I guess we can leave it as mp_int | 15:00 | ||
Though we may find that *most* programs are much more memory efficient with it being mp_int *, since most integers will be small. | |||
Sorry for the confusion. | |||
timotimo | i can do that, too, if you'd like | 15:01 | |
diakopter | that would also add an additional malloc per big bigint, of course | ||
(which may be worth it, of course) | |||
timotimo | say, jnthn, how do you feel about this idea: | ||
when we create a p6bigint, we wr^H^Hcreate the data for dp directly after the structure if we already know the size | |||
that way it can be prefetched without indirection until it has to be realloc'd | 15:02 | ||
(in which case it will explode in our faces, because that pointer doesn't have a malloc header in front of its data | |||
but mayhaps we could handle that somehow if it's more efficient that way?) | |||
jnthn | diakopter: I think it would be worth it because people doing stuff with bigints will be the exception, not the norm... | ||
timotimo | i have to get off this train in a minute | ||
jnthn | timotimo: I don't think we easily can do that, REPRs are meant to have a fixed size for a given type. | 15:03 | |
And it'd make Int even bigger. | |||
diakopter | jnthn: I don't know. :) a *lot* of crypto code uses bigints | ||
jnthn | Well, actually not really... | ||
diakopter | and a lot of code is becoming crypto code | ||
jnthn | diakopter: Yes, that's (a) not typical, and (b) you shoudln't implement your own crypto in 99.99999% of cases :) | ||
diakopter: I suspect a bunch of it will be delegated to well-trusted libraries. | 15:04 | ||
diakopter | (a) what's not typical | ||
jnthn | diakopter: Writing crypto code is not typical. | ||
diakopter | I had just said the contrary | ||
jnthn | I'm saying I don't agree wiht you. | 15:05 | |
benabik | Rule #1 of writing crypto code: Don't. Rule #2: See rule #1 | ||
diakopter | why would using p6bigint mean you are "implementing your own crypto" | 15:06 | |
why wouldn't the well-trusted libraries use it | |||
benabik | Generally they want speed. Variable sized and dynamically allocated integers is not really a good idea there. | ||
jnthn | Because the well-trusted libraries largely already exist and they're probably written in native code. | ||
diakopter: Oh, did you mean code using bigints is becoming mroe common? | 15:07 | ||
diakopter | benabik: wut. how do you use multiple/arbitrary precision integers without dynamically allocated | ||
and variable sized | |||
jnthn should go to the airport... | 15:08 | ||
bbl | |||
benabik | Cryptography is usually on fixed sized integers? | ||
diakopter | no | ||
never | |||
moritz | depends, really | 15:09 | |
diakopter | every crypto library I've seen uses very large integers | ||
moritz | lots of symmetric cryptography uses fixed-sized buffers or ints | ||
asymmetric crypto usually uses variable-sized integers | 15:10 | ||
diakopter | ok | ||
moritz | in fact, libtommath is used as the base for libtomcrypt | ||
diakopter | .. which uses large integers | 15:11 | |
moritz | aye | ||
it does asymmetric crypto too :-) | |||
diakopter | it also provides its own pooling/custom allocator as an option (libtommath) | 15:13 | |
for its *dp allocation | 15:14 | ||
but we're not using it | |||
libgcrypt uses a fork of GNU MP Library, but the JS version from emscripten uses fast_mpi.js | 15:19 | ||
openssl uses libcrypto's BIGNUM | 15:26 | ||
timotimo: just make copy_to do a set_int(get_int( since those will already have the checks you need | 15:28 | ||
benabik: ok, it was my understanding most cryptography was asymmetric; maybe that's wrong | 15:31 | ||
benabik | Asymmetric encryption tends to be just long enough to negotiate a shared key for symmetric encryption. :-D | ||
Symmetric is MUCH faster. | |||
diakopter | oh | 15:32 | |
masak | right. the reason to use asymmetric is to share the key safely for the symmetric, I guess. | ||
a bit like a secure courier showing up with the encryption key in a sealed envelope, and then you downgrade to the fast mechanism. | 15:33 | ||
benabik | Right. SSL and SSH both work that way. I think PGP might be pure asymmetric by default, but I haven't actually looked. | ||
timotimo | in case the program is getting a big hit from little_big_int overhead, we could have a counter that short-circuits any LBI stuff | 15:34 | |
hm. | 15:42 | ||
although it'd not work to replace mp_int *i with mp_int i at run time, except if we transform REPRs | 15:43 | ||
jnthn: so ... should i try transforming P6bigintbody to have an mp_int* in it? | 15:54 | ||
i think the amount of big integers you can even come up with at all will vastly be drowned out by all the Ints that rakudo constructs around you | |||
except you can still use int if you know you only need 64 bits | |||
16:32
FROGGS joined
16:35
jnap joined
|
|||
diakopter | timotimo: I think you should do what jnthn was suggesting (transforming P6bigintbody to have an mp_int* in it) | 16:37 | |
then on 32-bit platforms, make the body a union { struct { a 32-bit int (for the fast/small int value) and a 32-bit int to store the flag of whether to use the pointer }, and dp * | 16:39 | ||
but then on 64-bit, simply use dp * only | 16:40 | ||
er | |||
actually duh. use the union I said on both... | |||
(that's what I dreamt it up..) | 16:41 | ||
er sorry, argh | |||
I don't mean dp*, I meant mp_int* | |||
timotimo | :) | ||
diakopter | anyway yes, it should work out correctly on both 32 and 64 | ||
if you use that union | |||
no matter how the compiler lays out the union or struct | 16:42 | ||
timotimo | thank you :) | ||
diakopter | do you agree? | ||
timotimo | i didn't think much about it, but it seemed right | 16:43 | |
diakopter | [that that's a good application of what jnthn was suggesting?] | ||
timotimo | the thing i find annoying is i have to make a new struct for the two 32 bit integers to plug in there | ||
otherwise the union won't fly | |||
i could "just cast" it instead, but ... >_> | |||
diakopter | it's safer,ish, to use the union | ||
ish | |||
ish ish | 16:44 | ||
timotimo | but then i have to make like 10 structs and add lots of names everywhere | 17:03 | |
diakopter | er wut | ||
timotimo | because one of the platforms we target doesn't support anonymous structs | ||
diakopter | it doesn't need to be anonymous | ||
timotimo | yeah, but then i have to put lots of stuff into the access code :) | 17:04 | |
diakopter | why do you need 10 structs | 17:25 | |
what's wrong with the 1 I mentioned | 17:26 | ||
tadzik | which platform we target doesn't support anon structs? | 17:27 | |
I thought moarvm has those already | |||
I seem to have seen them here and there | |||
timotimo | someone told me it wouldn't fly | 17:29 | |
diakopter | I've used them in moar | ||
timotimo | 15:11 < JimmyZ> timotimo: union needs a name, solaris doesn't support anonymous union | 17:30 | |
diakopter | yeah, sure enough, andy has been sending in patches to get rid of anon unions | 17:32 | |
but those are anonymous unions, not structs | |||
besides, it's supported them for years, just gives warnings | 17:33 | ||
sun studio that is | 17:35 | ||
timotimo | oh, huh | 17:40 | |
17:47
FROGGS joined
|
|||
[Coke] | moar is passing one more test today. | 18:07 | |
tadzik | 1 moar test | ||
[Coke] | warnings free is nice. | ||
18:19
tgt joined
|
|||
benabik | One of these days I'm going to remove the const/signed mismatch warnings I keep getting. | 18:46 | |
FROGGS | jnthn: I've got a deal for you... I implement openpipe when you fix that STable bug :o) | 18:59 | |
benabik | ... Stable bug? That sounds ominous. | 19:00 | |
FROGGS | STable, that it not a typo :o) | 19:01 | |
benabik | No less ominous, given how central STables are. | 19:02 | |
19:07
raiph joined
|
|||
diakopter | what was the stable bug | 19:09 | |
raiph | I've built a rakudo/moarvm. what's the incantation to spectest nqp/moarvm? | 19:11 | |
timotimo | TEST_JOBS=n make m-spectest | 19:12 | |
[Coke] | you can't spectest nqp. | 19:13 | |
timotimo | well, you spectest it indirectly :) | 19:14 | |
FROGGS | diakopter: I can't even explain | 19:20 | |
diakopter: I just know it happens in v5, when you load a module like Config that depends on Perl5::Terms (which is like v5's setting) | 19:21 | ||
diakopter: and this exception is thrown in that case: github.com/MoarVM/MoarVM/blob/mast...on.c#L2044 | 19:25 | ||
raiph | [Coke], timotimo: s/spectest/run nqp's own tests against/ | 19:26 | |
diakopter | apporpriate | ||
reposession | |||
FROGGS | raiph: make m-test | ||
[Coke] | if moar is the only one you built, I'd expect make test to work, but I could be mistaken. | 19:27 | |
FROGGS | it will work, yes | ||
if you built the others too, it will run the test for every backend in order | 19:28 | ||
exactly like there is a make install and a make m-install | 19:29 | ||
diakopter: besides NYI'd openpipe() this bug hinders me running v5 on moar :o( | 19:33 | ||
diakopter: would be nice to spectest in about 8 minutes instead of 35 | |||
hoelzro | FROGGS: I'm working on openpipe() right now! | 19:34 | |
FROGGS | uhh!! | ||
hoelzro | speaking of which...I'm guessing that #ifdef _WIN32 #error "openpipe is NYI on Windows" wouldn't be very nice, right? | ||
what would be the preferred course of action? | |||
FROGGS | hoelzro: damn it, now how should I convince jnthn to hack for me? :o) | ||
hoelzro | (no one else is working on it, are they?) | 19:35 | |
FROGGS: get him to make sure it works on Windows? =P | |||
FROGGS | hoelzro: I can make it work on windows then... | ||
hoelzro: if you can implement it on linux, that this is awesome on its own | |||
hoelzro | ok | ||
benabik | hoelzro: #error << throw_adhoc < working | ||
hoelzro | yeah, I came across it when vetting Perl 6 modules on Mokudo | 19:36 | |
I guess I can throw in a throw_adhoc | |||
benabik | Not allowing Moar to build on a platform just because one thing is NYI is LTA. | 19:37 | |
hoelzro | that's why I ask =) | ||
should I create a new .c file for pipe stuff? or shoehorn it into fileops? | 19:41 | ||
FROGGS | what about procops.? | 19:42 | |
procops.c* | 19:43 | ||
PerlJam | hoelzro: a new pipe.c file with references to magritte "Ceci n'est pas une pipe" :-) | ||
FROGGS | *g* | ||
hoelzro | heh | 19:44 | |
hmm...if I close() a pipe, should that just close my side of the pipe? | 20:13 | ||
because the child will get a SIGPIPE, won't it? | |||
20:15
tgt joined
|
|||
hoelzro | MoarVM has a uv loop per thread, right? | 20:30 | |
I take it to mean that if I create a handle on one thread, it can only ever be picked up by the corresponding thread? | 20:31 | ||
diakopter | eh | 20:36 | |
not yet | |||
but actually I thought uv loops sat on top of another thread system in libuv, so you can have handle sharing across loops... or is that wrong? | |||
hoelzro | heh, I have no idea =/ | 20:37 | |
this is my first exposure to libuv | |||
=) | |||
MVM_repr_alloc_init actually allocates data, right? | |||
diakopter | i think jnthn said he wanted to do the io stuff | 20:38 | |
hoelzro | and you have to free() it yourself? | ||
diakopter: should I leave openpipe to him? | |||
diakopter | because he has some designs/plans in mind he hasn't communicated [because it would be faster to implement them than write them out, I'm sure] | ||
hoelzro | damn | 20:39 | |
diakopter | well I just mean don't feel bad if he redoes all that :) but please explore and learn and try | ||
it's pretty complex | |||
hoelzro | alright | ||
good to know =) | |||
diakopter | I spent a lot of time thinking/talking with him about it last summer? spring? | 20:40 | |
jnthn | hoelzro: I'm fine with you putting in openpipe | 20:51 | |
I *will* be shuffling IO stuff around a bunch, but I'll be doing it step by step rather than throwing everything out. | 20:52 | ||
hoelzro | ok | 21:13 | |
very good =) | |||
is nqp::closefh($pipe) not supposed to throw an exception the second time? | 21:41 | ||
hoelzro is looking at the JVM pipes test | |||
nwc10 | jnthn: is the MVMSTable written to disk as is? I assume not | 21:44 | |
basically, I have sizeof(MSMStable) down by 8 | |||
but it seems that something wrote out REPR_data etc at the old offsets | |||
jnthn | nwc10: No, it's not written out directly... | 21:45 | |
nwc10: I think the thing responsible is called serialize_stable | |||
nwc10 | OK, there has to be a structure initialiser somewhere... | 21:48 | |
jnthn | They're typiccally allocated by the stable allocation function in srf/gc/allocate.t | ||
uh | |||
src/gc/allocate.c | |||
nwc10 | that's not what i'm trying to describe. | 21:52 | |
nwc10 flails harder | |||
I see things like MVM_REPR_DEFAULT_ATTR_FUNCS in reprs.h | |||
which looks like text that gets stiched together to be inside {...} to be used a struct initialiser | |||
hoelzro | alright, openpipe work is here: github.com/hoelzro/MoarVM | 21:53 | |
it's not done yet, but it's a good start =) | |||
nwc10 | so I think I'm looking for a struct initialiser for an stable | 21:55 | |
jnthn | Ooh, Moar stage parse crept under 40s for the first time ever on my box | 21:57 | |
With the nwc10++ GC patch | 21:58 | ||
nwc10 | yay | ||
jnthn | nwc10: OK, I didn't think we had any STables statically initialized, if that's what you mean | ||
nwc10: Can you describe the symptoms a little more? | |||
nwc10 | with a bit of pasting | 21:59 | |
correct working STable looks like this: | |||
(gdb) p *((MVMObject *)c)->st$5 = {header = {owner = 4154457015, flags = 32767, size = 0, forwarder = 0x7ffff79ffba2 <allocate>, sc_forward_u = {sc = 0x0, st = 0x0}}, REPR = 0x7ffff79ffb90 <copy_to>, REPR_data = 0x7ffff79f4884 <MVM_REPR_DEFAULT_GET_ATTRIBUTE>, | |||
gah. | |||
tmux goes om nom nom :-( | |||
jnthn | That...REPR and REPR_data seem to be poitning to odd places | 22:01 | |
nwc10 | hangon | ||
this is working: | |||
paste.scsys.co.uk/296447 | |||
however ugly and wrong that looks, it is from working MoarVM | 22:02 | ||
better paste paste.scsys.co.uk/296448 | 22:03 | ||
jnthn | And first sub-300s spectest (299s) for me too :) | ||
dalek | arVM: 4c8452a | nicholas++ | src/gc/collect.c: process_worklist() only needs to enforce the GC invariant if the object moved. The comment notes "In moving an object to generation 2"... but the code had been doing the work for *all* objects in generation 2, not just those moved there. We know whether we have just moved an object from the nursery to gen2, so track that, and only walk the recently marked items for a newly moved object. |
22:04 | |
jnthn | $5 = {header = {owner = 4154457015, flags = 32767, size = 0, | 22:05 | |
All of those fields are bogus. The owner should be 0 or maybe 1, but certainly that size of a number. And size should not be 0 | |||
nwc10 | and not working paste.scsys.co.uk/296450 | ||
OK | |||
interesting | |||
jnthn | Oh, you know waht this looks like? | ||
Like something has confused st and a REPR | 22:06 | ||
nwc10 | please tell :-) | ||
OK, this is on a somewhat variant branch | |||
jnthn | st = 0x7ffff7dd4be0 <this_repr> | 22:07 | |
That st point is pointing to a REPR table | |||
One of the static things in a src/6model/reprs/ | |||
*pointer | |||
nwc10 | ah OK | ||
that would explain a bit. And we got away with it due to chance | 22:08 | ||
(assuming it's not stupid I added) | |||
jnthn | p *(MVMStable *)c | ||
timotimo | hey jnthn :) | ||
nwc10 | c is 0 | ||
jnthn | nwc10: Youv'e cast c to MVMObject * | 22:09 | |
timotimo | jnthn: should i go ahead with the mp_int * change? that is, un-inlining mp_int from P6bigintbody | ||
jnthn | nwc10: But the flags indicate it's an MVMStable * | ||
nwc10 | oh, I must be somewhere else | ||
jnthn | flags = 10 | ||
I'm at the very top of what you pasted | |||
10 = MVM_CF_STABLE = 2 + MVM_CF_SECOND_GEN = 8 | |||
timotimo: I'm fine with that. | 22:10 | ||
timotimo | sounds good | ||
but not right now. | |||
jnthn | timotimo: It'll make the majority of programs memory-lighter. | ||
timotimo | do we have any way of using a different REPR if we detect a crapton of bigints being used? | ||
nwc10 | aha OK | 22:11 | |
jnthn | timotimo: Not at present | ||
nwc10 | jnthn: this is me trying to work out why I later have garbage in the gen2 roots | ||
so this particular one *is* me being stupid, I think | 22:12 | ||
jnthn | nwc10: Oh | ||
nwc10 | sorry to be a small waste of time | ||
jnthn | nwc10: Well, I know there's code that used to use the presence of a forwarder as a mark bit. | ||
nwc10: In order to compact the gen2 roots | |||
nwc10 | this is sort of X Y | ||
jnthn | nwc10: After a full collect. | ||
nwc10 | found that, that's patched locally | ||
jnthn | nwc10: No, you're not being a waste of time at all. You're saving a lot of memory ;) | ||
nwc10 | I haven't *yet* | ||
jnthn | timotimo: I'm not saying we have to follow this approach for all time, simply that I think it's the right way for now. | 22:13 | |
timotimo | right. will do. | 22:14 | |
is somebody already working on putting the forwarding pointer into the rest of the object? | |||
jnthn | timotimo: Additionally, once we get escape analysis in place, given we know about bigints and stuff at VM level, I'm hoping we can do stuff like, doing operations on mp_int without all the box/unbox | ||
timotimo | that would be lovely | ||
jnthn | timotimo: Yes, that's what nwc10++ is talking about/debugging righ tnow :) | ||
timotimo | ah, great! | ||
saves one int for every single object, that's 8 bytes, yes? | 22:15 | ||
do we have any heap/allocation/... statistics at the moment? | |||
jnthn | Correct. | ||
timotimo | i remember i wanted to build the gdb thing that can output statistics without having to put lots of conditional C in place | ||
it may be easiest to have a "startup script" that gdb sources that says "put this breakpoint in this function, step until you reach this line, collect these locals and continue | 22:16 | ||
that way, i wouldn't even have to walk worklists myself at all, i'd just observe what the GC does anyway | |||
okay, nwc10++ will be removing 8 bytes from all objects, i'll hopefully remove 24 bytes from almost every Int | 22:22 | ||
i'll be excited to see how big the "say 1" program running on rakudo-moar will be after we finish this particular piece of work | 22:24 | ||
nwc10 | jnthn: OK, the bug may be these 2 lines in MVM_gc_root_add_gen2s_to_worklist | ||
if (!num_in_nursery && REPR(gen2roots[i])->refs_frames) | 22:25 | ||
num_in_nursery = 1; | |||
specifically that use of the REPR() macro | |||
on a collectable, that turns out to be an STable | |||
*not* verified | |||
jnthn | Oh, ouch | ||
I can confirm with quite high confidence that that's wrong. | 22:26 | ||
nwc10 | shall I try locally fixing my REPR macro to assert that it's only used on Objects, not STables, and see what breaks? :-) | ||
actully, scrub that | |||
I am going to go to bed | |||
but if nothing has changed, I will try that sort of thing tomorrow | |||
jnthn | Yes, try that. But above isn't right. In fact, it's potentially a performance bug today | ||
nwc10 | anyway, that's why I've been asking questions about why my assertions with REPR() fail, when I shouldn't even be using REPR() on them | 22:27 | |
because I was trying to work out why that REPR() there ended up as a NULL pointer de-ref | |||
we have probably been getting away with it due to alignment chance between two different structures | 22:28 | ||
timotimo | a performance bug! \o/ | ||
jnthn | nwc10: aye, seems likely | 22:33 | |
To clarify why it may be a performance bug: if we find anything but NULL at that address, we'll have been considering refs_frames to be true. | 22:34 | ||
On STable | |||
And so not letting them leave the gen2 roots list | |||
dalek | arVM: ffa4cb1 | nicholas++ | src/6model/reprs/P6opaque.c: In P6opaque's compose(), zero the freshly allocated repr_data->unbox_slots. Not all the slots are used, but serialize_repr_data() will serialise all of them, and hence write out garbage to disk. This doesn't cause crashes, because the unuused slots are never accessed, but it does conceal other problems. valgrind reports an awful lot of warnings, concealing real problems, and the generated bytecode files will not be byte-for-byte identical, preventing easy consistency checking. |
22:39 | |
timotimo | nwc10++ # removing unnecessary garbage reads/writes | 22:46 | |
diakopter thinks that fix might not have detectable improvement | 22:49 | ||
but I'm hoping to be surprised | 22:50 | ||
jnthn | diakopter: ffa4cb1 almost certainly ain't. 4c8452a was for me. | ||
ffa4cb1 eliminates most of valgrind's sadness | 22:51 | ||
diakopter | I meant the repr frames one | ||
jnthn | diakopter: Oh | ||
Yeah, I dunno about that. Marking STables isn't profile-expensive in any I've done. | 22:52 | ||
But adding gen2 roots is. | |||
Oh, and it wouldn't show up in there... | |||
We'll see :) | |||
diakopter leaves it to you | |||
since I don't have my phone dev env set up yet | |||
jnthn | ETOOTINYTODEV | 22:53 | |
:P | |||
timotimo | cpython takes 4116 maxresidentk for print("hello world") | 22:55 | |
will we reach that? :3 | |||
if you think about it, using more than one floppie's worth of space in RAM just to print "hello world" is pretty crazy | 22:56 | ||
jnthn | So is thining "hello world" is a useful benchmark :P | 22:59 | |
*thinking |