fidothe has quit [Read error: Connection reset by peer]
sagax has quit [Read error: Connection reset by peer]
shellac has joined #jruby
sagax has joined #jruby
<headius[m]>
enebo: I'm working on getting instructions to lazily deserialize, which will be useful for AOT but might actually make IR precompiling a win too
<headius[m]>
problem I'm having is that I can't defer the the reading of the instructions because there's no length encoded
<headius[m]>
I will probably have to change the writing logic to write the instrs to a temporary byte buffer before actually writing to the stream
<headius[m]>
that will be additional overhead for writing but perhaps we don't care?
<enebo[m]>
ah you mean total byte size of the chunk
<headius[m]>
yeah
<enebo[m]>
we do not care since it is a side-effect of compilation thread
<headius[m]>
it's a little tricky because you have everything behind interfaces
<enebo[m]>
or it would be if we had full time serialization on
<headius[m]>
I think this should go in the impl of IRWriterEncoder because the IRWriter class can't really control how or when the encoder writes
<enebo[m]>
Assuming this makes it super fast :)
<enebo[m]>
I doubt it would be a huge extra overhead to writing
<headius[m]>
probably not
<enebo[m]>
I mean writing to a byte[] and then doing a single write() or something is probably not slower
<enebo[m]>
or not very much
<enebo[m]>
I don't remember how do we write anyways?
<headius[m]>
probably not much slower yeagh
<enebo[m]>
the interface design started from the GSOC project. Honestly, it gives us ability to wrapper it (which is only used for logging)
<headius[m]>
oh you know what I do see something interesting
<headius[m]>
you seem to write everything to a ByteBuffer?
<enebo[m]>
If I was to start that from scratch I would probably fixed width bytes and try to use protobufs and also make a binary interpreter
<headius[m]>
yeah
<headius[m]>
that would be magic
<enebo[m]>
It definitely would be faster
<enebo[m]>
faster to start executing at least
shellac has quit [Quit: Computer has gone to sleep.]
<enebo[m]>
headius: so I think in some sense our two activities do not stomp on each other
<enebo[m]>
I am just reducing usage of IRScope within generated bytecode and at runtime
shellac has joined #jruby
<enebo[m]>
I may not make it completely eliminated but as I said before I like the notion that IRScope is for "compiler" activities and staticscope is for "runtime" activities
<enebo[m]>
the fact that IRScope is referenced from StaticScope is one unknown still but a quick look and main issue I can see if runtime uses IRScope for non local returns
<headius[m]>
yeah it makes sense
<enebo[m]>
I keep repeating this because it is the exact opposite of how I felt a year ago
<headius[m]>
non-local returns have to use dynamic scope
<enebo[m]>
I had the intention of IRScope being the only thing but it is obvious in retrospect it has a cost for stuff like this
<headius[m]>
or frame
<enebo[m]>
It also makes it much easier to just dangle stuff off of IRScope
<enebo[m]>
headius: I have not looked at how it is used but noticed it was used
<enebo[m]>
I agree though it probably is replaceable
<enebo[m]>
heh I used 'was' ... how is that for optimism
<enebo[m]>
Ironically I see getFile() as weirder edge case
<headius[m]>
hmm I'm really confused by the workflow of the IR writer
<enebo[m]>
but that is really only encountered via AOT itself
<headius[m]>
it puts the instruction offset into a map right before it encodes the instructions
<headius[m]>
but later it needs to write the offset before the instructions
<enebo[m]>
ok I think I can explain this :) It has been a long time
<headius[m]>
OH
<headius[m]>
I think I just got it
<headius[m]>
the scope headers actually go at the end of the file
<enebo[m]>
The top of the file contains all scopes and each entry needs to know where instrs are
<enebo[m]>
or bottom of the file
<headius[m]>
end of the file?
<enebo[m]>
somewhere is the scope headers and all instrs are just in a section
<headius[m]>
ok I think I get it
<enebo[m]>
anyways the instrs are not written into the scope header info
<enebo[m]>
that is why there is an offset
<headius[m]>
that may make this easier then
<headius[m]>
I should be able to just add another map of scope's instr length
<enebo[m]>
if you add a length to the scope header it can instantly be lazy as long as you keep it open
<headius[m]>
yeah
<enebo[m]>
"keep it open"
<headius[m]>
that's a separate discussion but I was planning to still read into a byte[]
<headius[m]>
yeah
<enebo[m]>
you actually could keep a map of files to reopen
<headius[m]>
I mean these could also be mmap'ed and then they're "open"
<enebo[m]>
with that info but obviously try this one first
<enebo[m]>
yeah
<headius[m]>
reopening is a worry because file may change
<headius[m]>
but byte[] is simple to do for now, and then the scope has everything it needs in memory to restore instrs
<enebo[m]>
I mean from an appcds perspective you just need to access into "something"
<headius[m]>
I will have you review this
shellac has quit [Quit: Computer has gone to sleep.]
<headius[m]>
hmm yeah if the bytes are coming out of constant pool they don't necessarily need to be copied into a new byte[]
<headius[m]>
but that's opto we can do later
shellac has joined #jruby
<enebo[m]>
yeah I guess that was what I meant by 'something'
ur5us has joined #jruby
<enebo[m]>
yeah this may work out really well
shellac has quit [Client Quit]
<enebo[m]>
I am sure a lion share of original IR persist was loading instrs
<enebo[m]>
for an AOT which will not ever call those then that part of the time will disappear
<enebo[m]>
StaticScope itself is smaller so if I succeed then it may chip away at that new cost perhaps
<headius[m]>
this would only deserialize a tiny part of Rails + deps on boot
<headius[m]>
I dunno why we didn't think of this initially
<headius[m]>
intrs can be deserialized any time
<enebo[m]>
probably the lack of appcds when we originally put most thought into the problem
shellac has joined #jruby
<enebo[m]>
after it came into being older thoughts made the idea not as visible
<headius[m]>
you basically did the in-memory buffering for me by having headers come at the end of the file
<enebo[m]>
I wanted to read scopes without processing the entire file but I wanted scopes to be able to record that value without having to get into seeking or whatnot
<headius[m]>
huh this already has a measurably effect on -e 1
<headius[m]>
where does IR write by default
<enebo[m]>
One thing I don't recall is how it knows to skip to where the scope headers start
<headius[m]>
it outputs that offset at the front of the file
<headius[m]>
before it dumps the in-memory buffer
<headius[m]>
so you basically are doing what I would have had to do by design
<enebo[m]>
ah ok that would have been my guess but then I could have just recorded where to store offsets for each scope and seeked there
<enebo[m]>
I don't remember but there might have been some benefit to writing in memory and doing a single write
<enebo[m]>
It is atomic in the sense it will not generate a partial file
<enebo[m]>
but I doubt that was an explicit reason as much as a coincidental benefit
<headius[m]>
oh ~/.ir I think?
<enebo[m]>
yeah could be...new laptop
<headius[m]>
yeah there it is
<headius[m]>
yoink
<headius[m]>
is there any verification in the reader?
<enebo[m]>
no
<headius[m]>
none of this is relevant for AOT but if this actually speeds startup we might start doing it by default
<headius[m]>
that's the only other read of ir.writing property
<enebo[m]>
and that is more overhead
<enebo[m]>
not much
<headius[m]>
yeah
ur5us has joined #jruby
<enebo[m]>
ex.printStackTrace on persist
<enebo[m]>
so presumably you would see that
<headius[m]>
yeah
<headius[m]>
should go straight to stderr
<enebo[m]>
I find it impossible to see how this could be that much faster on a single thread
<headius[m]>
yeah like way faster
<enebo[m]>
I do not think half our startup is parsing
<enebo[m]>
part of the whole parse thing is actually registering methods and so forth
<enebo[m]>
the execute part mixes into it
<headius[m]>
well for rails -v it might be a large part
<headius[m]>
parsing + compiling
<enebo[m]>
yeah I guess. I mean it still defines a lot of types and methods
<enebo[m]>
It must because it takes forever
<enebo[m]>
where -v prints in Rails source put a 'gets' and dump with/without
<enebo[m]>
See if you have similar numbers of classes/modules
<enebo[m]>
ir.write makes no sense bcause it is both reading all the sources of .rb and still deciding to persist them :) No way that can actually be faster
<enebo[m]>
We will realize we have been 2x parsing/loading everything for the last 10 years and be happy while crying
<headius[m]>
yeah I'm baffled
<headius[m]>
wow
<headius[m]>
ir.writing.debug needs a non-verbose mode
<headius[m]>
and it screwed up my terminal with some ansi color
<enebo[m]>
I always write that out to a file
shellac has quit [Quit: Computer has gone to sleep.]
<enebo[m]>
The primary debugging was to figure out what operand was missing on encode/decode
<headius[m]>
yeah
<headius[m]>
maybe I want ir.writing.log
<headius[m]>
or something
<enebo[m]>
all operands start with ascii char
<headius[m]>
I just wanted to know what files were getting written
<enebo[m]>
yeah I can only say nuke ~/.ir run the command and see what is there
<enebo[m]>
not perfect obviously and it will not tell you what is really in the file
<enebo[m]>
although we could probably write a simple print scopes script