portkey

Portkey: from REPL to Serverless in one call
cgrand 2017-08-10T08:41:16.320951Z

UCInterpreter.merge is responsible for merging UCValues

cgrand 2017-08-10T08:44:07.386111Z

together they are a join semi-lattice https://en.wikipedia.org/wiki/Semilattice

cgrand 2017-08-10T08:44:48.401746Z

currently merge is bugged and can create cycles

cgrand 2017-08-10T08:46:38.444285Z

asm Analyzer takes a method and returns an array of Frames, one frame per instruction.

viesti 2017-08-10T08:46:52.449587Z

SemiLattice for a class name would have been neat šŸ˜„

cgrand 2017-08-10T08:47:58.474566Z

a Frame represents the (abstract) state of the VM at a given instruction: it contains abstract values for all locals and the stack

cgrand 2017-08-10T08:50:33.534875Z

frames[0] is initialized with an empty stack, and abstract arguments (created only from their type). Unitiliazed locals are abstracted to whatever Interpreter.newValue(null) returns. This value is also used for padding of double-word values (longs and doubles).

cgrand 2017-08-10T08:51:18.552247Z

starting from frame[0] the analyzer interprets the bytecode and produces next frames

cgrand 2017-08-10T08:52:48.586568Z

when a jump occurs to a previously visited instruction then the new frame and the old frames are merged and subsequent frames will be recomputed.

cgrand 2017-08-10T08:57:22.692504Z

for this process to terminate it must converge

cgrand 2017-08-10T08:58:53.728849Z

the semilattice properties assures that progress is made, convergence involves the interpreter not creating ever ā€œgreaterā€ abstract values.

cgrand 2017-08-10T09:06:52.918576Z

Here are the kind of abstract values we try to represent: ā€¢ constants (strings, numbers, classes for a start) as their own value ā€¢ uninitialized ā€¢ instances with their types

viesti 2017-08-10T09:34:45.541413Z

hmm so what happens in merge with different sized Values?

viesti 2017-08-10T09:35:25.556757Z

looking at

@Override
    public Value merge(final Value v, final Value w) {
        // is this enough?
        if (v.equals(w)) return v;
        if (((UCValue) v).type == null && w.getSize() == 1) return w;
        if (((UCValue) w).type == null && v.getSize() == 1) return v;
        return UCValue.UNINITIALIZED_VALUE;
    }

viesti 2017-08-10T09:35:44.563368Z

UCValue.UNINITIALIZED_VALUE is returned I guess

viesti 2017-08-10T10:12:07.356425Z

switched to Idea+Cursive for Java land browsing, seems that I have to renew Cursive license

cgrand 2017-08-10T10:19:04.492602Z

these 4 lines of code are baaaaad (well #2 and #3)

viesti 2017-08-10T10:20:20.517868Z

thought so šŸ™‚

viesti 2017-08-10T10:20:32.521608Z

or innocent at least, they need friends šŸ™‚

viesti 2017-08-10T10:21:22.537347Z

good friends

cgrand 2017-08-10T10:22:32.559888Z

Iā€™m not even sure that in legal bytecode you could have that case (merging different sizes)

cgrand 2017-08-10T10:23:16.574317Z

reuse of space happens but between different points in the program

cgrand 2017-08-10T10:23:29.578401Z

merge occur at the same place in a program

cgrand 2017-08-10T10:24:31.599400Z

it makes no sense to say ā€œat instruction #42, local #1 and #2 are one double or two object references.

cgrand 2017-08-10T10:25:20.615267Z

ā€œone double or one longā€ (no diff in size) seems already wrong

cgrand 2017-08-10T10:50:41.091557Z

the only case where it may happen is when an ā€œunitializedā€ slot is merged with a double-word one

cgrand 2017-08-10T11:20:30.635347Z

and this kind of merge should not happen (from my current understanding of the analyzer) with ā€œnot initializedā€ values (cf access arrays)

viesti 2017-08-10T11:50:17.177348Z

so hmm, did the problematic behavior of merge surface only after these two commits? https://github.com/cgrand/portkey/commit/217acd4e6eae54ee995363861f362135b1e197b3 5b651877291c165e807a39e29133f1612473f30a

cgrand 2017-08-10T11:51:19.197273Z

these two commits allowed to go further and reach problematic code

viesti 2017-08-10T11:55:57.284307Z

yep

viesti 2017-08-10T15:56:33.273442Z

hmm, Kotlin uses also Interpreter https://github.com/jetbrains/kotlin/commit/c24e6b56985f86e857523f9bbce27395a3f33945