Created
May 27, 2011 15:21
-
-
Save cotto/995467 to your computer and use it in GitHub Desktop.
cps questions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
list of questions about CPS and how it relates to M0 | |
* goals * | |
implement cps fib in M0 | |
* notes from the meeting * | |
need to add an optional signing chunk that signs everything except the signing chunk itself | |
- sign a zeroed version of the file | |
- signing chunk needs to be extensible so that it'll work fine once sha1 is broken | |
- storing algorithm as a name is more user-friendly | |
* allison question - when merging files, does the metadata keep track of which files the chunks came from? | |
- | |
* need to think about how m0b_merge will work. | |
* moving to continuations | |
- when you take a continuation that's later modified, you want those modifiations. The taken coninuation should be a pointer. | |
* look into dynasm - chromatic says it's a really good thing to look into | |
* a continuation is a context | |
* cps is slow IF | |
- taking a continuation takes a lot of cpu time | |
- taking a continuation takes a lot of memory | |
- taking a continuation should be a pointer copy | |
- what makes a continuation captures is that there's a pointer to it | |
- a potential GC optimization is to have a context-specific memory pool | |
* need to consider changing the name "context" to something else. It's not a stack. "Call frame" is a more univeral name. | |
* andrew's proposal is message-passing only, so each context is isolated from each other | |
- using message-passing exclusively means we're limited in the languages we can support. | |
- we need to support experimentation | |
- Async I/O is the better way since it can emulate synchronous I/O | |
* GC needs to play nice with M0, M0 needs to play nice with GC | |
- all M0 needs to know about is that GC is that it has chunks of memory | |
* for the existing Parrot, we need to move to a compile-time selected GC | |
- a possibility is to make GC a link-time thing by compiling all GCs to .o files and deciding when libparrot is linked | |
- equivalent to infnite gc is to modify tuning options to effectively infinite memory | |
* thinking about memory, there's a p5 targ op that sets up a temporary sv tied to the stack | |
- in M0, look at references and if they can't escape, make them temporary and tied to the lifetime of the call frame | |
- think about how to have M0 store escape and reference information tied to references | |
- if there are 4 possible storage types (global, local, possibly others) you can tag pointers in the variables table | |
- this involves some analysis, which is part of the purpose of M0 | |
- a possibility is to add a lifespan arg to the malloc op | |
- need to think about what the GC interface to M0 looks like | |
- The M0 interface to malloc should be "here's n bytes you can write to and need to free" | |
* M0 should only require FFI if the running code explicitly uses it. | |
- the malloc and free ops should work fine in the absence of ffi | |
- there's another interface to grab a GCable chunk of memory, with flags to indicate stuff | |
- have extra arg to gc_malloc indicates interesting things such as scope, etc (not needed for all interpreters) | |
- need to make sure that the chunk doesn't get killed before it's returned (avoid infant mortality) | |
* in M1, there needs to be a differentiation between the compile-time lexpad, which determines where variables live, and the runtime lexpad, which stores the actual runtime values and of which there can be many | |
* invoke is just another vtable function | |
* what's needed for cps m0 fib | |
- resolve the name of the function | |
- in the common case, the callee is responsible for setting up the storage for arguments and return values | |
- if you inline, you're just operating on the registers directly | |
- the goal is to minimize memory copies | |
- a call (aka invoke) looks like: | |
-- set up a return continuation | |
- this can be as simple as setting the return pc and return chunk in the current context | |
-- caller executes goto_chunk | |
-- callee creates a new context | |
-- callee picks arguments out of the parent context | |
-- callee does its thing | |
-- callee puts return value into a register where the return context knows how to find it | |
-- callee gotos the return continuation (return pc and return chunk) | |
- when you call a chunk that returns, it doesn't create | |
- the important thing is that the M0 interpreter knows what pc to go to when a chunk is done | |
- there's an important distinction between call and return; call | |
- there should be no difference between invoke and return except that return doesn't change the calling context | |
* exceptions | |
- exception handlers should be static so that work only happens when an exception is thrown | |
- an exception handler is just an invokable object | |
- throwing an exception is just invoking an exception | |
- resuming an exception means invoking its calling context (the pc where it exploded + 1) | |
- when an exception handler can't handle an exception, it invokes its parent exception handler | |
- the topmost exception handler spits stuff to stderr | |
- exceptions need - invocation, arg passing, search for next handler | |
- throw op is M1, M0 is create context, lookup handler, invoke handler with exception | |
- current exception doesn't need to be a fixed register; it's always passed to handlers | |
- when setting up a context, exception handlers need to be set up to tailcall into the next register if they don't handle the exception | |
- when an exception is invoked, it looks up the call graph until it finds a context with a usable exception handler | |
- this means that exception handlers are very cheap when they're not used | |
* variables | |
- there's a static variables segment (from bytecode) and a runtime variables table | |
- the runtime variables table is for overflow from the register and lexicals | |
- this isn't optimal | |
- the new solution is to have a special overflow context for spilling | |
- to generate code to spill, put registers in the overflow context | |
- spilling acts like a stack. You spill all existing registers and put a pointer in the overflow context. | |
- the only special register that's copied in spilling | |
- if you repeat, it works and the original overflow context is further back | |
- despilling means restoring all registers *and* the overflow context register of the overflow context | |
* calling conventions | |
- callee is responsible | |
- signatures are an M1 thing | |
- requisite: make sure that it's possible to dereference into the parent context via M0 code and get/set values | |
- with that, we're ok | |
talk about: | |
- M0 fib | |
- roadmap | |
* | |
* a roadmap: | |
- m0b disassembler (can happen any time, also needs tests) | |
- fibonacci in M0 | |
- glossy brochure for M0 - one page w\ motivation, implementation and plan for M0 | |
- complete test coverage | |
- each op is tested | |
- complete branch coverage of the assembler and interpreter according to Devel::Cover | |
- "complete" means anything we can reasonably expect to hit | |
- final implementation of the M0 assembler and interpreter in C | |
- it's an option to use gcc extensions | |
- we also need an C89 or C99 version | |
- calculate the hash of a string using a non-trivial algorithm (CRC or something basic, not sha1 or md5) | |
- noop integration with libparrot | |
- interpreter is linked into libparrot | |
- assembler isn't needed except for developers | |
- implement I/O in M0 | |
- implement a very simple PMC in M0 (noop, hello or int) that acts like a core PMC - set and retrieve a value | |
- TODO: define what the expected distribution method for Parrot-hosted code will be in the distant future | |
- run with the idea of m0b as the distribution format. See what happens and who balks. | |
- | |
- | |
- | |
- | |
- | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment