assume, assert, enforce, @safe

Artur Skawina via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 31 15:57:57 PDT 2014


On 08/01/14 00:08, Walter Bright via Digitalmars-d wrote:
> On 7/31/2014 9:02 AM, Artur Skawina via Digitalmars-d wrote:
>>>> The solution is to tell the compiler that you really need that newly
>>>> (over-)written data. Eg
>>>>
>>>>      asm {"" : : "m" (*cast(typeof(password[0])[9999999]*)password.ptr); }
>>>
>>> inline asm is not portable
>>
>> That's why a portable compiler barrier interface is needed.
>> But this was just an example showing a zero-cost solution. A portable
>> fallback is always possible (the bug report was about C code -- there,
>> a loop that reads the data and stores a copy into a volatile location
>> would work).
> 
> This is not a "barrier" operation. There you are thinking of atomic operations. This is a case of a "volatile" operation, and this supports it for D:
> 
>   https://github.com/D-Programming-Language/druntime/pull/892

It's a _compiler_ barrier and has nothing to do with atomic ops or
volatile. It simply tells the compiler (in this case) 'i'm going
to read the data in the memory locations pointed to by the password.ptr'.
That means that the compiler has to make sure that the data is there,
before the `asm` executes; it can not assume that the stores are dead
and can not optimize them away. The actual (emitted) asm does nothing.
It's just a way to communicate to the compiler that the data is needed.
Since in this case the point was just to overwrite /other/ security
sensitive data present at this location, nothing else is necessary. We
don't actually care about the new content, we only pretend we do, so
that the compiler isn't able to optimize across this barrier.

Exposing compiler barriers in a portable way in D would definitively be
a good idea. Relatively decent implementations can be easily done, for
example, the above functionality can be achieved via a pure function
that takes a reference to a static array. The function would do nothing,
just immediately return to the caller; it'd just need to be opaque from
the optimizers POV. This version wouldn't be zero-cost, like the example
above, but still very cheap (usually just a call+ret sequence), correct
and enough for many not perf-sensitive use cases like the one described
in that bug report.

artur



More information about the Digitalmars-d mailing list