Open Bug 1003801 Opened 5 years ago Updated 4 months ago
[meta] Recover all non-effectful instructions
I'm trying to understand the logic in RAdd::recover in jit/Recover.cpp In RAdd::recover in jit/Recover.cpp, js::AddValues is called with parameters of type RootedValue although js::AddValues in vm/Interpreter.cpp accepts parameters of type MutableHandleValue. Why is that not a problem? Can we safely assume that each SnapshotIterator::read call will return us an operand of the operation Inst, whose RInst::recover method we are implementing?
(In reply to inanc.seylan from comment #2) > I'm trying to understand the logic in RAdd::recover in jit/Recover.cpp > > In RAdd::recover in jit/Recover.cpp, js::AddValues is called with parameters > of type RootedValue although js::AddValues in vm/Interpreter.cpp accepts > parameters of type MutableHandleValue. Why is that not a problem? In order to have a precise GC, we need to index all values/objects which are followed by the GC. To do so we use RootedValue / RootedObject, which is a linked list of values which are traversed by the GC. These objects (Rooted*) can be implictly converted into an Handle* which is the equivalent of a reference. The only difference with a reference is that ensure that we have rooted it previously. A MutableHandle* is like a pointer to the Rooted, where we can change the content of the Rooted. you can find more detail on our GC Rooting Guide.  https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/GC_Rooting_Guide > Can we safely assume that each SnapshotIterator::read call will return us an > operand of the operation Inst, whose RInst::recover method we are > implementing? Yes, with the operands of the MInst. The SnapshotIterator::read() reads the value of allocations (= where it is stored) encoded in the snapshot. When a snapshot is encoded, each MInstruction which is flagged as RecoveredOnBailout would have all its operands allocations encoded sequentially in the snapshot. When you use the SnapshotIterator::read() in a RInst::recover(), you are reading the value represented by the MDefinition operands of the MInst, in the same order as they are list in the MInst.
This image is produce by iongraph with support for recover instruction (as linked above): I ran: IONFLAGS=logs ./build-debug/dist/bin/js --ion-parallel-compile=off --ion-eager jit-test/tests/ion/dce-with-rinstructions.js then in iongraph directory: make clean png This function correspond to the Float32 variant which has multiple additions in it, as you can see the additions appear in gray instead of being black as other instructions, because they are used on the bailout path, as resume points.
(Copy of the reply of an email) On Tue 20 May 2014 04:53:28 PM PDT, Amol Mundayoor wrote: > I have been trying to understand what Recover.cpp does along with the > other files that were edited in the provided patch (IonAnalysis.cpp, > MIR.cpp, jsmath.cpp). While I understand that the code within these files > get executed when the compiler requests a bailout (after executing a non > successful optimization path), I have some questions: > > Is my understanding (of when the code gets executed) correct? Yes, RInstructions::recover functions are executed when we bailout from IonMonkey to Baseline. They are using the SnapshotIterator (IonFrameIterator.h) which is basically the central point for giving an interpretation to IonMonkey's allocations (registers, stack offsets, constants, recover instructions). When we generate code for IonMonkey, we record all the locations into a snapshot for each LInstruction which might bailout. The SnapshotIterator decodes all these informations which are stored during the compilation. Bailouts are using a SnapshotIterator to read and execute the RInstruction::recover functions. > I would also like to know how we extract the information from the JIT > compiler frame (I read this article > <https://wiki.mozilla.org/Platform/Features/IonMonkey>) The SnapshotReader (Snapshots.cpp) decodes allocations of Value. The allocation can either be a register (we get the spill location of it by reading the MachineState), a stack offset (we read from the bottom of the IonFrame), a constant (we read from the constant pool of the compiled script meta data), a recover instruction result (we read from the vector where the result is supposed to be stored). > I have seen skeleton functions in Recover.cpp under m-c. Is that the only > file I'll have to edit apart from writing tests? Or is > dce-with-rinstructions.js the test file that I'm supposed to pass? You will also have to edit MIR.h to encode the Recover_Instruction byte, and Recover.h to declare the structure of the RInstruction.
Hi Nicolas. I'm studying the Recover.cpp code and I guess I'm able to implement a patch, but I would like to share a question here. I've made a some changes on RSub::recover(Recover.cpp#355) to force an error(changed 'SubValues' to 'MulValues'. So, I've tested the dce-with-rinstruction.js using ./dist/bin/js --ion-eager ../jit-test/tests/ion/dce-with-rinstructions.js and all test cases passed ok. When I've used the --ion-parallel-compile=off flag, the test test case of 'rsub_number' failed(as i expected). So, I've started to make some guesses, but I would like to understand it correctly. This test case gave me another doubt. When the Ion JIT fails, it bailout to the last success Instruction and execute it agin on Baseline level? Another question is, What is the real behavior of iter.read()?
(In reply to Caio Lima(:caiolima) from comment #6) > I've made a some changes on RSub::recover(Recover.cpp#355) to force an > error(changed 'SubValues' to 'MulValues'. So, I've tested the > dce-with-rinstruction.js using ./dist/bin/js --ion-eager > ../jit-test/tests/ion/dce-with-rinstructions.js and all test cases passed > ok. When I've used the --ion-parallel-compile=off flag, the test test case > of 'rsub_number' failed(as i expected). So, I've started to make some > guesses, but I would like to understand it correctly. When we compile with ion eager, we start the compilation out of the main thread with ion-eager, but the result of the compilation might not arrive in time for catching the failure. When ran with --ion-parallel-compile=off, as soon as we want to compile we wait for the compilation result to be available before running the function. This garantee that the compilation would be available as soon as we request it to be compiled. > This test case gave me another doubt. When the Ion JIT fails, it bailout to > the last success Instruction and execute it agin on Baseline level? Yes, which is why we restrict these optimizations on side-effect free instructions. Which is also the reason why we protect us against the object input case, as an object might be the subject of obervable changes. > Another question is, What is the real behavior of iter.read()? You can look at the code at, this function is used to iterate over the allocations contained in a snapshot. The best representation of it is in the slides I made to introduce recover instructions.  http://dxr.mozilla.org/mozilla-central/source/js/src/jit/JitFrameIterator.h?from=js::jit::SnapshotIterator::read%28%29&case=true#374  https://nbp.github.io/slides/RInstruction/index.html?full#recover-instruction-rp
Thank you for the explanation! So, actually, when the Bailout occurs, the Baseline executes since the last ResumePoint instead of return to the last imediate Instruction. Is it right? By the way, the basic operations was implemented, but we need to implement the remain MDefinitions. May I open new bugs for them?
(In reply to Caio Lima(:caiolima) from comment #8) > So, actually, when the Bailout occurs, the Baseline executes since the last > ResumePoint instead of return to the last imediate Instruction. Is it right? This is correct. we resume the execution in baseline since the last captured resume point. > By the way, the basic operations was implemented, but we need to implement > the remain MDefinitions. May I open new bugs for them? Only the non-effectful one, as we cannot recover after an effectful instruction. I gathered a list in comment 0. If there is no more bug available, or if you are interested by one in particular, feel free to open it as we did for other recover instructions.
Clean-up: https://hg.mozilla.org/integration/mozilla-inbound/rev/6ddc7aee37eb Add a [leave-open], as this is a meta bug.
10 months ago
You need to log in before you can comment on or make changes to this bug.