dissecting the Scope API
David Holmes
david.holmes at oracle.com
Sat Dec 22 06:53:17 UTC 2018
Hi Maurizio,
On a casual read aspects of this are sounding like RTSJ MemoryAreas
[1][2][3], which define allocation contexts which allow for a
bounded/scoped lifetime (and very strong rules about allowing things to
be referenced from other scopes).
Are you aware of those? John may have mentioned them.
Cheers,
David
[1] http://www.rtsj.org/specjavadoc/book_index.html
[2]
https://docs.oracle.com/javase/realtime/doc_2.1/release/rtsj-docs/javax/realtime/MemoryArea.html
[3] http://janvitek.org/pubs/isorc04.pdf "Real-Time Java Scoped Memory:
Design Patterns and Semantics", by Vitek, Pizlo, Fox & Holmes
On 22/12/2018 10:18 am, Maurizio Cimadamore wrote:
> Hi,
> as mentioned in a recent email, I think the Scope API is conflating
> several aspects together, which makes it difficult to discuss it and/or
> evolve it into a more stable API. This email is an attempt at teasing
> apart the various aspects of the Scope API; while it's not meant to be a
> full proposal, I think there are many ideas in here worthy of more
> consideration. Much of the credits for the ideas in here go to Steve
> Dohrmann from Intel and Jorn Vernee who recently started a discussion
> on this [1]; Henry Jen also provided some insights into the dual nature
> played by the Scope API.
>
> So, before jumping into some pseudocode, let's review some basic key
> points:
>
> * I believe Scope is condensing two aspects: it has an allocation
> interface (Scope::allocateXYZ), but it also serves as a life-cycle
> management. While in the end we might (or not) end up to conflate the
> two, let's try to keep them separated for now
>
> * Let's try to get there in layers (as we did for the SystemABI); there
> are clearly low level allocators - e.g. things that just give you a slab
> of memory - called memory regions - and high-level allocators, e.g.
> things that can allocate user defined data (structs, arrays, etc.)
>
> * We'd like the approach to scale, if possible, to different kind of
> memories (heap, offheap, NVM, ...)
>
> * Let's double down on the Pointer abstraction to do the memory
> dereference; e.g. let's not add methods to a memory abstraction a la
> Unsafe (get/putLong, ...) instead, let's have a way to get a Pointer out
> of a memory region
>
> So, let's start... the first thing we need is something that creates
> memory regions:
>
> interface MemoryStore {
> MemoryRegion allocate(long size);
> MemoryRegion allocate(Access access, long size);
> void free(MemoryRegion region);
>
> interface Access {
> READ, WRITE, READ_WRITE;
> }
>
> static MemoryStore offheapStore() { ... }
> static MemoryStore heapStore() { ... }
> ... //others?
> }
>
> So far so good, we can create regions, with given access etc. Note that
> here I'm trying to hide the addressing model used by Unsafe (Object +
> long offset); after all, the addressing model depends on the kind of
> memory you are operating on, so I don't think it's good to expose it via
> the API (if we can avoid doing so).
>
> What is a memory region? Here:
>
>
> interface MemoryRegion {
> MemoryStore store();
> Pointer<?> basePointer();
> //maybe ByteBuffer accessor too?
> boolean checkAlive();
> boolean checkAccess(Memory.Access access);
> long size();
> }
>
> As Jorn (and separately, Steve) suggested, this could be the place where
> we add the logic for liveness check - more specifically, a memory region
> is considered alive unless freed on its corresponding store.
> Interestingly, a memory region has a way to retrieve a pointer to its
> base location. We can assume it will be a void pointer and that the
> client will have to cast accordingly; this is, after all, a low level
> API. This is also a very general API - it's not really specific to
> Panama - other than the fact that a memory region can be projected to a
> Pointer - but we can imagine other useful projections too (e.g.
> Bytebuffers).
>
> What about high-level allocation? This is where Panama-related concepts
> start to kick in:
>
>
> abstract class Allocator {
> Allocator(MemoryStore store);
>
> public <Z> Pointer<Z> allocate(LayoutType<Z> type);
> public <Z extends Struct<Z>> allocateStruct(Class<Z> strClass);
> ... //other allocation factories
> }
>
> So, an allocator takes a store, and then implements the various
> allocation functions; it is easy to see how such allocation functions
> can be implemented: they will typically obtain a region (using the
> store) of a given size (given by some LayoutType), then obtain a pointer
> from the region and cast it to the desired type.
>
> What about scope-ness? Let's start from here:
>
> abstract class ScopedAllocator extends Allocator implements AutoCloseable {
> ScopedAllocator(MemoryStore store);
> public void close() //this makes sure that all regions created
> within this 'scope' are automatically freed
> }
>
> So, this is a special allocator that also supports the AutoCloseable
> interface, and can therefore be used with a try-with-resources, in the
> usual way. In other words, clients will often do things like:
>
> try (Scope sc = new ScopedAllocator(MemoryStore.offheapStore())) {
> sc.allocateStruct(...)
> }
>
> You can think of this as an allocator that keeps track of the regions it
> creates, and frees them as soon as you call close().
>
> I think this looks more or less equivalent to what we have now, but we
> have captured and broken down the primitive concepts more clearly now.
> There's a *store* that is responsible for allocating regions (all
> relatively Panama-agnostic), and high level allocators, built on top of
> stores, which provide the user facing allocation facilities. Scoped
> allocators keep track of memory region usages, to allow for automatic
> collection upon closing.
>
> One remarkable thing is that Scope/Resource have disappeared from this
> API - the features available in the current Scope interface have been
> split between memory regions and allocators. I think there could be ways
> to add back explicit scopes into this flavor of the API - but I think
> that, before we jump to that, it's better to stop and ask - what are the
> use cases that would not be covered by this proposal?
>
> Maurizio
>
> [1] -
> http://mail.openjdk.java.net/pipermail/panama-dev/2018-December/003572.html
>
>
More information about the panama-dev
mailing list