December 18, 2012
12/18/2012 6:51 PM, Walter Bright пишет:
> On 12/18/2012 1:33 AM, Dmitry Olshansky wrote:
>> More then that - the end result is the same: to avoid carrying junk
>> into an app
>> you (or compiler) still have to put each function in its own section.
>
> That's what COMDATs are.
>
Okay..

>> Doing separate compilation I always (unless doing LTO or template
>> heavy code)
>> see either whole or nothing (D included). Most likely the compiler
>> will do it
>> for you only with a special switch.
>
> dmd emits COMDATs for all global functions.
>
> You can see this by running dumpobj on the output.

Thanks for carrying on this Q.

I'm using objconv by Agner Fog as I haven't got dumpobj (guess I'll buy it if need be). However I see comments in dumped asm  that mark section boundaries that all functions are indeed in COMDAT sections.

Still linking these object files and disassembling output I see all of functions are there intact. I've added debug symbols to the build though - could it make optlink keep symbols?

After dropping debug info I can't yet make heads or tails of what's in the exe yet but it _seems_ to not include all of the unused code. Gotta investigate on a smaller sample.

-- 
Dmitry Olshansky
December 18, 2012
On 12/18/2012 8:48 AM, Dmitry Olshansky wrote:
> After dropping debug info I can't yet make heads or tails of what's in the exe
> yet but it _seems_ to not include all of the unused code. Gotta investigate on a
> smaller sample.

Generate a linker .map file (-map to dmd). That'll tell you what's in it.

December 18, 2012
On Tue, Dec 18, 2012 at 09:55:57AM -0800, Walter Bright wrote:
> On 12/18/2012 9:42 AM, H. S. Teoh wrote:
> >I was thinking more along the lines of things like fully automatic purity, safety, exception inference. For example, every function body eventually has to be processed by the compiler, so if a particular function is inferred to throw exception X, for example, then when its callers are compiled, this fact can be propagated to them. To do this for the whole program might be infeasible due to the sheer size of things, but if a module contains, for each function exposed by the API, a list of all thrown exceptions, then when the module is imported this information is available up-front and can be propagated further up the call chain. Same thing goes with purity and @safe.
> >
> >This may even allow us to make pure/@safe/nothrow fully automated so that you don't have to explicitly state them (except when you want the compiler to verify that what you wrote is actually pure, safe, etc.).
> 
> The trouble with this is the separate compilation model. If the attributes are not in the function signature, then the function implementation can change without recompiling the user of that function. Changing the inferred attributes then will subtly break your build.

And here's a reason for using an intermediate format (whether it's bytecote or just plain serialized AST or something else, is irrelevant). Say we put the precompiled module in a zip file of some sort.  If the function attributes change, so does the zip file. So if proper make dependencies are setup, this will automatically trigger the recompilation of whoever uses the module.


> Inferred attributes only work when the implementation source is guaranteed to be available, such as with template functions.
> 
> Having a binary format doesn't change this.

Actually, this doesn't depend on the format being binary. You can save everything in plain text format and it will still work. In fact, there might be reasons to want a text format instead of binary, since then one could look at the compiler output to find out what the inferred attributes of a particular declaration are without needing to add compiler querying features.


T

-- 
Why have vacation when you can work?? -- EC
December 18, 2012
On 2012-12-18 17:48, Dmitry Olshansky wrote:

> I'm using objconv by Agner Fog as I haven't got dumpobj (guess I'll buy
> it if need be).

dumpobj is included in the DMD release, at least on Mac OS X.

-- 
/Jacob Carlborg
December 18, 2012
12/19/2012 12:01 AM, Jacob Carlborg пишет:
> On 2012-12-18 17:48, Dmitry Olshansky wrote:
>
>> I'm using objconv by Agner Fog as I haven't got dumpobj (guess I'll buy
>> it if need be).
>
> dumpobj is included in the DMD release, at least on Mac OS X.
>
And linux has it. Guess Windows sucks ...

-- 
Dmitry Olshansky
December 18, 2012
Am 18.12.2012 21:09, schrieb Dmitry Olshansky:
> 12/19/2012 12:01 AM, Jacob Carlborg пишет:
>> On 2012-12-18 17:48, Dmitry Olshansky wrote:
>>
>>> I'm using objconv by Agner Fog as I haven't got dumpobj (guess I'll buy
>>> it if need be).
>>
>> dumpobj is included in the DMD release, at least on Mac OS X.
>>
> And linux has it. Guess Windows sucks ...
>

dumpbin
December 18, 2012
On 12/18/2012 11:23 AM, H. S. Teoh wrote:
> On Tue, Dec 18, 2012 at 09:55:57AM -0800, Walter Bright wrote:
>> On 12/18/2012 9:42 AM, H. S. Teoh wrote:
>>> I was thinking more along the lines of things like fully automatic
>>> purity, safety, exception inference. For example, every function body
>>> eventually has to be processed by the compiler, so if a particular
>>> function is inferred to throw exception X, for example, then when its
>>> callers are compiled, this fact can be propagated to them. To do this
>>> for the whole program might be infeasible due to the sheer size of
>>> things, but if a module contains, for each function exposed by the
>>> API, a list of all thrown exceptions, then when the module is
>>> imported this information is available up-front and can be propagated
>>> further up the call chain. Same thing goes with purity and @safe.
>>>
>>> This may even allow us to make pure/@safe/nothrow fully automated so
>>> that you don't have to explicitly state them (except when you want
>>> the compiler to verify that what you wrote is actually pure, safe,
>>> etc.).
>>
>> The trouble with this is the separate compilation model. If the
>> attributes are not in the function signature, then the function
>> implementation can change without recompiling the user of that
>> function. Changing the inferred attributes then will subtly break
>> your build.
>
> And here's a reason for using an intermediate format (whether it's
> bytecote or just plain serialized AST or something else, is irrelevant).
> Say we put the precompiled module in a zip file of some sort.  If the
> function attributes change, so does the zip file. So if proper make
> dependencies are setup, this will automatically trigger the
> recompilation of whoever uses the module.

Relying on a makefile being correct does not solve it.


>> Inferred attributes only work when the implementation source is
>> guaranteed to be available, such as with template functions.
>>
>> Having a binary format doesn't change this.
>
> Actually, this doesn't depend on the format being binary. You can save
> everything in plain text format and it will still work. In fact, there
> might be reasons to want a text format instead of binary, since then one
> could look at the compiler output to find out what the inferred
> attributes of a particular declaration are without needing to add
> compiler querying features.

The "plain text format" that works is called D source code :-)

December 19, 2012
12/19/2012 12:15 AM, Paulo Pinto пишет:
> Am 18.12.2012 21:09, schrieb Dmitry Olshansky:
>> 12/19/2012 12:01 AM, Jacob Carlborg пишет:
>>> On 2012-12-18 17:48, Dmitry Olshansky wrote:
>>>
>>>> I'm using objconv by Agner Fog as I haven't got dumpobj (guess I'll buy
>>>> it if need be).
>>>
>>> dumpobj is included in the DMD release, at least on Mac OS X.
>>>
>> And linux has it. Guess Windows sucks ...
>>
>
> dumpbin

Only COFF I guess ;)

-- 
Dmitry Olshansky
December 19, 2012
12/18/2012 9:15 PM, Walter Bright пишет:
> On 12/18/2012 8:48 AM, Dmitry Olshansky wrote:
>> After dropping debug info I can't yet make heads or tails of what's in
>> the exe
>> yet but it _seems_ to not include all of the unused code. Gotta
>> investigate on a
>> smaller sample.
>
> Generate a linker .map file (-map to dmd). That'll tell you what's in it.
>
It's rather enlightening especially after running ddemangle over it.

Still it tells only half the story - what symbols are there (and a lot of them shouldn't have been) - now the most important part to figure out is _why_.

Given that almost everything is templates and not instantiated (thus thank god is not present). Still both quite some templates and certain normal functions made it in without ever being called. I'm sure they are not called because I just imported the module. Adding trace prints to the functions in question shows nothing on screen.

I tried running linker with -xref and I see that the stuff I don't expect to land in .exe looks either like this:

 Symbol           Defined           Referenced
immutable(unicode_tables.SetEntry!(ushort).SetEntry) unicode_tables.unicodeCased
                   unicode_tables

(Meaning that it's not referenced anywhere yet present but I guess unreferenced global data is not stripped away)

Or (for functions):

dchar uni.toUpper(dchar)
                   uni               uni

const(@trusted dchar function(uint)) uni.Grapheme.opIndex
                   uni               uni

...

Meaning that it's defined & referenced in the same module only (not the one with empty main). Yet it's getting pulled in... I'm certain that at least toUpper is not called anywhere in the empty module (nor module ctors, as I have none).

Can you recommend any steps to see the web of symbols that eventually pulls them in? Peeking at dependency chain (not file-grained but symbol grained) in any form would have been awesome.

-- 
Dmitry Olshansky
1 2 3 4
Next ›   Last »