digitalmars.D - Object.factory() and exe file size bloat
- Walter Bright (10/10) Aug 20 2015 This function:
- Dmitry Olshansky (7/17) Aug 20 2015 +1000 Though I'd kill the whole object factory if I had a chance. It
- deadalnix (3/14) Aug 20 2015 Wait ? Why only classes marked export ? I don't follow the
- H. S. Teoh via Digitalmars-d (11/32) Aug 20 2015 Because if your code imports the module that defines the class, you
- Johannes Pfau (5/41) Aug 21 2015 As Benjamin explained export works on library level, not on module
- BBasile (7/14) Aug 20 2015 This is a good idea. Some other langs use a similar system with a
- Walter Bright (6/8) Aug 20 2015 Interestingly, my idea would not disable TypeInfo generation. Instead, t...
- Mike (11/20) Aug 20 2015 Disabling TypeInfo forces one to compromise on slicing, postblit,
- Walter Bright (2/6) Aug 20 2015 I do plan to do a review of ModuleInfo with this in mind, but not immedi...
- Johannes Pfau (11/21) Aug 21 2015 Right now we use ModuleInfo to iterate all linked modules*. Keeping
- Steven Schveighoffer (5/26) Aug 21 2015 It's used to call static ctor/dtors as well.
- Kagamin (2/3) Aug 21 2015 Why slicing and postblit would need typeinfo?
- Mike (20/24) Aug 21 2015 See below for the source code. Some obvious, some not.
- Johannes Pfau (6/39) Aug 21 2015 It's been some time since I looked at this so I don't remember exactly
- Steven Schveighoffer (7/28) Aug 21 2015 You need some static data to hold the vtable. I think typeinfo is fine
- Iain Buclaw via Digitalmars-d (18/45) Aug 21 2015 Where removing RTTI disables D feature's in a compromising way, I'd star...
- Steven Schveighoffer (10/25) Aug 21 2015 I strongly suggest we *don't* go this route. This means that any changes...
- Dicebot (4/9) Aug 21 2015 It needs to be trivial wrapper which forwards to proposed
- Steven Schveighoffer (4/12) Aug 21 2015 Sure:
- Dicebot (4/7) Aug 21 2015 Btw, are `pragma(inline, true)` function actually guaranteed to
- Steven Schveighoffer (6/14) Aug 21 2015 I have no idea. It probably should be guaranteed, because what is the
- Dicebot (11/14) Aug 21 2015 If it is guaranteed, almost makes me want to abuse it for this:
- Iain Buclaw via Digitalmars-d (4/17) Aug 21 2015 That enforces that foo() is always folded at compile time, not always
- Dicebot (7/22) Aug 21 2015 And when you combine both you gets function that is always folded
- Walter Bright (3/6) Aug 21 2015 They are emitted as COMDATs, and as such are not emitted to the binary (...
- Iain Buclaw via Digitalmars-d (10/19) Aug 21 2015 For compilers other than DMD, their code needs to be generated to allow ...
- Johannes Pfau (7/11) Aug 22 2015 This really should be documented then. If we build a shared library
- Iain Buclaw via Digitalmars-d (8/19) Aug 22 2015 I wouldn't go as far as preventing these functions from having their
- Johannes Pfau (3/31) Aug 22 2015 That's indeed a better solution.
- Walter Bright (2/3) Aug 22 2015 And it is.
- Iain Buclaw via Digitalmars-d (4/35) Aug 22 2015 I only looked at 2.066.1, the runtime implementation did not pass the
- Mike (5/16) Aug 26 2015 _d_arrayliteralTX eventually calls structTypeInfoSize() which,
- Iain Buclaw via Digitalmars-d (4/23) Aug 26 2015 Well, I have no control over what the library maintainers in DMD want to...
- Steven Schveighoffer (3/22) Aug 27 2015 The change was to make it so struct dtors are called by the GC.
- Kagamin (5/11) Aug 21 2015 Looks like these are generated for fixed sized array of structs
- Johannes Pfau (15/29) Aug 22 2015 If you do
- Andrei Alexandrescu (5/30) Aug 21 2015 Thanks for this list. I think these need to be fixed (by replacing
- Martin Nowak (3/8) Aug 22 2015 Yes, it's a major pain and a source for many incorrect attributes.
- Mike (233/238) Aug 22 2015 For whatever it's worth, below is a list of druntime functions
- deadalnix (3/7) Aug 21 2015 Because the runtime implementation is broken and rely on it
- sclytrack (9/20) Aug 20 2015 1. "Since it is compiled in the {$M+} state, the compiler
- Paolo Invernizzi (2/13) Aug 20 2015 +1000!
- Rikki Cattermole (11/21) Aug 20 2015 I need to look over my code that I've written for my to be web
- Rikki Cattermole (8/39) Aug 23 2015 I've had a look at it finally. This would definitely effect me.
- Jacob Carlborg (12/22) Aug 20 2015 I think, or rather know, that this will break serialization, i.e. my
- Walter Bright (12/20) Aug 21 2015 A large purpose of starting this thread is to find out in advance what s...
- Dicebot (30/36) Aug 23 2015 This is fundamentally flawed way of thinking which only confirms
- Walter Bright (6/27) Aug 23 2015 I agree the cost is small, but the benefit is zero. Yes, I understand yo...
- Benjamin Thaut (34/45) Aug 21 2015 I don't think this is a good idea. That's just abusing a already
- Jacob Carlborg (8/11) Aug 21 2015 How is it limiting? That it only works with default constructors? I
- Benjamin Thaut (10/15) Aug 21 2015 Yes, the usual problem was that it only works with default
- Jacob Carlborg (5/14) Aug 21 2015 It sounds like both of these could be fixed. BTW, in my serialization
- Johannes Pfau (4/7) Aug 21 2015 +1. I think we should be very careful when reusing a keyword which
- Walter Bright (3/5) Aug 21 2015 Object.factory() only has a point when it is used to instantiate classes...
- Dmitry Olshansky (6/12) Aug 21 2015 Still abusing visibility keyword is probably bad idea, it's already
- Jacob Carlborg (4/6) Aug 21 2015 It's useful for deserialization as well.
- Dicebot (4/9) Aug 21 2015 Btw we use it for high-level testing framework - will be rather
- Walter Bright (3/13) Aug 21 2015 Bugzilla issues? (You knew that was coming!)
- Dicebot (12/18) Aug 22 2015 If you want details it is special library for black box testing
- Walter Bright (3/21) Aug 22 2015 Thanks!
- David Nadlinger (7/8) Aug 22 2015 One of the use cases for export on Linux would be to set the ELF
- Walter Bright (2/8) Aug 22 2015 A bugzilla enhancement request for this would be nice.
- David Nadlinger (3/12) Aug 22 2015 https://issues.dlang.org/show_bug.cgi?id=9893
- Adam D. Ruppe (5/7) Aug 22 2015 The common saying "if it isn't in bugzilla it is forgotten" seems
- Walter Bright (7/9) Aug 22 2015 Lots of people, like Daniel and Kenji and Vladimir and Martin, etc., go ...
- Benjamin Thaut (7/16) Aug 23 2015 The good news is, once I'm done with my windows DLL work the code
- Rikki Cattermole (3/8) Aug 23 2015 Wait we are getting almost full blown DLL support on Windows?
- Benjamin Thaut (30/35) Aug 23 2015 But then you have the same problem on linux as on windows.
- Dicebot (4/10) Aug 23 2015 I have always been in support of actually enforcing export on
- Freddy (3/9) Aug 21 2015 Can't we just make that Object.factory() an empty template and
- Kagamin (3/4) Aug 21 2015 Isn't typeinfo referenced from vtbl? So as long as the class is
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/17) Aug 21 2015 Just change Object.factory to require registration of the class.
- Walter Bright (2/3) Aug 21 2015 What mechanism do you propose for that?
- deadalnix (2/7) Aug 21 2015 http://forum.dlang.org/post/fxansmxbiobeshefszlm@forum.dlang.org
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (19/24) Aug 22 2015 E.g.:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (10/11) Aug 22 2015 E.g.:
- Vladimir Panteleev (8/19) Aug 21 2015 An alternative which would be more work but wouldn't break code
- Andrei Alexandrescu (3/13) Aug 21 2015 Knee-jerk reaction: sensible and meaningful, but we need to make a good
- tcak (4/4) Aug 21 2015 How expensive putting a flag for the compiler?
- Walter Bright (10/12) Aug 21 2015 The case is:
- deadalnix (26/41) Aug 21 2015 That sound reasonable and I advocated for changing Object.factory
- Walter Bright (3/4) Aug 21 2015 It's a good idea, but is still equivalent to manually annotating the cla...
- deadalnix (2/7) Aug 21 2015 Breaking the code must be worth it.
- rsw0x (3/20) Aug 21 2015 +1, this seems like a great solution.
- Jacob Carlborg (7/10) Aug 23 2015 A always thought of D as a bit more convenient language. Variables are
- ponce (6/7) Aug 21 2015 Do function pointer types also have TypeInfo? Derelict libraries
- Walter Bright (2/4) Aug 21 2015 Compile with -map and check to see what winds up in the binary.
- bitwise (14/31) Aug 21 2015 Can't this be optional?
- Jonathan M Davis (11/12) Aug 21 2015 Well, one suggestion would be to simply version Object.factory so
- Martin Nowak (16/19) Aug 22 2015 The export seems to be an arbitrary rule (and export is really
- Benjamin Thaut (4/19) Aug 23 2015 How do you implement weak linking? It would be really usefull for
- Walter Bright (3/5) Aug 23 2015 I've always had trouble with linker bugs when using weak linking, to the...
- Manu via Digitalmars-d (5/15) Aug 22 2015 I don't follow the reasoning, but yes! Kill it with fire!
- rsw0x (3/10) Aug 22 2015 rtti is used heavily in the runtime hooks, this needs to be fixed
- Jacob Carlborg (6/15) Aug 23 2015 If we're actually going to talk about solution then it seems better to
- w0rp (6/6) Aug 25 2015 I think this is another case where Walter has got it right, by
- Jacob Carlborg (5/11) Aug 25 2015 I'm been doing that and I get a lot of complains from developers how
- Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d (4/16) Aug 25 2015 As a library author (ideal case) you need to support both, some stable
This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?
Aug 20 2015
On 21-Aug-2015 08:06, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?+1000 Though I'd kill the whole object factory if I had a chance. It looks a lot like Java-woannabe feature that may be better done with UDA's and meta-programming (like e.g. run--time type info can be based on compile-time one). -- Dmitry Olshansky
Aug 20 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Wait ? Why only classes marked export ? I don't follow the reasoning here.
Aug 20 2015
On Fri, Aug 21, 2015 at 05:15:00AM +0000, deadalnix via Digitalmars-d wrote:On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:Because if your code imports the module that defines the class, you already know the class name (either by design, or by compile-time introspection) so you don't need to use the object factory. It's only when you want to dynamically load new classes at runtime that you didn't know about at compile-time, that you need to use the object factory -- and that's also when you'd mark classes as 'export'. Makes sense to me. T -- Windows: the ultimate triumph of marketing over technology. -- Adrian von BidderThis function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Wait ? Why only classes marked export ? I don't follow the reasoning here.
Aug 20 2015
Am Thu, 20 Aug 2015 22:21:30 -0700 schrieb "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com>:On Fri, Aug 21, 2015 at 05:15:00AM +0000, deadalnix via Digitalmars-d wrote:As Benjamin explained export works on library level, not on module level. You export from a library (DLL/.so) not from a module, so the analogy with D's 'import' is flawed.On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:Because if your code imports the module that defines the class, you already know the class name (either by design, or by compile-time introspection) so you don't need to use the object factory. It's only when you want to dynamically load new classes at runtime that you didn't know about at compile-time, that you need to use the object factory -- and that's also when you'd mark classes as 'export'. Makes sense to me. TThis function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Wait ? Why only classes marked export ? I don't follow the reasoning here.
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it: [...] What do you think?This is a good idea. Some other langs use a similar system with a registration. Eg instances can only be streamed if type is registered. Other alternatives would be a pragma or an attribute to disable TypeInfo generation. NoTI.
Aug 20 2015
On 8/20/2015 10:24 PM, BBasile wrote:Other alternatives would be a pragma or an attribute to disable TypeInfo generation.Interestingly, my idea would not disable TypeInfo generation. Instead, the TypeInfo would be generated into a COMDAT section. Then, only if it is referenced is it linked in. The ModuleInfo, as it currently is implemented, contains a reference to every class TypeInfo, thus pulling them all in.
Aug 20 2015
On Friday, 21 August 2015 at 05:35:21 UTC, Walter Bright wrote:On 8/20/2015 10:24 PM, BBasile wrote:Disabling TypeInfo forces one to compromise on slicing, postblit, and potentially others useful features, so finding a way to keep TypeInfo, yet remove the dead code is much less of a blunt instrument, and very much preferred.Other alternatives would be a pragma or an attribute to disable TypeInfo generation.Interestingly, my idea would not disable TypeInfo generation. Instead, the TypeInfo would be generated into a COMDAT section. Then, only if it is referenced is it linked in.The ModuleInfo, as it currently is implemented, contains a reference to every class TypeInfo, thus pulling them all in.Ideally it would be nice to only pull in those ModuleInfo instances that are actually needed in the program, and by association, only pull in those TypeInfo instances needed by the ModuleInfo. If no ModuleInfo is used, and the associated TypeInfo is also not used, then neither is pulled in. Mike
Aug 20 2015
On 8/20/2015 11:00 PM, Mike wrote:Ideally it would be nice to only pull in those ModuleInfo instances that are actually needed in the program, and by association, only pull in those TypeInfo instances needed by the ModuleInfo. If no ModuleInfo is used, and the associated TypeInfo is also not used, then neither is pulled in.I do plan to do a review of ModuleInfo with this in mind, but not immediately.
Aug 20 2015
Am Thu, 20 Aug 2015 23:16:10 -0700 schrieb Walter Bright <newshound2 digitalmars.com>:On 8/20/2015 11:00 PM, Mike wrote:Right now we use ModuleInfo to iterate all linked modules*. Keeping modules but removing the ModuleInfo seems irreconcilable with that use case? Of course completely removing a module could work. *: foreach(mod; ModuleInfo) is used in * druntime to run unittests for all modules * gdc druntime to find all modules with TLS variables for emulated TLS support * IIRC also somehow used in dynamic shared library loading/unloading?Ideally it would be nice to only pull in those ModuleInfo instances that are actually needed in the program, and by association, only pull in those TypeInfo instances needed by the ModuleInfo. If no ModuleInfo is used, and the associated TypeInfo is also not used, then neither is pulled in.I do plan to do a review of ModuleInfo with this in mind, but not immediately.
Aug 21 2015
On 8/21/15 6:59 AM, Johannes Pfau wrote:Am Thu, 20 Aug 2015 23:16:10 -0700 schrieb Walter Bright <newshound2 digitalmars.com>:It's used to call static ctor/dtors as well. I think for modules that have none of these features, you could omit the ModuleInfo. -SteveOn 8/20/2015 11:00 PM, Mike wrote:Right now we use ModuleInfo to iterate all linked modules*. Keeping modules but removing the ModuleInfo seems irreconcilable with that use case? Of course completely removing a module could work. *: foreach(mod; ModuleInfo) is used in * druntime to run unittests for all modules * gdc druntime to find all modules with TLS variables for emulated TLS support * IIRC also somehow used in dynamic shared library loading/unloading?Ideally it would be nice to only pull in those ModuleInfo instances that are actually needed in the program, and by association, only pull in those TypeInfo instances needed by the ModuleInfo. If no ModuleInfo is used, and the associated TypeInfo is also not used, then neither is pulled in.I do plan to do a review of ModuleInfo with this in mind, but not immediately.
Aug 21 2015
On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:Disabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:See below for the source code. Some obvious, some not. * dynamic cast - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-83bcb64558f947e39f87d7435709dfe7R364 * array literal - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-bed7d2226948b1e098749985d7a60633R2353 * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1 63d02e24318bbR1039, https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-867588d7078efd0364c256152fb5a2e7R2053 * new - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R5091 * AAs - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R10710 * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857 etc... Disabling TypeInfo requires quite a compromise on D's features. I want TypeInfo, I just don't want dead code. MikeDisabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
Am Fri, 21 Aug 2015 11:03:00 +0000 schrieb "Mike" <none none.com>:On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:It's been some time since I looked at this so I don't remember exactly how severe these limitations are. However, it should be noted that not all 'array literals', ... need TypeInfo, only a subset of them does. Some are fixable others (dynamic downcast) probably not.On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:See below for the source code. Some obvious, some not. * dynamic cast - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-83bcb64558f947e39f87d7435709dfe7R364 * array literal - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-bed7d2226948b1e098749985d7a60633R2353 * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039, https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-867588d7078efd0364c256152fb5a2e7R2053 * new - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R5091 * AAs - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R10710 * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857 etc... Disabling TypeInfo requires quite a compromise on D's features. I want TypeInfo, I just don't want dead code. MikeDisabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
On 8/21/15 7:03 AM, Mike wrote:On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:You need some static data to hold the vtable. I think typeinfo is fine to have for this, but I don't think it's actually necessary.On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:See below for the source code. Some obvious, some not. * dynamic cast - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-83bcb64558f947e39f87d7435709dfe7R364Disabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?* array literal - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-bed7d2226948b1e098749985d7a60633R2353 * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039, https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-867588d7078efd0364c256152fb5a2e7R2053 * new - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R5091 * AAs - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R10710 * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857These are all runtime limitations rooted in legacy that could be lifted. If druntime was just hooks that the compiler called with the type as a template parameter, we could fix all this. -Steve
Aug 21 2015
On 21 August 2015 at 13:03, Mike via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:Where removing RTTI disables D feature's in a compromising way, I'd start by questioning the why. Eg: Why does array literals need RTTI? Looking at _d_arrayliteralTX implementation, it only does the following with the given TypeInfo provided: - Get the array element size (this is known at compile time) - Get the array element type flags (calculated during the codegen stage, but otherwise known at compile time) - Test if the TypeInfo is derived from TypeInfo_Shared (can be done at - you guessed it - compile time by peeking through the baseClass linked list for a given TypeInfo type we are passing). So we have this function that accepts a TypeInfo, but doesn't really *need* to at all. void* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool isshared); Just putting it out there.... Iain.On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:See below for the source code. Some obvious, some not. * dynamic cast - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-83bcb64558f947e39f87d7435709dfe7R364 * array literal - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-bed7d2226948b1e098749985d7a60633R2353 * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039, https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-867588d7078efd0364c256152fb5a2e7R2053 * new - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R5091 * AAs - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R10710 * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857 etc... Disabling TypeInfo requires quite a compromise on D's features. I want TypeInfo, I just don't want dead code.Disabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
On 8/21/15 7:22 AM, Iain Buclaw via Digitalmars-d wrote:Where removing RTTI disables D feature's in a compromising way, I'd start by questioning the why. Eg: Why does array literals need RTTI? Looking at _d_arrayliteralTX implementation, it only does the following with the given TypeInfo provided: - Get the array element size (this is known at compile time) - Get the array element type flags (calculated during the codegen stage, but otherwise known at compile time) - Test if the TypeInfo is derived from TypeInfo_Shared (can be done at - you guessed it - compile time by peeking through the baseClass linked list for a given TypeInfo type we are passing). So we have this function that accepts a TypeInfo, but doesn't really *need* to at all. void* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool isshared); Just putting it out there....I strongly suggest we *don't* go this route. This means that any changes to what is required for the runtime to properly construct an array requires a compiler change. A MUCH better solution: T[] _d_arrayliteral(T)(size_t length) Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature. -Steve
Aug 21 2015
On Friday, 21 August 2015 at 11:34:58 UTC, Steven Schveighoffer wrote:A MUCH better solution: T[] _d_arrayliteral(T)(size_t length)It needs to be trivial wrapper which forwards to proposedvoid* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool isshared);Otherwise you get another binary bloat issue.
Aug 21 2015
On 8/21/15 7:39 AM, Dicebot wrote:On Friday, 21 August 2015 at 11:34:58 UTC, Steven Schveighoffer wrote:Sure: pragma(inline, true) T[] _d_arrayliteral(T)(size_t length) -SteveA MUCH better solution: T[] _d_arrayliteral(T)(size_t length)It needs to be trivial wrapper which forwards to proposedvoid* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool isshared);Otherwise you get another binary bloat issue.
Aug 21 2015
On Friday, 21 August 2015 at 11:48:12 UTC, Steven Schveighoffer wrote:Sure: pragma(inline, true) T[] _d_arrayliteral(T)(size_t length) -SteveBtw, are `pragma(inline, true)` function actually guaranteed to not have own code gen? :)
Aug 21 2015
On 8/21/15 7:57 AM, Dicebot wrote:On Friday, 21 August 2015 at 11:48:12 UTC, Steven Schveighoffer wrote:I have no idea. It probably should be guaranteed, because what is the point of having an "always inlined" function that generates it's own code? But if you took the address of it, it would need the code to be generated. Not sure what happens there, probably should be an error. -SteveSure: pragma(inline, true) T[] _d_arrayliteral(T)(size_t length) -SteveBtw, are `pragma(inline, true)` function actually guaranteed to not have own code gen? :)
Aug 21 2015
On Friday, 21 August 2015 at 12:41:17 UTC, Steven Schveighoffer wrote:I have no idea. It probably should be guaranteed, because what is the point of having an "always inlined" function that generates it's own code?If it is guaranteed, almost makes me want to abuse it for this: pragma(inline, true) string foo() { if (!__ctfe) assert(false); // ... } (for compilers other than LDC)
Aug 21 2015
On 21 August 2015 at 14:43, Dicebot via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Friday, 21 August 2015 at 12:41:17 UTC, Steven Schveighoffer wrote:That enforces that foo() is always folded at compile time, not always inlined, no?I have no idea. It probably should be guaranteed, because what is the point of having an "always inlined" function that generates it's own code?If it is guaranteed, almost makes me want to abuse it for this: pragma(inline, true) string foo() { if (!__ctfe) assert(false); // ... } (for compilers other than LDC)
Aug 21 2015
On Friday, 21 August 2015 at 13:11:14 UTC, Iain Buclaw wrote:And when you combine both you gets function that is always folded at compile time and does not bloat the generated object file (like it happens right now with CTFE-only functions - they are still emitted to the binary). Win. Of course, with LDC it is not an issue because they got --gc-sections working and CTFE utils get garbage collected :PIf it is guaranteed, almost makes me want to abuse it for this: pragma(inline, true) string foo() { if (!__ctfe) assert(false); // ... } (for compilers other than LDC)That enforces that foo() is always folded at compile time, not always inlined, no?
Aug 21 2015
On 8/21/2015 6:27 AM, Dicebot wrote:And when you combine both you gets function that is always folded at compile time and does not bloat the generated object file (like it happens right now with CTFE-only functions - they are still emitted to the binary). Win.They are emitted as COMDATs, and as such are not emitted to the binary (at least on Windows, where COMDATs actually work).
Aug 21 2015
On 21 August 2015 at 13:57, Dicebot via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Friday, 21 August 2015 at 11:48:12 UTC, Steven Schveighoffer wrote:For compilers other than DMD, their code needs to be generated to allow the backend to inline/optimize calls away - something that I'm pretty sure is not done when calling a pragma(inline, true) function that lives in another module. Other than that, the semantics of pragma(inline, true) should guarantee that the function is never *written* to object file. Regards IainSure: pragma(inline, true) T[] _d_arrayliteral(T)(size_t length) -SteveBtw, are `pragma(inline, true)` function actually guaranteed to not have own code gen? :)
Aug 21 2015
Am Fri, 21 Aug 2015 15:16:01 +0200 schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:Other than that, the semantics of pragma(inline, true) should guarantee that the function is never *written* to object file.This really should be documented then. If we build a shared library with pragma(inline) functions not emitting the function prevents taking the address of that function in all client code. As this is a breaking change to 'normal' inline semantics it needs to be documented. https://github.com/D-Programming-Language/dlang.org/pull/1073
Aug 22 2015
On 22 August 2015 at 11:33, Johannes Pfau via Digitalmars-d < digitalmars-d puremagic.com> wrote:Am Fri, 21 Aug 2015 15:16:01 +0200 schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:I wouldn't go as far as preventing these functions from having their address taken. In that instance, of *course* it needs to be written to object file. But it should be put in COMDAT as each external module that takes its address will have a copy of it. Regards Iain.Other than that, the semantics of pragma(inline, true) should guarantee that the function is never *written* to object file.This really should be documented then. If we build a shared library with pragma(inline) functions not emitting the function prevents taking the address of that function in all client code. As this is a breaking change to 'normal' inline semantics it needs to be documented. https://github.com/D-Programming-Language/dlang.org/pull/1073
Aug 22 2015
Am Sat, 22 Aug 2015 14:47:34 +0200 schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:On 22 August 2015 at 11:33, Johannes Pfau via Digitalmars-d < digitalmars-d puremagic.com> wrote:That's indeed a better solution.Am Fri, 21 Aug 2015 15:16:01 +0200 schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:I wouldn't go as far as preventing these functions from having their address taken. In that instance, of *course* it needs to be written to object file. But it should be put in COMDAT as each external module that takes its address will have a copy of it. Regards Iain.Other than that, the semantics of pragma(inline, true) should guarantee that the function is never *written* to object file.This really should be documented then. If we build a shared library with pragma(inline) functions not emitting the function prevents taking the address of that function in all client code. As this is a breaking change to 'normal' inline semantics it needs to be documented. https://github.com/D-Programming-Language/dlang.org/pull/1073
Aug 22 2015
On 8/22/2015 5:47 AM, Iain Buclaw via Digitalmars-d wrote:But it should be put in COMDATAnd it is.
Aug 22 2015
On 21 August 2015 at 13:35, Steven Schveighoffer via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 8/21/15 7:22 AM, Iain Buclaw via Digitalmars-d wrote:I only looked at 2.066.1, the runtime implementation did not pass the typeinfo to the GC.Where removing RTTI disables D feature's in a compromising way, I'd start by questioning the why. Eg: Why does array literals need RTTI? Looking at _d_arrayliteralTX implementation, it only does the following with the given TypeInfo provided: - Get the array element size (this is known at compile time) - Get the array element type flags (calculated during the codegen stage, but otherwise known at compile time) - Test if the TypeInfo is derived from TypeInfo_Shared (can be done at - you guessed it - compile time by peeking through the baseClass linked list for a given TypeInfo type we are passing). So we have this function that accepts a TypeInfo, but doesn't really *need* to at all. void* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool isshared); Just putting it out there....I strongly suggest we *don't* go this route. This means that any changes to what is required for the runtime to properly construct an array requires a compiler change. A MUCH better solution: T[] _d_arrayliteral(T)(size_t length) Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature.
Aug 22 2015
On Saturday, 22 August 2015 at 10:11:24 UTC, Iain Buclaw wrote:_d_arrayliteralTX eventually calls structTypeInfoSize() which, according to https://github.com/D-Programming-Language/druntime/blob/master/src rt/lifetime.d#L214, is used to determine the size of TypeInfo so it can be stored by the GC, as Steven said. MikeA MUCH better solution: T[] _d_arrayliteral(T)(size_t length) Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature.I only looked at 2.066.1, the runtime implementation did not pass the typeinfo to the GC.
Aug 26 2015
On 26 August 2015 at 15:14, Mike via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Saturday, 22 August 2015 at 10:11:24 UTC, Iain Buclaw wrote: A MUCH better solution:Well, I have no control over what the library maintainers in DMD want to do in their runtime, but all is working fine without doing that in my camp._d_arrayliteralTX eventually calls structTypeInfoSize() which, according to https://github.com/D-Programming-Language/druntime/blob/master/src/rt/lifetime.d#L214, is used to determine the size of TypeInfo so it can be stored by the GC, as Steven said. MikeT[] _d_arrayliteral(T)(size_t length) Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature. I only looked at 2.066.1, the runtime implementation did not pass thetypeinfo to the GC.
Aug 26 2015
On 8/26/15 10:50 AM, Iain Buclaw via Digitalmars-d wrote:On 26 August 2015 at 15:14, Mike via Digitalmars-d <digitalmars-d puremagic.com <mailto:digitalmars-d puremagic.com>> wrote: On Saturday, 22 August 2015 at 10:11:24 UTC, Iain Buclaw wrote: A MUCH better solution: T[] _d_arrayliteral(T)(size_t length) Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature. I only looked at 2.066.1, the runtime implementation did not pass the typeinfo to the GC. _d_arrayliteralTX eventually calls structTypeInfoSize() which, according to https://github..com/D-Programming-Language/druntime/blob/master/src/rt/lifetime.d#L214 <https://github.com/D-Programming-Language/druntime/blob/master/src/rt/lifetime.d#L214>, is used to determine the size of TypeInfo so it can be stored by the GC, as Steven said. Mike Well, I have no control over what the library maintainers in DMD want to do in their runtime, but all is working fine without doing that in my camp.The change was to make it so struct dtors are called by the GC. -Steve
Aug 27 2015
On Friday, 21 August 2015 at 11:03:09 UTC, Mike wrote:* postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039Looks like these are generated for fixed sized array of structs in a struct.* slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857Can't even understand, what is this. Array op? But array ops are handled just above.
Aug 21 2015
Am Fri, 21 Aug 2015 11:46:21 +0000 schrieb "Kagamin" <spam here.lot>:On Friday, 21 August 2015 at 11:03:09 UTC, Mike wrote:If you do 'array[] = n' the compiler calls one of _d_arraysetctor, _d_arraysetassign, _d_arrayassign, _d_arrayctor or _d_arraycopy. http://wiki.dlang.org/Runtime_Hooks The calls basically copy n to the array and call the postblit for every value in array[]. They also call 'TypeInfo.destroy' (destructor) on old values before overwriting. arraycopy doesn't use TypeInfo. The rest could be easily rewritten to be templated* or completely compiler generated. * I'm not sure if we support manually accessing the postblit of a type. OTOH if these functions were templated the compiler would likely emit the correct postblit/destroy calls automatically.* postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039Looks like these are generated for fixed sized array of structs in a struct.* slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857Can't even understand, what is this. Array op? But array ops are handled just above.
Aug 22 2015
On 8/21/15 7:03 AM, Mike wrote:On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:Thanks for this list. I think these need to be fixed (by replacing indirect-calls-based code with templates) regardless of where we go with TypeInfo. There's a fair amount of druntime code that suffers from being written before templates or in avoidance thereof. -- AndreiOn Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:See below for the source code. Some obvious, some not. * dynamic cast - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-83bcb64558f947e39f87d7435709dfe7R364 * array literal - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-bed7d2226948b1e098749985d7a60633R2353 * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039, https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-867588d7078efd0364c256152fb5a2e7R2053 * new - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R5091 * AAs - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R10710 * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857 etc... Disabling TypeInfo requires quite a compromise on D's features. I want TypeInfo, I just don't want dead code. MikeDisabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
On Friday, 21 August 2015 at 13:47:49 UTC, Andrei Alexandrescu wrote:Thanks for this list. I think these need to be fixed (by replacing indirect-calls-based code with templates) regardless of where we go with TypeInfo. There's a fair amount of druntime code that suffers from being written before templates or in avoidance thereof. -- AndreiYes, it's a major pain and a source for many incorrect attributes.
Aug 22 2015
On Friday, 21 August 2015 at 13:47:49 UTC, Andrei Alexandrescu wrote:I think these need to be fixed (by replacing indirect-calls-based code with templates) regardless of where we go with TypeInfo. There's a fair amount of druntime code that suffers from being written before templates or in avoidance thereof. -- AndreiFor whatever it's worth, below is a list of druntime functions that take TypeInfo as a parameter. My immediate need is to make it possible for an -fno-rtti switch to be added to the compiler with as little compromise as possible. In general, I'm not actually trying disable D features, even those that I don't actually need. I only need to remove dead code. If -fno-rtti is the best I can hope for, than I'll take it. Perhaps templating some of these functions will make an -fno-rtti switch more viable. I'm judging from the comments in this thread that there may be additional benefits. Would submitting pull requests towards this goal be a distraction from current priorities? Should I wait until after DDMD is out? Mike \core\memory.d 143 extern (C) void gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow nogc; 364 static void* malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow 390 static BlkInfo qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow 417 static void* calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow 457 static void* realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow 501 static size_t extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) pure nothrow 754 static void addRange( in void* p, size_t sz, const TypeInfo ti = null ) nogc nothrow /* FIXME pure */ \object.d 1761 inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow; 1762 inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow; 1778 int _aaEqual(in TypeInfo tiRaw, in void* e1, in void* e2); 1779 hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow; 2794 extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow; 2795 extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void *arrptr) pure nothrow; 3231 private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow; \core\stdc\stdarg.d 60 void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) 131 void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) 345 void va_arg()(va_list apx, TypeInfo ti, void* parmn) \gc\proxy.d 58 void function(void*, size_t, const TypeInfo ti) gc_addRange; 184 void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow 191 BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow 203 void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow 210 void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow 217 size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow 282 void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow \gcstub\gc.d 65 extern (C) void function(void*, size_t, const TypeInfo ti) gc_addRange; 184 extern (C) void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) 197 extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) 210 extern (C) void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) 223 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) 236 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) 293 extern (C) void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) \rt\arrayassign.d 27 extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) 49 extern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp) 141 extern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp) 167 extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) 205 extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti) 236 extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti) \rt\aaA.d 438 extern (C) inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow 461 extern (C) inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow 567 extern (C) int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2) 597 extern (C) hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow \rt\adi.d 24 extern (C) void[] _adSort(void[] a, TypeInfo ti); 365 extern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti) 386 extern (C) int _adEq2(void[] a1, void[] a2, TypeInfo ti) 415 extern (C) int _adCmp(void[] a1, void[] a2, TypeInfo ti) 445 extern (C) int _adCmp2(void[] a1, void[] a2, TypeInfo ti) \gc\gc.d 484 void *malloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow 516 private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow 546 void *calloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow 578 void *realloc(void *p, size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow 603 private void *reallocNoSync(void *p, size_t size, ref uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow 753 size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow 766 private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow 1178 void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow nogc 1568 void addRange(void *pbot, void *ptop, const TypeInfo ti) nothrow nogc 1826 void* bigAlloc(size_t size, ref size_t alloc_size, uint bits, const TypeInfo ti = null) nothrow \rt\qsort.d 26 extern (C) void[] _adSort(void[] a, TypeInfo ti) 41 extern (C) void[] _adSort(void[] a, TypeInfo ti) 56 extern (C) void[] _adSort(void[] a, TypeInfo ti) 68 private TypeInfo tiglobal; 70 extern (C) void[] _adSort(void[] a, TypeInfo ti) \rt\typeinfo\ti_Aint.d 19 extern (C) void[] _adSort(void[] a, TypeInfo ti); \rt\tracegc.d 87 extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length); 88 extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length); 89 extern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims); 90 extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims); 109 extern (C) void[] _d_newarrayTTrace(string file, int line, string funcname, const TypeInfo ti, size_t length) 125 extern (C) void[] _d_newarrayiTTrace(string file, int line, string funcname, const TypeInfo ti, size_t length) 141 extern (C) void[] _d_newarraymTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t[] dims) 160 extern (C) void[] _d_newarraymiTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t[] dims) 179 extern (C) void* _d_newitemTTrace(string file, int line, string funcname, in TypeInfo ti) 194 extern (C) void* _d_newitemiTTrace(string file, int line, string funcname, in TypeInfo ti) 214 extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf) 274 extern (C) void _d_delstructTrace(string file, int line, string funcname, void** p, TypeInfo_Struct inf) 319 extern (C) void* _d_arrayliteralTX(const TypeInfo ti, size_t length); 322 extern (C) void* _d_arrayliteralTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t length) 358 extern (C) byte[] _d_arraycatT(const TypeInfo ti, byte[] x, byte[] y); 359 extern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs); 361 extern (C) byte[] _d_arraycatTTrace(string file, int line, string funcname, const TypeInfo ti, byte[] x, byte[] y) 378 extern (C) void[] _d_arraycatnTXTrace(string file, int line, string funcname, const TypeInfo ti, byte[][] arrs) 397 extern (C) void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, byte[] y); 398 extern (C) byte[] _d_arrayappendcTX(const TypeInfo ti, ref byte[] px, size_t n); 402 extern (C) void[] _d_arrayappendTTrace(string file, int line, string funcname, const TypeInfo ti, ref byte[] x, byte[] y) 419 extern (C) byte[] _d_arrayappendcTXTrace(string file, int line, string funcname, const TypeInfo ti, ref byte[] px, size_t n) 480 extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p); 481 extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p); 483 extern (C) void[] _d_arraysetlengthTTrace(string file, int line, string funcname, const TypeInfo ti, size_t newlength, void[]* p) 500 extern (C) void[] _d_arraysetlengthiTTrace(string file, int line, string funcname, const TypeInfo ti, size_t newlength, void[]* p) \rt\lifetime.d 180 extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf) 215 size_t structTypeInfoSize(const TypeInfo ti) pure nothrow nogc 269 bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo tinext, size_t oldlength = ~0) pure nothrow 374 size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow 398 size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure trusted 407 BlkInfo __arrayAlloc(size_t arrsize, const TypeInfo ti, const TypeInfo tinext) nothrow pure 421 BlkInfo __arrayAlloc(size_t arrsize, ref BlkInfo info, const TypeInfo ti, const TypeInfo tinext) 631 extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/ 670 package bool hasPostblit(in TypeInfo ti) 675 void __doPostblit(void *ptr, size_t len, const TypeInfo ti) 712 extern(C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* p) 882 extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow 941 extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length) pure nothrow 954 extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow 987 void[] _d_newarrayOpT(alias op)(const TypeInfo ti, size_t[] dims) 1028 extern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims) 1044 extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims) 1413 extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p) 1597 extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p) 1794 extern (C) void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, byte[] y) 1894 byte[] _d_arrayappendcTX(const TypeInfo ti, ref byte[] px, size_t n) 2076 extern (C) byte[] _d_arraycatT(const TypeInfo ti, byte[] x, byte[] y) 2141 extern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs) 2180 void* _d_arrayliteralTX(const TypeInfo ti, size_t length)
Aug 22 2015
On Friday, 21 August 2015 at 08:11:37 UTC, Kagamin wrote:On Friday, 21 August 2015 at 06:00:44 UTC, Mike wrote:Because the runtime implementation is broken and rely on it instead of templates.Disabling TypeInfo forces one to compromise on slicing, postblitWhy slicing and postblit would need typeinfo?
Aug 21 2015
On Friday, 21 August 2015 at 05:24:52 UTC, BBasile wrote:On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:...This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it:Other alternatives would be a pragma or an attribute to disable TypeInfo generation. NoTI.1. "Since it is compiled in the {$M+} state, the compiler generates RTTI (Run-Time Type Information) for it and all classes that descend from it." http://freepascal.org/docs-html/rtl/classes/tpersistent.html 2. "Published properties are included in RTTI, public properties aren't" http://stackoverflow.com/questions/3157648/whats-the-difference-between-public-and-published-class-members-in-delphi
Aug 20 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?+1000!
Aug 20 2015
On 8/21/2015 5:06 PM, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?I need to look over my code that I've written for my to be web application server. But: I'm a little concerned that if there is no alternative we won't be able to seriously be able to have a web application server ala JSP servlet style. So while export may work, perhaps a slightly different approach. If an interface/class is marked as export, it gets inherited. So an child class/implementation would also be export because a super interface/class was export. This would make me a lot happier.
Aug 20 2015
On Friday, 21 August 2015 at 06:24:34 UTC, Rikki Cattermole wrote:On 8/21/2015 5:06 PM, Walter Bright wrote:I've had a look at it finally. This would definitely effect me. Since TypeInfo_Class would still need to exist to access .init. Humpth yes, it would be definitely desirable for me as the framework author to say every class that inherits from this interface must be visible to me. If it is not it is useless. Transients would be desired in this use case. That way the average developer wouldn't have to worry about this behaviour.This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?I need to look over my code that I've written for my to be web application server. But: I'm a little concerned that if there is no alternative we won't be able to seriously be able to have a web application server ala JSP servlet style. So while export may work, perhaps a slightly different approach. If an interface/class is marked as export, it gets inherited. So an child class/implementation would also be export because a super interface/class was export. This would make me a lot happier.
Aug 23 2015
On 2015-08-21 07:06, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?I think, or rather know, that this will break serialization, i.e. my library Orange [1]. I really like that one doesn't need to register a class to be able to (de)serialize it. I can't believe this change is purposed that will clearly break valid code. But at the same time there are other breaking changes you refuse to do that would fix design flaws in the language. I still remember your rant about your old D1 project that didn't compile with the latest D2 compiler. [1] https://github.com/jacob-carlborg/orange -- /Jacob Carlborg
Aug 20 2015
On 8/20/2015 11:40 PM, Jacob Carlborg wrote:I think, or rather know, that this will break serialization, i.e. my library Orange [1]. I really like that one doesn't need to register a class to be able to (de)serialize it. I can't believe this change is purposed that will clearly break valid code.A large purpose of starting this thread is to find out in advance what sort of breakage would be likely, and explore ways to mitigate that breakage.But at the same time there are other breaking changes you refuse to do that would fix design flaws in the language.As with everything, it's cost/benefit. Changing isnan to isNaN is an example of all cost and no benefit. I've explained the benefits of changing factory() a couple times in this thread. I believe the benefits are significant, including the benefit of making D viable for use in embedded systems.I still remember your rant about your old D1 project that didn't compile with the latest D2 compiler.Many of the breaking changes were gratuitous (all cost and no benefit), and some required rewrites so extensive I (along with invaluable help from Dmitry) created undeaD to deal with it: https://github.com/DigitalMars/undeaD
Aug 21 2015
On Friday, 21 August 2015 at 21:50:21 UTC, Walter Bright wrote:As with everything, it's cost/benefit. Changing isnan to isNaN is an example of all cost and no benefit. I've explained the benefits of changing factory() a couple times in this thread. I believe the benefits are significant, including the benefit of making D viable for use in embedded systems.This is fundamentally flawed way of thinking which only confirms my feeling that my last DConf talk was a complete waste. You completely ignore what those changes mean to your users by making such statements. Changing isnan to isNaN is a small benefit (better internal structure and consistency is important) but it also comes at tiny, almost insignificant costs. It doesn't cause any immediate breakage and can be adjusted to at any moment with 1 simple search/replace. It is a best kind of change you can have, tier 1 ("good") in my classification. Proposed change in Object.factory, on the other hand, is the worst possible kind of breaking changes you can ever make (tier 3, "ugly") - it changes program semantics silently at runtime with no errors and can't be adjusted to in automated manner, requiring full reimplementation of some designs. Cost of this change is huge, it will take no less than several full working days to fix everything. Benefits are also not small - Mike use case is very important. Yet in current proposed form ration of cost/benefit is much much worse than one of isnan/isNaN - simply because how big costs are. To make the change more acceptable you can take one of two possible paths: 1) make more benefits, for example by improving `export` definition and unifying its semantics between platforms (see also attribute inference / WPO proposals by Martin) 2) reduce costs by providing compiler diagnostics for transition and enabling similar designs at CT (see the issue I have linked earlier) Doing both is perfection, of course.
Aug 23 2015
On 8/23/2015 2:27 AM, Dicebot wrote:Changing isnan to isNaN is a small benefit (better internal structure and consistency is important) but it also comes at tiny, almost insignificant costs. It doesn't cause any immediate breakage and can be adjusted to at any moment with 1 simple search/replace. It is a best kind of change you can have, tier 1 ("good") in my classification.I agree the cost is small, but the benefit is zero. Yes, I understand you (and others) don't agree with my estimation of the benefit. I don't see much point in debating that one further, it's a done deal.Proposed change in Object.factory, on the other hand, is the worst possible kind of breaking changes you can ever make (tier 3, "ugly") - it changes program semantics silently at runtime with no errors and can't be adjusted to in automated manner, requiring full reimplementation of some designs. Cost of this change is huge, it will take no less than several full working days to fix everything. Benefits are also not small - Mike use case is very important. Yet in current proposed form ration of cost/benefit is much much worse than one of isnan/isNaN - simply because how big costs are. To make the change more acceptable you can take one of two possible paths: 1) make more benefits, for example by improving `export` definition and unifying its semantics between platforms (see also attribute inference / WPO proposals by Martin) 2) reduce costs by providing compiler diagnostics for transition and enabling similar designs at CT (see the issue I have linked earlier) Doing both is perfection, of course.The point of this thread is to investigate the various ways of mitigating the costs and figure out the best way forward.
Aug 23 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?I don't think this is a good idea. That's just abusing a already existing keyword. Export basically means "Make this function or class visible across shared library boundaries". I don't see how this connects to the object factory. Maybe I want to instantiate a class via the factory that should not be visible across a shared library boundary (e.g. to keep the interface of a shared library minimal). Please also consider that as export means dllexport and dllimport at the same time (on Windows) classes marked with export will inflict additional runtime overhead due to the double indirection needed for dlls and due to the fact that you sometimes don't know if the class resides in a different binary then the one your are currently in. This runtime overhead even occurs for purely static builds, as the compiler can't know if the generated code uses some shared library or not. (unless we add a specific compiler switch for it, like -onlyStatic which many people will not be a fan of. And no the -shared flag doesn't help as executables are build without -shared and might still use shared libraries) Given how limited object.factory is I would just vote that we kill it completely. Every time I wanted to use it, it was to limited and I ended up building my own reflection / factory mechanism. Even though you rejected my proposal for making export a attribute instead of a visibility level, I think that once a broader set of contributors sees the issue behind export being a protection level the demand will be high to make export an attribute. Giving export a additional meaning now will only complicate this. Tldr: As broken as export currently is we shouldn't be using it for anything else. Kind Regards Benjamin Thaut
Aug 21 2015
On 2015-08-21 09:24, Benjamin Thaut wrote:Given how limited object.factory is I would just vote that we kill it completely. Every time I wanted to use it, it was to limited and I ended up building my own reflection / factory mechanism.How is it limiting? That it only works with default constructors? I don't think that underlying ClassInfo.find is limiting, which is where the interesting part happens. I'm pretty sure that Object.factory could be extended to support non-default constructors, if that makes it less limiting. -- /Jacob Carlborg
Aug 21 2015
On Friday, 21 August 2015 at 08:49:37 UTC, Jacob Carlborg wrote:How is it limiting? That it only works with default constructors? I don't think that underlying ClassInfo.find is limiting, which is where the interesting part happens. I'm pretty sure that Object.factory could be extended to support non-default constructors, if that makes it less limiting.Yes, the usual problem was that it only works with default constructors. Also it doesn't work with nested classes e.g. class Outer { class Inner { } } I don't know if that is fixed now.
Aug 21 2015
On 2015-08-21 10:52, Benjamin Thaut wrote:Yes, the usual problem was that it only works with default constructors. Also it doesn't work with nested classes e.g. class Outer { class Inner { } } I don't know if that is fixed now.It sounds like both of these could be fixed. BTW, in my serialization library I don't even call the constructor so I don't have that problem. -- /Jacob Carlborg
Aug 21 2015
Am Fri, 21 Aug 2015 07:24:58 +0000 schrieb "Benjamin Thaut" <code benjamin-thaut.de>:I don't think this is a good idea. That's just abusing a already existing keyword. Export basically means "Make this function or class visible across shared library boundaries".+1. I think we should be very careful when reusing a keyword which isn't fully specified.
Aug 21 2015
On 8/21/2015 12:24 AM, Benjamin Thaut wrote:Export basically means "Make this function or class visible across shared library boundaries". I don't see how this connects to the object factory.Object.factory() only has a point when it is used to instantiate classes in a DLL/so. It fits in nicely with export.
Aug 21 2015
On 21-Aug-2015 13:44, Walter Bright wrote:On 8/21/2015 12:24 AM, Benjamin Thaut wrote:Still abusing visibility keyword is probably bad idea, it's already tricky with private implying final or some such nonsense. Just add ObjectFactory UDA to object.d and be done with it? -- Dmitry OlshanskyExport basically means "Make this function or class visible across shared library boundaries". I don't see how this connects to the object factory.Object.factory() only has a point when it is used to instantiate classes in a DLL/so. It fits in nicely with export.
Aug 21 2015
On 2015-08-21 12:44, Walter Bright wrote:Object.factory() only has a point when it is used to instantiate classes in a DLL/so. It fits in nicely with export.It's useful for deserialization as well. -- /Jacob Carlborg
Aug 21 2015
On Friday, 21 August 2015 at 13:18:17 UTC, Jacob Carlborg wrote:On 2015-08-21 12:44, Walter Bright wrote:Btw we use it for high-level testing framework - will be rather hard to move that to compile-time approach until some reflection bugs gets fixed.Object.factory() only has a point when it is used to instantiate classes in a DLL/so. It fits in nicely with export.It's useful for deserialization as well.
Aug 21 2015
On 8/21/2015 6:29 AM, Dicebot wrote:On Friday, 21 August 2015 at 13:18:17 UTC, Jacob Carlborg wrote:It's good to hear of use cases for Object.factory.On 2015-08-21 12:44, Walter Bright wrote:Btw we use it for high-level testing framework - will be rather hard to move that to compile-time approachObject.factory() only has a point when it is used to instantiate classes in a DLL/so. It fits in nicely with export.It's useful for deserialization as well.until some reflection bugs gets fixed.Bugzilla issues? (You knew that was coming!)
Aug 21 2015
On Friday, 21 August 2015 at 20:28:47 UTC, Walter Bright wrote:If you want details it is special library for black box testing applications by spawning them as external processes and interacting with their shell/network API. To minimize boilerplate test scenarios are derived from special TestCase class and test runner finds all classes that derive from TestCase automatically. Marking them all as export will be inconvenient but is possible - but I'd like to get something useful in return, like well-defined and working export for example.Btw we use it for high-level testing framework - will be rather hard to move that to compile-time approachIt's good to hear of use cases for Object.factory.https://issues.dlang.org/show_bug.cgi?id=11595 is the main offender. Currently the task 'find all symbols with a given trait in the whole program' can't be implemented at CT.until some reflection bugs gets fixed.Bugzilla issues? (You knew that was coming!)
Aug 22 2015
On 8/22/2015 2:42 AM, Dicebot wrote:On Friday, 21 August 2015 at 20:28:47 UTC, Walter Bright wrote:I'm not sure how export would help on Linux.If you want details it is special library for black box testing applications by spawning them as external processes and interacting with their shell/network API. To minimize boilerplate test scenarios are derived from special TestCase class and test runner finds all classes that derive from TestCase automatically. Marking them all as export will be inconvenient but is possible - but I'd like to get something useful in return, like well-defined and working export for example.Btw we use it for high-level testing framework - will be rather hard to move that to compile-time approachIt's good to hear of use cases for Object.factory.Thanks!https://issues.dlang.org/show_bug.cgi?id=11595 is the main offender. Currently the task 'find all symbols with a given trait in the whole program' can't be implemented at CT.until some reflection bugs gets fixed.Bugzilla issues? (You knew that was coming!)
Aug 22 2015
On Saturday, 22 August 2015 at 20:14:59 UTC, Walter Bright wrote:I'm not sure how export would help on Linux.One of the use cases for export on Linux would be to set the ELF visibility based on it. Emitting all the symbols with default visibility, like we currently do, leads to size and load time problems with large libraries. Big C++ projects are plagued regularly by this (cf. "-fvisibility=hidden"). — David
Aug 22 2015
On 8/22/2015 1:22 PM, David Nadlinger wrote:On Saturday, 22 August 2015 at 20:14:59 UTC, Walter Bright wrote:A bugzilla enhancement request for this would be nice.I'm not sure how export would help on Linux.One of the use cases for export on Linux would be to set the ELF visibility based on it. Emitting all the symbols with default visibility, like we currently do, leads to size and load time problems with large libraries. Big C++ projects are plagued regularly by this (cf. "-fvisibility=hidden").
Aug 22 2015
On Saturday, 22 August 2015 at 21:56:25 UTC, Walter Bright wrote:On 8/22/2015 1:22 PM, David Nadlinger wrote:https://issues.dlang.org/show_bug.cgi?id=9893 – DavidOne of the use cases for export on Linux would be to set the ELF visibility based on it. Emitting all the symbols with default visibility, like we currently do, leads to size and load time problems with large libraries. Big C++ projects are plagued regularly by this (cf. "-fvisibility=hidden").A bugzilla enhancement request for this would be nice.
Aug 22 2015
On Saturday, 22 August 2015 at 22:08:50 UTC, David Nadlinger wrote:The common saying "if it isn't in bugzilla it is forgotten" seems quite silly when so much that IS in bugzilla is forgotten all the same.A bugzilla enhancement request for this would be nice.https://issues.dlang.org/show_bug.cgi?id=9893
Aug 22 2015
On 8/22/2015 3:41 PM, Adam D. Ruppe wrote:The common saying "if it isn't in bugzilla it is forgotten" seems quite silly when so much that IS in bugzilla is forgotten all the same.Lots of people, like Daniel and Kenji and Vladimir and Martin, etc., go through Bugzilla looking for things to fix. I don't know anyone combing through the 300,000 messages in this n.g. looking for vaguely described complaints to fix. Furthermore, the changelog for each release shows hundreds of bugzilla issues fixed, and 0 newsgroup complaints fixed.
Aug 22 2015
On Saturday, 22 August 2015 at 20:22:58 UTC, David Nadlinger wrote:On Saturday, 22 August 2015 at 20:14:59 UTC, Walter Bright wrote:The good news is, once I'm done with my windows DLL work the code can be trivialy reused to make export control the visibility of symbols on linux as well. Kind Regards Benjamin ThautI'm not sure how export would help on Linux.One of the use cases for export on Linux would be to set the ELF visibility based on it. Emitting all the symbols with default visibility, like we currently do, leads to size and load time problems with large libraries. Big C++ projects are plagued regularly by this (cf. "-fvisibility=hidden"). — David
Aug 23 2015
On 8/24/2015 1:09 AM, Benjamin Thaut wrote:The good news is, once I'm done with my windows DLL work the code can be trivialy reused to make export control the visibility of symbols on linux as well. Kind Regards Benjamin ThautWait we are getting almost full blown DLL support on Windows? Yuppie!
Aug 23 2015
On Sunday, 23 August 2015 at 13:09:46 UTC, Benjamin Thaut wrote:The good news is, once I'm done with my windows DLL work the code can be trivialy reused to make export control the visibility of symbols on linux as well. Kind Regards Benjamin ThautBut then you have the same problem on linux as on windows. "Export" controls not only the symbol visibility across shared library boundaries but also the module level visibility. E.g. this is a problem private void SomeImplementationDetail() { ... } void SomeTemplateFunc(T)() { SomeImplementationDetail(); } If you compile this into a shared library and all symbols are hidden by default unless marked with export it will fail to compile if someone tries to use it. Because the instanciated template SomeTemplateFunc will call the SomeImplementationDetail function which is not visible across the shared library boundary. To fix this you would have to do: export void SomeImplementationDetail() { ... } void SomeTemplateFunc(T)() { SomeImplementationDetail(); } But this means that users of the shared library would suddenly be allowed to call SomeImplementationDetail. The fix would be to make export an attribute instead of an protection level resulting in: private export void SomeImplementationDetail() { ... } void SomeTemplateFunc(T)() { SomeImplementationDetail(); }
Aug 23 2015
On Saturday, 22 August 2015 at 20:14:59 UTC, Walter Bright wrote:I have always been in support of actually enforcing export on Linux (== making all non-export symbols hidden). It is a key for heavy cross-module optimization.Marking them all as export will be inconvenient but is possible - but I'd like to get something useful in return, like well-defined and working export for example.I'm not sure how export would help on Linux.
Aug 23 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: What do you think?Can't we just make that Object.factory() an empty template and lazily instantiate class TypeInfo when needed.
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:What do you think?Isn't typeinfo referenced from vtbl? So as long as the class is used, its typeinfo stays.
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Just change Object.factory to require registration of the class. It isn't too much of an effort to designate the few classes where it's needed, really. It's even safer, because the class name could potentially come from user input, and needs to be sanitized anyway in this case.
Aug 21 2015
On 8/21/2015 4:44 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> wrote:Just change Object.factory to require registration of the class.What mechanism do you propose for that?
Aug 21 2015
On Friday, 21 August 2015 at 21:37:34 UTC, Walter Bright wrote:On 8/21/2015 4:44 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> wrote:http://forum.dlang.org/post/fxansmxbiobeshefszlm forum.dlang.orgJust change Object.factory to require registration of the class.What mechanism do you propose for that?
Aug 21 2015
On Friday, 21 August 2015 at 21:37:34 UTC, Walter Bright wrote:On 8/21/2015 4:44 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> wrote:E.g.: template factoryConstructors(Args...) { // using void* because I don't know whether it's possible // to have a function pointer to a constructor void*[string] factoryConstructors; } void registerFactoryConstructor(Class, Args...)() if(is(Class == class)) { factoryConstructors!Args[Class.stringof] = ...; } Object factory(Args...)(string className, Args args) { auto constructor = factoryConstructors!Args[className]; return ...; } This even allows to call constructors with arguments. deadalnix's proposal is a nice way to automate this for an entire class hierarchy. Another possible mechanisms would be some UDA magic.Just change Object.factory to require registration of the class.What mechanism do you propose for that?
Aug 22 2015
On Saturday, 22 August 2015 at 08:16:06 UTC, Marc Schütz wrote:Another possible mechanisms would be some UDA magic.E.g.: class MyClass { factorizable this() { } factorizable this(string) { } this(int) { } } mixin registerFactoryConstructors; // for entire module
Aug 22 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?An alternative which would be more work but wouldn't break code would be to put the "all the classes" structure in a separate section, which is only referenced by Object.factory. Thus, the structure will be GC-ed by the linker, unless Object.factory is actually used somewhere in the program. Not sure how this would tie in with shared objects though. Maybe this needs to be combined with your "export" idea.
Aug 21 2015
On 8/21/15 1:06 AM, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Knee-jerk reaction: sensible and meaningful, but we need to make a good case for breaking code. -- Andrei
Aug 21 2015
How expensive putting a flag for the compiler? --exportall, -ea to export all, otherwise, only the classes with "export" keyword are to be exported.
Aug 21 2015
On 8/21/2015 6:29 AM, Andrei Alexandrescu wrote:Knee-jerk reaction: sensible and meaningful, but we need to make a good case for breaking code. -- AndreiThe case is: https://issues.dlang.org/show_bug.cgi?id=14758 i.e. D being unusable for embedded systems because of bloat. And it always has been a little strange to make every class available via Object.factory. I have a hard time imagining an application for it that needed more than a handful of classes available that way. The principle often used by languages (C, C++, Rust) is you only pay for what you use. With Object.factory, every program pays for it with every class, despite very few actual uses of it.
Aug 21 2015
On Friday, 21 August 2015 at 20:26:29 UTC, Walter Bright wrote:On 8/21/2015 6:29 AM, Andrei Alexandrescu wrote:That sound reasonable and I advocated for changing Object.factory in the past for this very reason. That being said, if we are going to break code, we'd better be sure we do it for something that is worth it. That mean we need a way for user to repro the feature, and I rather avoid a dirty hack to do it, as proposed here. A generic solution, for instance, could be for a superclass to be able to mixin something in all its child. Such a feature can be used to make sure that all child have a mechanism to register themselves int he factory. Something à la class Base { super mixin { shared this() { library.register(typeid(typeof(this))); } } } class Child : Base { // The super mixin also gets expanded here. // But this does not have the same type. // Both end up being registered, whatever that means. } Such a solution can be leveraged by any library or user to do whatever they want. Sounds a better approach to me that introducing hacks.Knee-jerk reaction: sensible and meaningful, but we need to make a good case for breaking code. -- AndreiThe case is: https://issues.dlang.org/show_bug.cgi?id=14758 i.e. D being unusable for embedded systems because of bloat. And it always has been a little strange to make every class available via Object.factory. I have a hard time imagining an application for it that needed more than a handful of classes available that way. The principle often used by languages (C, C++, Rust) is you only pay for what you use. With Object.factory, every program pays for it with every class, despite very few actual uses of it.
Aug 21 2015
On 8/21/2015 2:59 PM, deadalnix wrote:[...]It's a good idea, but is still equivalent to manually annotating the classes one wishes to register, and still requires a new language feature.
Aug 21 2015
On Friday, 21 August 2015 at 22:21:43 UTC, Walter Bright wrote:On 8/21/2015 2:59 PM, deadalnix wrote:Breaking the code must be worth it.[...]It's a good idea, but is still equivalent to manually annotating the classes one wishes to register, and still requires a new language feature.
Aug 21 2015
On Friday, 21 August 2015 at 21:59:30 UTC, deadalnix wrote:Such a feature can be used to make sure that all child have a mechanism to register themselves int he factory. Something à la class Base { super mixin { shared this() { library.register(typeid(typeof(this))); } } } class Child : Base { // The super mixin also gets expanded here. // But this does not have the same type. // Both end up being registered, whatever that means. } Such a solution can be leveraged by any library or user to do whatever they want. Sounds a better approach to me that introducing hacks.+1, this seems like a great solution. now if only typeinfo could be completely redone...
Aug 21 2015
On 2015-08-21 22:26, Walter Bright wrote:The principle often used by languages (C, C++, Rust) is you only pay for what you use. With Object.factory, every program pays for it with every class, despite very few actual uses of it.A always thought of D as a bit more convenient language. Variables are automatically initialized, virtual by default, minimal reflation functionality, i.e. Object.factory. Although, all of these can be avoided except for Object.factory. -- /Jacob Carlborg
Aug 23 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:What do you think?Do function pointer types also have TypeInfo? Derelict libraries has hundreds of them and my belief is that they are related. There were complaints about bloat at times. Those function pointer types typically don't need anything that TypeInfo provides.
Aug 21 2015
On 8/21/2015 2:53 PM, ponce wrote:Do function pointer types also have TypeInfo? Derelict libraries has hundreds of them and my belief is that they are related.Compile with -map and check to see what winds up in the binary.
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?Can't this be optional? -slim-rtti // hold the gravy -verbose-rtti // more gravy!On Friday, 21 August 2015 at 20:26:29 UTC, Walter Bright wrote: [...] The principle often used by languages (C, C++, Rust) is you only pay for what you use. With Object.factory, every program pays for it with every class, despite very few actual uses of it.Object.factory() would probably get more use if D provided a full solution in this category. OffsetTypeInfo was never implemented, but is still collecting dust: https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L197 I would love to see OffsetTypeInfo implemented, and have the field name included as well so it could be used for serialization. I don't believe there has to be a "one size fits all" solution for this. Some people need small binaries, some need utility. Bit
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:What do you think?Well, one suggestion would be to simply version Object.factory so that programs that don't need it and don't want the bloat can define a version which versions it out. The it won't pull in all of the TypeInfos, and you won't get that bloat. It's not exactly an ideal solution, but it's easy enough to do that it might be worth it to get rid of that bloat for the folks who can't afford it. I do agree though that we should try and find a better way to fix the problem so that the situation is improved for everyone. - Jonathan M Davis
Aug 21 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway.The export seems to be an arbitrary rule (and export is really broken currently). Let's just use every class that is linked into the binary (e.g. weakly referencing them), then it'll naturally work with all linker functionalities. This doesn't only affect Object.factory but also ModuleInfo.localClasses. I'd suggest we first add a new internal array of weakly linked classes, turn localClasses into an opApply function or range so it automatically skips null classes (weakly undefined), then change Object.factory to only load weakly linked classes. For an intermediate time we can keep the old array and print a deprecation warning in Object.factory when a class would no longer be available. https://github.com/D-Programming-Language/dmd/pull/4638
Aug 22 2015
On Saturday, 22 August 2015 at 09:44:48 UTC, Martin Nowak wrote:The export seems to be an arbitrary rule (and export is really broken currently). Let's just use every class that is linked into the binary (e.g. weakly referencing them), then it'll naturally work with all linker functionalities. This doesn't only affect Object.factory but also ModuleInfo.localClasses. I'd suggest we first add a new internal array of weakly linked classes, turn localClasses into an opApply function or range so it automatically skips null classes (weakly undefined), then change Object.factory to only load weakly linked classes. For an intermediate time we can keep the old array and print a deprecation warning in Object.factory when a class would no longer be available. https://github.com/D-Programming-Language/dmd/pull/4638How do you implement weak linking? It would be really usefull for my DLL work as well, but I couldn't find any way to make it work with the microsoft linker.
Aug 23 2015
On 8/23/2015 6:17 AM, Benjamin Thaut wrote:How do you implement weak linking? It would be really usefull for my DLL work as well, but I couldn't find any way to make it work with the microsoft linker.I've always had trouble with linker bugs when using weak linking, to the point where I simply gave up on using it.
Aug 23 2015
On 21 August 2015 at 15:06, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway. What do you think?I don't follow the reasoning, but yes! Kill it with fire! I'd rather see a compile option or something to disable it completely, like how disabling RTTI is a common C++ option.
Aug 22 2015
On Saturday, 22 August 2015 at 23:33:15 UTC, Manu wrote:On 21 August 2015 at 15:06, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:rtti is used heavily in the runtime hooks, this needs to be fixed first as far as I know.[...]I don't follow the reasoning, but yes! Kill it with fire! I'd rather see a compile option or something to disable it completely, like how disabling RTTI is a common C++ option.
Aug 22 2015
On 2015-08-21 07:06, Walter Bright wrote:This function: enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it. This leads to bloat: https://issues.dlang.org/show_bug.cgi?id=14758 and sometimes the bloat can be overwhelming. The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway.If we're actually going to talk about solution then it seems better to have a flag that disables Object.factory. It won't break any code and everyone that doesn't like can disable it. Everybody wins. -- /Jacob Carlborg
Aug 23 2015
I think this is another case where Walter has got it right, by and large. I think we should try and use 'export' to cut down on binary bloat, and it looks like an acceptable solution. I have said many times, lock your versions down, and don't update your D compiler until you're ready to pay the cost of updating. There is always a cost involved, small or great.
Aug 25 2015
On 2015-08-25 10:18, w0rp wrote:I think this is another case where Walter has got it right, by and large. I think we should try and use 'export' to cut down on binary bloat, and it looks like an acceptable solution. I have said many times, lock your versions down, and don't update your D compiler until you're ready to pay the cost of updating. There is always a cost involved, small or great.I'm been doing that and I get a lot of complains from developers how want to use my libraries with later versions of the compiler. -- /Jacob Carlborg
Aug 25 2015
V Tue, 25 Aug 2015 10:34:57 +0200 Jacob Carlborg via Digitalmars-d <digitalmars-d puremagic.com> napsáno:On 2015-08-25 10:18, w0rp wrote:As a library author (ideal case) you need to support both, some stable branch and some development branch ;-).I think this is another case where Walter has got it right, by and large. I think we should try and use 'export' to cut down on binary bloat, and it looks like an acceptable solution. I have said many times, lock your versions down, and don't update your D compiler until you're ready to pay the cost of updating. There is always a cost involved, small or great.I'm been doing that and I get a lot of complains from developers how want to use my libraries with later versions of the compiler.
Aug 25 2015