Skip to content

Comments

Make allocate @safe#5879

Closed
edi33416 wants to merge 1 commit intodlang:masterfrom
edi33416:safe_alloc_allocate
Closed

Make allocate @safe#5879
edi33416 wants to merge 1 commit intodlang:masterfrom
edi33416:safe_alloc_allocate

Conversation

@edi33416
Copy link
Contributor

For allocators that implement their own allocate method, this should be a pure nothrow @safe function.
Allocators that are building on top of such allocators should infer the function attributes from their parents.

This PR is a subset of #5330, as this approach will provide us with better granularity. More smaller PRs to come :)

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @edi33416! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.

Some tips to help speed things up:

  • smaller, focused PRs are easier to review than big ones

  • try not to mix up refactoring or style changes with bug fixes or feature enhancements

  • provide helpful commit messages explaining the rationale behind each change

Bear in mind that large or tricky changes may require multiple rounds of review and revision.

Please see CONTRIBUTING.md for more information.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

static if (stateSize!Prefix)
{
assert(result.ptr.alignedAt(Prefix.alignof));
emplace!Prefix(cast(Prefix*) result.ptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that it's safe to write over result. As far as I see, you can't assume that. Every array type implicitly converts to void[], so it's possible that parent.allocate returns memory that's already used elsewhere, differently typed.

Same with Suffix below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it safe to assume that parent.allocate will return fresh memory? Imho, allocate should always return fresh memory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it safe to assume that parent.allocate will return fresh memory?

No. parent is provided by the user. You can't assume anything about it beyond what is guaranteed/required by the language.

It might be possible to check if the return value is unique. Then you can rely on that. But you have to check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is problematic. We may need to replace the result of allocate with ubyte[] everywhere, or give up on making allocate safe for this allocator.

@andralex
Copy link
Member

@edi33416 I suggest for now let's leave AffixAllocator with an unsafe allocate.


// Check that goodAllocSize inherits from parent, i.e. GCAllocator
assert(__traits(compiles, (() nothrow @safe @nogc => a.goodAllocSize(1))()));
assert(__traits(compiles, (() @nogc => a.goodAllocSize(1))()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an anti-pattern. Get rid of the __traits(compiles here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wilzbach What is the preferred alternative to __traits(compiles, ...)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a.goodAllocSize(1) and if don't want to call it, simply put it in a function or lambda which isn't called. It looks a lot nicer to read and has the same effect and for the main reason you see the error messages e.g. if you decide to refactor your codebase.

FWIW it should have been static assert too.

auto b = a.allocate(42);
assert(b.length == 42);
() nothrow @nogc { a.deallocate(b); }();
() @trusted @nogc { a.deallocate(b); }();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did the nothrow go? And better wrap the specific part in an @safe lambda than spreading @trusted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did the nothrow go?

I changed the unittest to nothrow @safe

And better wrap the specific part in an @safe lambda than spreading @trusted

What do you mean?

}

bool failedNewAlloc = false;
mixin(q{() } ~ trusted_ ~ q{ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do this without a mixin, by simply doing sth. like

static if (<checkWhetherItCanBeTrusted>) 
   () @trusted { callFun() }();
else
   callFun();

metadata.
*/
@trusted void[] allocate(const size_t s)
pure nothrow @trusted @nogc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can this @trusted? (Please don't slap @trusted on functions.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was made @trusted before. I just added pure nothrow @nogc.
Should I make this @safe and add @trusted lambdas inside?

/**
Directs the call to either one of the $(D buckets) allocators.
*/
//pure nothrow @safe @nogc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO?

static if (hasMember!(ParentAllocator, "deallocate"))
{
clear;
() @trusted { clear; }();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about making the function @safe instead of blindly trusting it?

assert(b1.length == 10000);
assert(b2.length == 20000);
assert(b3.length == 30000);
() @trusted @nogc { a.deallocate(b1); }();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close lambda and open it three lines later ;-)

assert(b.length == 42);
// Ensure deallocate inherits from parent
() nothrow @nogc { a.deallocate(b); }();
() @trusted nothrow @nogc { a.deallocate(b); }();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could have wrapped the other block in an @safe lambda ...

version(Posix)
{
/// Allocator API.
@trusted @nogc nothrow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't apply @trusted to entire functions.

PAGE_READWRITE, MEM_RELEASE;

/// Allocator API.
@trusted @nogc nothrow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't apply @trusted to entire functions.

@wilzbach
Copy link
Contributor

wilzbach commented Dec 1, 2017

@edi33416 I recommend splitting this PR up into smaller chunks, s.t. it can be reviewed and merged more quickly. As an additional benefit your chances of running into merge conflicts decrease too ;-)

@andralex
Copy link
Member

andralex commented Dec 6, 2017

Per the convo with @edi33416 today, please convert this diff to making allocate only nothrow and (where applicable) @nogc.

@wilzbach
Copy link
Contributor

Ping @edi33416

@RazvanN7
Copy link
Collaborator

RazvanN7 commented Oct 22, 2021

@edi33416 Any chance of finishing this?

@LightBender LightBender added the Review:Phantom Zone Has value/information for future work, but closed for now label Oct 26, 2024
@LightBender
Copy link
Contributor

PR closed as stalled. If you wish to resurrect it you are welcome to do so. We will look into this in Phobos 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Merge:Needs Rebase Merge:stalled Review:Needs Work Review:Phantom Zone Has value/information for future work, but closed for now

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants