-
-
Notifications
You must be signed in to change notification settings - Fork 421
[WIP] Lower newExp #2508
[WIP] Lower newExp #2508
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -38,6 +38,68 @@ alias dstring = immutable(dchar)[]; | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
version (D_ObjectiveC) public import core.attribute : selector; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
// Size used to store the TypeInfo at the end of an allocation for structs that | ||||||||||||||||||||||||||||||||||
// have a destructor | ||||||||||||||||||||||||||||||||||
private size_t structTypeInfoSize(T)() pure nothrow @nogc | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
// can't use because it's in rt.lifetime | ||||||||||||||||||||||||||||||||||
//if (!callStructDtorsDuringGC) | ||||||||||||||||||||||||||||||||||
//return 0; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
static if (is(T == struct) && is(typeof({ T t; t.__xdtor; }))) | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this the same as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm afraid I don't know at this time. I'm sorry. |
||||||||||||||||||||||||||||||||||
return size_t.sizeof; | ||||||||||||||||||||||||||||||||||
return 0; | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will complain about unreachable statement if the above static if is true. |
||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||
* Allocate an uninitialized non-array item. | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's an |
||||||||||||||||||||||||||||||||||
* This is an optimization to avoid things needed for arrays like the __arrayPad(size). | ||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||
private T* ___d_newitemU(T)() | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think these names, |
||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
import core.memory; | ||||||||||||||||||||||||||||||||||
import core.internal.traits : Unqual; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
auto ti = typeid(Unqual!T); | ||||||||||||||||||||||||||||||||||
auto flags = !(ti.flags & 1) ? GC.BlkAttr.NO_SCAN : 0; | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought the whole point was to avoid typeid? Surely you should be able to use a compiler trait for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Otherwise one can be added. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't found a compiler trait. Maybe I missed it. Anyone know about one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, not that I can see. But add one. I think it's currently handled here: https://github.com/dlang/dmd/blob/bf26fb4ffc173f016eae9c241bcfd5a88da92957/src/dmd/toobj.d#L1291-L1327. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't know what Second, according to https://dlang.org/spec/interface.html#com-interfaces does that flag mean that it inherits from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's really bad: Lines 1313 to 1315 in 4ad638f
Especially as there is this easily confusing beauty (used for Lines 1969 to 1980 in 4ad638f
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 2194 in 4ad638f
Now I'm thoroughly confused. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is for structs, not classes. TypeInfo_Class.flags() always returns 1 as TypeInfo_Class tries to describe both the reference and the instance of a class at the same time (which is causing trouble elsewhere, too, e.g. when trying to specify the type of memory for the precise GC). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I guess There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using magic constants like this |
||||||||||||||||||||||||||||||||||
enum tiSize = structTypeInfoSize!T(); | ||||||||||||||||||||||||||||||||||
enum size = T.sizeof + tiSize; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
static if (is(T == struct)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
if (tiSize) | ||||||||||||||||||||||||||||||||||
flags |= GC.BlkAttr.STRUCTFINAL | GC.BlkAttr.FINALIZE; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
auto blkInf = GC.qalloc(size, flags, ti); | ||||||||||||||||||||||||||||||||||
auto p = blkInf.base; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
static if (is(T == struct)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
if (tiSize) | ||||||||||||||||||||||||||||||||||
*cast(TypeInfo*)(p + blkInf.size - tiSize) = cast() ti; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
return cast(T*) p; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
// Same as above, for item with non-zero initializer. | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a public symbol, should it has a Ddoc comment? |
||||||||||||||||||||||||||||||||||
T* ___d_newitemT(T)() | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
import core.stdc.string; | ||||||||||||||||||||||||||||||||||
auto p = ___d_newitemU!T(); | ||||||||||||||||||||||||||||||||||
memset(p, 0, T.sizeof); | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment says "for item with non-zero initializer". But doesn't this initialize to zero? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a problem of using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Zero initialisers didn't actually get emitted as such; the pointer then is zero. This only applies to TypeInfo, of course. |
||||||||||||||||||||||||||||||||||
return p; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
// Same as above, for item with non-zero initializer. | ||||||||||||||||||||||||||||||||||
T* ___d_newitemiT(T)() | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
import core.stdc.string; | ||||||||||||||||||||||||||||||||||
auto p = ___d_newitemU!T(); | ||||||||||||||||||||||||||||||||||
auto init = T.init; | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe |
||||||||||||||||||||||||||||||||||
memcpy(p, &init, T.sizeof); | ||||||||||||||||||||||||||||||||||
return p; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
int __cmp(T)(scope const T[] lhs, scope const T[] rhs) @trusted | ||||||||||||||||||||||||||||||||||
if (__traits(isScalar, T)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about this? Any solutions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The simplest would be to make
callStructDtorsDuringGC
package
and importrt.lifetime
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't import
rt.lifetime
. You can't import anything fromrt/*
since it's not inmak/COPY
's$(IMPDIR)
.Maybe I'm missing something, as the GC is able to import from
rt/util/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then you can do a hack, declare an
extern
variable and usepragma(mangle)
to get the same mangling as forcallStructDtorsDuringGC
declared inrt.lifetime
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do even better. Here's an example from the existing code:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that work with non-function types?That won't work for non-function types. The template explicitly checks for a function type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add an
extern (C)
function in lifetime.d to returncallStructDtorsDuringGC
and then just declare that prototype in object.d. You can already find precedent for that technique in object.d (e.g.druntime/src/object.d
Lines 3909 to 3910 in 4ad638f
Though, this isn't much different than @jacob-carlborg's suggestion.