August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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
|
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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: >> Just change Object.factory to require registration of the class. > > What mechanism do you propose for that? 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. |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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
|
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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. -- Andrei
Yes, it's a major pain and a source for many incorrect attributes.
|
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | 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: > > * 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 > > Looks 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-5960d486a42197785b9eee4ba95c6b95R11857 > > Can't even understand, what is this. Array op? But array ops are handled just above. 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. |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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 |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Friday, 21 August 2015 at 20:28:47 UTC, Walter Bright wrote: >> Btw we use it for high-level testing framework - will be rather hard to move >> that to compile-time approach > > It's good to hear of use cases for Object.factory. 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. > > until some reflection bugs gets fixed. > > Bugzilla issues? (You knew that was coming!) 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. |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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. -- Andrei For 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) |
August 22, 2015 Re: Object.factory() and exe file size bloat | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| 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:
>
>> 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.
>
>
I only looked at 2.066.1, the runtime implementation did not pass the typeinfo to the GC.
|
Copyright © 1999-2021 by the D Language Foundation