On 9/19/2016 7:04 AM, Andrei Alexandrescu wrote:
On 09/19/2016 01:16 AM, Walter Bright wrote:
The compiler currently creates the complete object file in a buffer,
then writes the buffer to a file in one command. The reason is mostly
because the object file format isn't incremental, the beginning is
written last and the body gets backpatched as the compilation progresses.
Great. In that case, if the target .o file already exists, it should be compared
against the buffer. If identical, there should be no write and the timestamp of
the .o file should stay the same.


That's right. I was just referring to the idea of incrementally writing and comparing, which is a great idea for sequential file writing, likely won't work for the object file case. I think it is distinct enough to merit a separate library function. Note that we already have:

    http://dlang.org/phobos/std_file.html#.write

Adding another "writeIfDifferent()" function would be a good thing. The range based incremental one should go into std.stdio.

Any case where writing is much more costly than reading (such as SSD drives you mentioned, and the new Seagate "archival" drives), would make your technique a good one. It works even for memory; I've used it in code to reduce swapping, as in:

    if (*p != newvalue) *p = newvalue;

I need to re-emphasize this kind of stuff is important for tooling. Many files
get recompiled to identical object files - e.g. the many innocent bystanders in
a dense dependency structure when one module changes. We also embed
documentation in source files. Being disciplined about reflecting actual changes
in the actual file operations is very helpful for tools that track file writes
and/or timestamps.

That's right.


I can't really see a compilation producing an object file where the
first half of it matches the previous object file and the second half is
different, because of the file format.

Interesting. What happens e.g. if one makes a change to a function whose
generated code is somewhere in the middle of the object file? If it doesn't
alter the call graph, doesn't the new .o file share a common prefix with the old
one?

Two things:

1. The object file starts out with a header that contains file offsets to the various tables and sections. Changing the size of any of the pieces in the file changes the header, and will likely require moving pieces around to make room.

2. Writing an object file can mean "backpatching" what was written earlier, as a declaration one assumed was external turns out to be internal.

Reply via email to