github.com/moarvm/moarvm | IRC logs at colabti.org/irclogger/irclogger_logs/moarvm Set by AlexDaniel on 12 June 2018. |
|||
01:11
ZzZombo left
01:16
lucasb left
04:18
coverable6 left,
reportable6 left,
quotable6 left,
evalable6 left,
benchable6 left,
committable6 left,
nativecallable6 left,
squashable6 left,
shareable6 left,
bloatable6 left,
statisfiable6 left,
tellable6 left,
greppable6 left,
notable6 left,
unicodable6 left,
bisectable6 left,
releasable6 left,
nativecallable6 joined
04:19
coverable6 joined
04:20
greppable6 joined,
statisfiable6 joined,
shareable6 joined,
bisectable6 joined
04:21
bloatable6 joined,
quotable6 joined,
committable6 joined
04:22
squashable6 joined,
reportable6 joined,
benchable6 joined,
evalable6 joined,
releasable6 joined,
tellable6 joined,
unicodable6 joined
04:23
notable6 joined
06:55
sena_kun joined
08:04
domidumont joined
|
|||
nine | For several hours, I've tried to come up with a reliable way to unsetup a native sub at all the required times and have failed so far. | 08:58 | |
But why do I need to do that in the first place? It's because MoarVM changes the state of the native call site without the upper layers noticing it. | 08:59 | ||
But MoarVM already has a way to maintain and keep that state: serialization. It's just that this is not implemented for NativeCall reprs. Instead we rely on the upper layer to run initialization again. | 09:00 | ||
But why is that? We actually have all the information we need to load that library and JIT compile the function body in the NativeCall's body. We just need to serialize that and run some initialization on deserialize. | 09:03 | ||
MasterDuke | sounds promising | 10:15 | |
nine | And not just that...it even works :) | 10:26 | |
At least for rakudo's tests and my golfed test case. There's still issues in Inline::Perl5, but that's just a matter of more debugging I guess | 10:28 | ||
Oh, I commented out a line in Inline::Perl5 during debugging. That of course doesn't help at all... | 10:30 | ||
There's one issue remaining that's really baffling. | 12:30 | ||
Exactly one of Inline::Perl5's tests is failing with a "Stub code executed" error, i.e. one (and apparently really only one) of the native subs is losing it's CALL-ME magic without getting the optimized function body | 12:32 | ||
13:02
Altai-man_ joined
|
|||
nine | Ok, how is it possible that the sub's invocation protocol gets changed but the code body not replaced when both is done by the !setup method? | 13:02 | |
The invocation protocol is a property of the type while the body is part of the object. Apparently only one of those gets repossessed (I guess the type) and thus changed by loading the precomped module. | 13:04 | ||
13:04
sena_kun left
13:05
Altai-man_ left
13:13
domidumont left
13:50
ZzZombo joined
13:53
lucasb joined
|
|||
nine | I can circumvent this by not changing the invocation protocol and not replacing the code body during compilation. But that means that the function will never get the speedup as the setup code will only ever run once. | 14:29 | |
dogbert17 | that sounds a bit bad doesn't it? | 14:32 | |
or perhaps I should have written suboptimal | 14:34 | ||
nine | Both are correct ;) | 14:35 | |
So....native subs get their special behaviour with the CALL-ME body mixed in. What if I mix in another role that gets rid of CALL-ME? | 14:37 | ||
Instead of changing the Mixin after the fact | |||
The question is: can a role hide a CALL-ME? | 14:39 | ||
dogbert17 | who might have the answer to that question? | 14:42 | |
nine | As an alternative I thought, maybe it's enough to mixin any role. This way the routine would get a new type and I only change the invocation spec of this new type. This would mean that we could never end up with an object with a changed code body but with an unchanged invocation spec. | 14:51 | |
Alas....this only gives me a different repossession error: Incompatible MROs in P6opaque rebless for types Method+{NativeCall::Native[Method,Distribution::Resource]}+{Callable[NativeCall::Types::Pointer]}+{<anon|1>} and Method+{NativeCall::Native[Method,Distribution::Resource]}+{Callable[NativeCall::Types::Pointer]} | |||
I think the whole issue is caused by repossession order. | 15:15 | ||
dogbert17 | so there are still bugs hiding :) | 15:17 | |
nine | Not sure it can be called a bug. It may be a conceptual restriction. | ||
I've been at this bug for 8 hours straight, so I'm not sure I've got enough brane left to explain this properly :/ | 15:18 | ||
But....I wonder if there's another workaround worth trying: due to even weirder issues NativeCall has never created optimized function bodies during precompilation. But what if we could at least replace the stub code with a function body that runs !setup? I've had success doing this manually | 15:19 | ||
dogbert17 | is that 'easy' to do? | 15:24 | |
nine | No, that'd require anything, literally anything to cooperate today... | 15:27 | |
Well....taking it one step further: if I already think about replacing the code body, why do we even add a CALL-ME in the first place? Why not replace the stub code with what CALL-ME is doing right now? | 15:28 | ||
Then we'd never have to change the invocation spec in the first place | 15:29 | ||
Feels like this whole thing is another exercise in finding out how deep a rabbit hole can really be | 15:30 | ||
dogbert17 | sounds clever. Are there any counterarguments, like code duplication? | ||
nine | No, it sounds desparate. Style is no longer an issue. This is about survival. | 15:33 | |
dogbert17 | uh oh | ||
timotimo | i wish for programs to be runnable without the compiler getting loaded at all :S | ||
at the moment we can't get that yet | 15:34 | ||
hm. for cases like "empty code file, but a -M is provided" we could probably get away without loading Grammar and Actions | 15:35 | ||
wouldn't that be nice | |||
nine | "An exception occurred while evaluating a constant" oh thank you! How helpful | ||
dogbert17 | sounds a bit like Visual Basic of old. "Array index out of range", and no we won't tell which array or where in the code that happened | 15:36 | |
nine: perhaps it's time for some food | 15:47 | ||
nine | Useless use of constant integer 1 in sink context (line 554) | 15:52 | |
No, actually this prevents "No such method 'sink' for invocant of type 'QAST::Stmts'" | |||
Which would be triggered by literally any code after that if block. It's pure chance that this hasn't happened before | 15:53 | ||
dogbert17: food does sound like a great idea | 15:55 | ||
Why can't anything ever go smooth? | 16:34 | ||
17:50
domidumont joined
|
|||
timotimo | cdn.discordapp.com/attachments/538...nknown.png - "find objects" shows BOOTHash objects grouped by size (it will of course later on also show what type is being looked for, lols) | 17:55 | |
19:08
domidumont left
|
|||
nine | m: perl6 -e 'class Foo { method foo() { ??? }; BEGIN { my $meth := Foo.^find_method("foo"); use nqp; nqp::bindattr($meth, Code, q<$!do>, nqp::getattr(-> |a { note "foo!" }, Code, q<$!do>)); }; }; Foo.foo;' | 19:37 | |
camelia | ===SORRY!=== Error while compiling <tmp> Two terms in a row at <tmp>:1 ------> perl6 -e⏏ 'class Foo { method foo() { ??? }; BEGI expecting any of: infix infix stopper postfix statement… |
||
nine | m: class Foo { method foo() { ??? }; BEGIN { my $meth := Foo.^find_method("foo"); use nqp; nqp::bindattr($meth, Code, q<$!do>, nqp::getattr(-> |a { note "foo!" }, Code, q<$!do>)); }; }; Foo.foo; | ||
camelia | Stub code executed in method foo at <tmp> line 1 |
||
nine | m: class Foo { method foo() { ??? }; do { my $meth := Foo.^find_method("foo"); use nqp; nqp::bindattr($meth, Code, q<$!do>, nqp::getattr(-> |a { note "foo!" }, Code, q<$!do>)); }; }; Foo.foo; | ||
camelia | foo! | ||
nine | m: class Foo { method foo() { ??? }; BEGIN { Foo.foo; my $meth := Foo.^find_method("foo"); use nqp; nqp::bindattr($meth, Code, q<$!do>, nqp::getattr(-> |a { note "foo!" }, Code, q<$!do>)); }; }; Foo.foo; | ||
camelia | Stub code executed in method foo at <tmp> line 1 foo! |
||
nine | So.....WTH?! | ||
Replacing the method's $!do at runtime is OK, but at BEGIN time it just doesn't do anything, except for when the method has been called at least once? | 19:38 | ||
Ah, of course! It's just missing the magic invocation: | 19:43 | ||
m: class Foo { method foo() { ??? }; BEGIN { my $meth := Foo.^find_method("foo"); use nqp; nqp::getattr($meth, Code, q<@!compstuff>)[1](); nqp::bindattr($meth, Code, q<$!do>, nqp::getattr(-> |a { note "foo!" }, Code, q<$!do>)); }; }; Foo.foo; | |||
camelia | foo! | ||
timotimo | compstuff? %) | 19:47 | |
nine | I've rarely written such self explanatory code | ||
All tests successful. | 20:26 | ||
timotimo | nice | ||
nine | Without the CALL-ME there's no more need to fiddle around with the invocation protocol, i.e. there cannot be any divergence between the routine's type and its body. This should also remove the need to exclude clones (i.e. closures) from getting the speedups. | 20:28 | |
timotimo | good | 20:29 | |
21:07
Ven`` joined
21:34
zakharyas joined
21:43
Kaiepi left
21:44
Kaiepi joined
21:55
zakharyas left
22:55
Ven`` left
23:00
committable6 left,
notable6 left,
greppable6 left,
nativecallable6 left,
shareable6 left,
evalable6 left,
bisectable6 left,
squashable6 left,
coverable6 left,
statisfiable6 left,
benchable6 left,
releasable6 left,
unicodable6 left,
bloatable6 left,
tellable6 left,
quotable6 left,
reportable6 left,
evalable6 joined
23:01
releasable6 joined,
squashable6 joined,
unicodable6 joined
23:02
greppable6 joined
23:03
tellable6 joined
23:04
bloatable6 joined,
quotable6 joined,
shareable6 joined,
reportable6 joined,
statisfiable6 joined,
benchable6 joined,
notable6 joined,
bisectable6 joined
23:05
coverable6 joined,
committable6 joined,
nativecallable6 joined
|
|||
timotimo | the collectable navigator now lets you use the browser's back and forward buttons | 23:39 |