Stream: t-compiler/const-eval

Topic: miri machine: global state from access hook

RalfJ (Nov 13 2018 at 16:37, on Zulip):

@Oli I think for the implementation of the last piece of stacked borrows, I'd like to have access to some global state from the memory access hooks (memory_read, memory_written, memory_deallocated). The state should be shared across all allocations. What do you think would be the best way to do that?

RalfJ (Nov 13 2018 at 16:39, on Zulip):

I am talking about "function barriers", which get pushed when a reference is passed to a function and should get removed when the function returns. A naive implementation would be to store the index of the function in the call stack, and then on a pop iterate over all of memory to get rid of these barriers. But I don't want to iterate over all of memory...

RalfJ (Nov 13 2018 at 16:41, on Zulip):

So instead I think I will introduce an indirection: Every call frame gets an ID that is unique across program execution, and we use that ID in the barrier. We have a global table storing which IDs are no longer in use, where frames get added when they are popped. When we encounter a barrier, if its ID is one of a call stack that is marked in that table as having popped already, we just ignore it.

RalfJ (Nov 13 2018 at 16:42, on Zulip):

But that means I need access to this global table from the memory access hooks. My best idea so far: Re-introduce the MemoryData that I killed some PRs ago, and pass that to the hooks. With the hooks being called from methods on allocations, that means those methods need to take a pointer to where the MemoryData is. Kind of ugly, but not too bad -- MemoryData would be () for CTFE so when CTFE accesses an allocation directly (outside of an execution), it can just pass &().

oli (Nov 13 2018 at 16:53, on Zulip):

What about using Rc? That would be completely encapsulated in miri and the engine would never know

oli (Nov 13 2018 at 16:54, on Zulip):

Would of course incur the memory cost of an additional pointer per AllocationExtra

RalfJ (Nov 13 2018 at 16:57, on Zulip):

how would that Rc get into the hooks?

oli (Nov 13 2018 at 16:58, on Zulip):

Uh, I don't know, I'm on mobile right now, so gimme a moment

oli (Nov 13 2018 at 17:05, on Zulip):

So, you do in fact reintroduce the MemoryData, and you also add an AllocExtra method for allocate, which produces the AllocExtra. You pass a reference to MemoryData to the allocate hook. CTFE just ignores the arg and has an empty function body producing the expected unit

oli (Nov 13 2018 at 17:05, on Zulip):

So no more Default bound on AllocationExtra

oli (Nov 13 2018 at 17:05, on Zulip):

Seems nicely symmetric with the deallocate hook

oli (Nov 13 2018 at 17:07, on Zulip):

If you need access to the allocation itself during the allocate hook, pass an allocation with the empty tuple as AllocExtra

RalfJ (Nov 14 2018 at 08:18, on Zulip):

So you want every AllocExtra to carry a pointer to the MemoryData? Why is that better than passing in a pointer on every read/write/dealloc? Passing in &() does not seem too bad?

oli (Nov 14 2018 at 08:23, on Zulip):

well... every call from within miri-engine and miri is already given a tcx, now a &MemoryData, too... these arguments are just noise. Maybe we can make get and get_mut return a wrapper around Allocation which has the same methods as Allocation but without the extra arguments

RalfJ (Nov 14 2018 at 08:40, on Zulip):

I do like not using Default, I got some use for that, but I don't like that extra ptr-sized overhead of memory use everywhere. Hm.

RalfJ (Nov 14 2018 at 08:58, on Zulip):

but maybe I am overthinking it and one more ptr size per allocation is not worth the effort?

oli (Nov 14 2018 at 08:59, on Zulip):

It's either complexity at every memory operation site or an Rc in the structure + one Mutex check per memory operation

oli (Nov 14 2018 at 09:00, on Zulip):

the complexity at every operation site can be solved by making get and get_mut return a wrapper around Allocation

oli (Nov 14 2018 at 09:01, on Zulip):

Are you planning on trying to get stacked borrows into const eval $ever?

oli (Nov 14 2018 at 09:02, on Zulip):

If not, then I think we should go with the extra Rc in miri

RalfJ (Nov 14 2018 at 09:08, on Zulip):

Not sure about $ever, but it'd probably kill compile times...

RalfJ (Nov 14 2018 at 09:08, on Zulip):

okay I will go with Rc for now

RalfJ (Nov 14 2018 at 09:08, on Zulip):

which Mutex?

oli (Nov 14 2018 at 09:22, on Zulip):

Well you need an Rc<Mutex<Data>> otherwise you can't mutate it ;)

oli (Nov 14 2018 at 09:22, on Zulip):

or RefCell

oli (Nov 14 2018 at 09:22, on Zulip):

same thing

RalfJ (Nov 14 2018 at 09:23, on Zulip):

fair enough

RalfJ (Nov 14 2018 at 09:24, on Zulip):

I also think I will actually use a HashSet of unique stack frame identifiers that have NOT been popped yet, that won't grow unboundedly like my original idea would^^

Last update: Apr 03 2020 at 18:10UTC