On Aug 12, 2016, at 2:56 PM, Michael Haupt <michael.ha...@oracle.com> wrote:
>
> Hi Mark,
>
>> Am 05.08.2016 um 12:13 schrieb Mark Roos <mr...@roos.com
>> <mailto:mr...@roos.com>>:
>> Good to see this.
>
> thanks. :-)
>
>> What is the philosophy for code annotations, line numbers and stack maps?
>>
>> Would they be some form of constant entry?
>
> I recall you had asked this question at JVMLS. I think it definitely makes
> sense to add support for these. How would you think they should be
> represented?
>
> Here are some thoughts.
>
> First, stack maps. Leave their generation to the bytecode generation
> framework responsible for producing the bytecode array (whichever one that
> may be), allow for easy extraction of the map from its generation result, and
> for passing that on to the loadCode implementation. This will require a
> library-level representation of stack maps (inspired by Sec. 4.7.4 of the JVM
> Spec), unless the plain class file format for them is used - which may not be
> desirable given the convenience attempts the API is making with the constants
> array. To maintain convenience, stack map generation could be the
> responsibility of the loadCode implementation. This would duplicate the work
> of generating the map, which seems rather unwelcome.
I think the right answer will involve making the verification of IM bytecodes
simpler. For example, if there is no invokespecial, all the nasty rules for
that instruction go away (along with those for "new"). Frame maps are designed
to support one-pass checking of bytecodes. There are restrictions we can put
on IM bytecodes that will recover the ability to perform one-pass checking,
with implicitly derived frame maps. In a nutshell, the first type-state wins,
and any other type-states (e.g., from backward branches) need to match. This
makes it very slightly harder to generate IM bytecodes (with sometimes an extra
checkcast for merge points), but in exchange nobody needs to mess with frame
maps (except maybe VM internals).
This does lead me to an extra thought: I think IM's could be given the
capability to have multiple entry points. This would allow a number of
interesting applications, starting with exception handling that appeals to a
helper object, instead of a handler table and some special verifier rules.
Immediately beyond that, although now I'm being a Mission Creep, if an IM has
multiple entry points for exception handling, it could also use these entry
points for frame resumption, as described by Ron Pressler in a previous JVMLS,
and Andrey Breslav this year. (That leads to the question of how an IM can
yield to an suspension point, a very good question. And something that a
helper object can help with. And so on. This might help us do fibers
experiments more quickly.)
> Annotations can be passed as a map from annotation classes to lists of
> values. Line numbers can be passed as an int array of pairs of numbers, where
> even indices represent start PCs, and odd indices, line numbers.
> Adding to your list, a source file association can be represented as a URL or
> String. (Cream on top: a multiline String containing the IM's actual source
> code.)
I hope all that logic can be wrapped up in a helper object, to be executed only
when needed. I.e., load quickly *with no paperwork*, and have the helper
object figure out what happened later on, if we get asked.
interface IsolatedMethod { // reflected view of raw IM
// recovered arguments to Lookup.loadCode:
Lookup lookup();
String name();
MethodType type();
ByteSequence bytes(); // NOTE: R/O view; same type for CONSTANT_Bytes
List<Object> constants();
// this has to be stuck in somehow:
//Inspector inspector();
interface Inspector { // helper for "paperwork"
String sourceFile(IsolatedMethod m);
String className(IsolatedMethod m);
int mapLineNumber(IsolatedMethod m, int bci);
List<LocalVariableInfo> mapLocalVariables(IsolatedMethod m, int bci);
List<HandlerInfo> mapExceptionHandlers(IsolatedMethod m, int bci);
List<Class> mapFrameState(IsolatedMethod m, int bci);
...
//?MethodHandleInfo methodHandleInfo(IsolatedMethod m);
}
}
> As a further addition, exceptions can be passed as a simple array or list,
> and an exception handler table can be passed as a tuple (not in the Valhalla
> sense, yet) of an int array of triplets of numbers representing start, end,
> and handler PCs and of a list or array of exception classes.
Yes, exception handling is the tricky part (along with verification). Maybe we
could use an Inspector to help extract the details:
interface Inspector { …
int exceptionContinuationPoint(IsolatedMethod m, int bci, Class<? extends
Throwable> exc);
}
The idea would be to call the IM inspector for a continuation point. Of
course, that thing might throw an exception, which makes the model muddy,
though not impossible. Verification of the CP could be lazy, or the CP's could
be marked up front and checked during loadCode.
There's a fiber frame system struggling to emerge here.
— John
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev