Live data from Hacker News

Group Borrowing: Zero-cost memory safety with fewer restrictions

verdagon.dev

61–70 of 87 posts

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#61

Earlier quoted context omitted.

Box heap allocates, references do not.

> `&own` references that take ownership of the object and free it when the reference goes out of scope How can you free something if it's not allocated

Sorry, yeah that phrasing was bad: I kinda think an "owning reference" is a contradiction in terms but I didn't come up with the idea.

What I meant was, creating a box creates a new allocation, whereas my understanding of &own would take over an existing allocation.

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#62
post #38

Earlier quoted context omitted.

But how would you prevent use-after-free? In other words, how do you prevent a child object's method from reaching out to its parent object and, say, clearing the container that contains the child object? Specifically, how do you do that without reference counting or garbage collection.

Well the distinction between mutable and immutable borrows doesn't solve use-after-free. What prevents use-after-free is ownership. There is one owner, and the owner can not free the memory as long as there is a borrower (it doesn't matter whether the borrower is mutable or not). So that's the task of the borrow checker. For my own programming language [1], I have only mutable borrowers (similar to Java), and a much…

> There is one owner, and the owner can not free the memory as long as there is a borrower (it doesn't matter whether the borrower is mutable or not). So that's the task of the borrow checker.

Yes, but what about:

``` let mut x = &mut some_vec; some_vec.push(10); ```

Sure the vec has an owner, but the second mutable borrow causes it to invalidate the first pointer. You need a _third_ category, “unstable mut”, which is exclusive as it can cause an object’s internal data to move. You can then collapse mut and immutable to one… but you end up with the exact some colouring problem between unstable mut and the others

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#63

Earlier quoted context omitted.

Drop takes an object itself ("owned reference"), as I remember. Mutable ref allows reading/writing but not destroying or passing the ownership. Owner = can read/write/destroy Mutable ref = can read/write Immutable ref = can only read, guarantered not to change

https://doc.rust-lang.org/stable/std/ops/trait.Drop.html#tym...

That's the destructor function, that is written by you and called by Rust before actually destroying something. The function that you want to look at is [1].

If you read the docs at your link it even says:

> This method is called implicitly when the value goes out of scope, and cannot be called explicitly (this is compiler error E0040).

> However, the mem::drop function in the prelude can be used to call the argument’s Drop implementation.

By the way the implementation of the function drop is just an empty function [2]; that's enough as local variables are destroyed on function return.

Mutable reference is a "borrow" which means you take a value from an owner and promise to return it back, and you cannot destroy a thing that you must return.

[1] https://doc.rust-lang.org/std/mem/fn.drop.html

[2] https://doc.rust-lang.org/src/core/mem/mod.rs.html#957

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#64
post #55

Earlier quoted context omitted.

As I remember, Cell only allows moving/copying data from/to cell so if you have a 128-byte object inside do you have to copy it to modify? Or this can be optimized?

Yes, that's how Cell works. If you want to work with the data in place, you need a RefCell instead.

But it is expensive, because it does run-time checks? Or they are optimized out?

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#65
post #37

Earlier quoted context omitted.

> Also it seems that it requires locking? That's not very good given that locks often need syscalls. AFAIU in most STMs all the fast paths are implemented using lock-free algorithms with just barriers.

How do you implement "commit" part safely (writing changes to the object) without locking the object?

One way is that the writer thread prepares a completely new copy of the object in a private area and then either compare-and-swaps a pointer to it, or executes a store with a store-store barrier (depending on details of the STM system around it).

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#66

Earlier quoted context omitted.

https://doc.rust-lang.org/stable/std/ops/trait.Drop.html#tym...

That's the destructor function, that is written by you and called by Rust before actually destroying something. The function that you want to look at is [1]. If you read the docs at your link it even says: > This method is called implicitly when the value goes out of scope, and cannot be called explicitly (this is compiler error E0040). > However, the mem::drop function in the prelude can be used to call the argument…

The drop function being talked about here is the one I pointed to, not the one you pointed to. The Drop trait is built into the language (as a lang item), std::mem::drop is just a regular old function.

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#67
post #5

Hey all, this is a post explaining a new memory safety model by my friend Nick Smith (original proposal at https://gist.github.com/nmsmith/cdaa94aa74e8e0611221e65db8e4... ) It was interesting enough that I knew I had to write a post about it. Happy to answer any questions!

> But... we humans can easily conclude this is safe. After the evaluation of list_ref_a.push(5), my_list is still there, and it's still in a valid state. So there is no risk of memory errors when evaluating the second call to push. Is the always true? What with piplining, branch prediction, and maybe asymmetrical NUMA , isn't out of order instructions possible? If so, don't you still need locks or memory barriers to…

Hardware-based instruction reordering always preserves the behaviour of the original program. (Assuming the original program is valid.)

For example, an Intel CPU won't reorder `x += 1` and `x *= 2`.

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#68
post #33
post #24

In memory-safety discussions it needs to be borne in mind that 'simply fix the hardware' is also a viable approach; or at least it's a lot more viable than it was or seemed to be a few decades ago https://en.wikipedia.org/wiki/Capability_Hardware_Enhanced_R... . Memory-safe BSD and applications running on real memory-safe RISC-V hardware apparently already exist, though obviously, yes, even in a best case existing ar…

True. To be fair, CHERI guarantees only security, while borrow checking (when it works) guarantees both security and correctness. If you write to a freed pointer or out-of-bounds, CHERI guarantees that your write either crashes or lands somewhere harmless, rather than corrupting other data. But borrow checking guarantees you won't perform such writes in the first place. Yet while correctness may excite programmers, i…

Yes but CHERI is supposed to work for every application, not only Rust, but your favourite game from Windows 95 era as well.

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#69
post #57
post #7

> Because of those "inaccessible" rules, we can never have a readwrite reference and a readonly reference to an object at the same time. I can't not see this as a good thing. It's almost at the level of "the only thing an ownership system does". If my thread is operating on a struct of 4 int64s, do I now have to think about another read-only thread seeing that struct in an invalid partially-written state?

The "Group Borrowing" concept that we're discussing still imposes aliasing restrictions to prevent unsynchronized concurrent access, and also to prevent "unplanned" aliasing. For example, for the duration of a function call, the default restriction is that a mut argument can only be mutated through the argument's identifier. The caller may be holding other aliases, but the callee doesn't need to be concerned about th…

> Borrowing happens for the duration of a function call

I don't understand this part. Cannot a function store a borrowed reference into a structure that outlives the function?

Re: Group Borrowing: Zero-cost memory safety with fewer restrictions

#70
post #65

Earlier quoted context omitted.

How do you implement "commit" part safely (writing changes to the object) without locking the object?

One way is that the writer thread prepares a completely new copy of the object in a private area and then either compare-and-swaps a pointer to it, or executes a store with a store-store barrier (depending on details of the STM system around it).

Interesting, it's almost like immutable data structures.
Post reply on HN