Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit af04c94

Browse files
authoredAug 1, 2021
Merge pull request #3527 from dlang/typeinfostruct_mangledName
TypeInfo_Struct: Switch to stored mangled name & demangle lazily (with per-thread cache) Signed-off-by: Razvan Nitu <RazvanN7@users.noreply.github.com> Merged-on-behalf-of: Razvan Nitu <RazvanN7@users.noreply.github.com>
2 parents 3079484 + cd591f4 commit af04c94

File tree

7 files changed

+114
-23
lines changed

7 files changed

+114
-23
lines changed
 

‎.cirrus.yml

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
common_steps_template: &COMMON_STEPS_TEMPLATE
2+
set_repo_branch_env_var_script: |
3+
set -uexo pipefail
4+
if [ -z ${CIRRUS_PR+x} ]; then
5+
# not a PR
6+
REPO_BRANCH="$CIRRUS_BRANCH"
7+
elif [[ ! "$CIRRUS_BRANCH" =~ ^pull/ ]]; then
8+
# PR originating from the official dlang repo
9+
REPO_BRANCH="$CIRRUS_BRANCH"
10+
else
11+
# PR from a fork
12+
REPO_BRANCH="$CIRRUS_BASE_BRANCH"
13+
fi
14+
echo "REPO_BRANCH=$REPO_BRANCH" >> $CIRRUS_ENV
215
clone_dmd_script: |
316
set -uexo pipefail
4-
git clone --branch "${CIRRUS_BASE_BRANCH:-$CIRRUS_BRANCH}" --depth 1 https://github.com/dlang/dmd.git ../dmd
17+
DMD_BRANCH="$REPO_BRANCH"
18+
if [ "$DMD_BRANCH" != master ] && [ "$DMD_BRANCH" != stable ] &&
19+
! git ls-remote --exit-code --heads "https://github.com/dlang/dmd.git" "$DMD_BRANCH" > /dev/null; then
20+
DMD_BRANCH="master"
21+
fi
22+
git clone --branch "$DMD_BRANCH" --depth 1 https://github.com/dlang/dmd.git ../dmd
523
install_prerequisites_script: cd ../dmd && ./cirrusci.sh
624
install_host_compiler_script: cd ../dmd && ./ci.sh install_host_compiler
725
setup_repos_script: |
826
set -uexo pipefail
927
ln -s $CIRRUS_WORKING_DIR ../druntime
10-
cd ../dmd && ./ci.sh setup_repos "${CIRRUS_BASE_BRANCH:-$CIRRUS_BRANCH}"
28+
cd ../dmd && ./ci.sh setup_repos "$REPO_BRANCH"
1129
build_script: cd ../dmd && ./ci.sh build
1230
test_dmd_script: cd ../dmd && ./ci.sh test_dmd
1331
test_druntime_script: cd ../dmd && ./ci.sh test_druntime

‎azure-pipelines.yml

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Learn more: https://aka.ms/yaml
22

33
variables:
4-
DMD_BRANCH: $[ coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranchName'], 'master') ]
54
VSINSTALLDIR: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
65

76
jobs:
@@ -34,7 +33,23 @@ jobs:
3433
sourceFolder: '$(Build.SourcesDirectory)'
3534
contents: '**/*'
3635
TargetFolder: '$(Build.SourcesDirectory)/../druntime'
37-
- script: git clone --branch $(DMD_BRANCH) --depth 1 https://github.com/dlang/dmd.git ../dmd
36+
- bash: |
37+
set -ex
38+
if [ -z ${SYSTEM_PULLREQUEST_TARGETBRANCH+x} ]; then
39+
# no PR
40+
DMD_BRANCH="$BUILD_SOURCEBRANCHNAME"
41+
elif [ $SYSTEM_PULLREQUEST_ISFORK == False ]; then
42+
# PR originating from the official dlang repo
43+
DMD_BRANCH="$SYSTEM_PULLREQUEST_SOURCEBRANCH"
44+
else
45+
# PR from a fork
46+
DMD_BRANCH="$SYSTEM_PULLREQUEST_TARGETBRANCH"
47+
fi
48+
if [ "$DMD_BRANCH" != master ] && [ "$DMD_BRANCH" != stable ] &&
49+
! git ls-remote --exit-code --heads "https://github.com/dlang/dmd.git" "$DMD_BRANCH" > /dev/null; then
50+
DMD_BRANCH="master"
51+
fi
52+
git clone --branch "$DMD_BRANCH" --depth 1 https://github.com/dlang/dmd.git ../dmd
3853
displayName: Clone DMD repo
3954
- script: |
4055
call "%VSINSTALLDIR%\VC\Auxiliary\Build\vcvarsall.bat" %ARCH%
@@ -72,7 +87,23 @@ jobs:
7287
sourceFolder: '$(Build.SourcesDirectory)'
7388
contents: '**/*'
7489
TargetFolder: '$(Build.SourcesDirectory)/../druntime'
75-
- script: git clone --branch $(DMD_BRANCH) --depth 1 https://github.com/dlang/dmd.git ../dmd
90+
- bash: |
91+
set -ex
92+
if [ -z ${SYSTEM_PULLREQUEST_TARGETBRANCH+x} ]; then
93+
# no PR
94+
DMD_BRANCH="$BUILD_SOURCEBRANCHNAME"
95+
elif [ $SYSTEM_PULLREQUEST_ISFORK == False ]; then
96+
# PR originating from the official dlang repo
97+
DMD_BRANCH="$SYSTEM_PULLREQUEST_SOURCEBRANCH"
98+
else
99+
# PR from a fork
100+
DMD_BRANCH="$SYSTEM_PULLREQUEST_TARGETBRANCH"
101+
fi
102+
if [ "$DMD_BRANCH" != master ] && [ "$DMD_BRANCH" != stable ] &&
103+
! git ls-remote --exit-code --heads "https://github.com/dlang/dmd.git" "$DMD_BRANCH" > /dev/null; then
104+
DMD_BRANCH="master"
105+
fi
106+
git clone --branch "$DMD_BRANCH" --depth 1 https://github.com/dlang/dmd.git ../dmd
76107
displayName: Clone DMD repo
77108
- script: cd ../dmd && sh --login .azure-pipelines/windows-visual-studio.sh
78109
displayName: Download required binaries

‎changelog/UniqueTypeInfoNames.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
TypeInfo names for aggregates are fully qualified and hence unique now
2+
3+
Previously, template arguments weren't fully qualified; they now are,
4+
implying longer names in that case.
5+
6+
`TypeInfo_Struct` instances now store the (potentially significantly shorter)
7+
mangled name only and demangle it lazily on the first `name` or `toString()`
8+
call (with a per-thread cache). So if you only need a unique string per
9+
struct TypeInfo, prefer `mangledName` over computed `name` (non-`@nogc` and
10+
non-`pure`).
11+
12+
**Related breaking change**: `TypeInfo.toString()` isn't `pure` anymore to
13+
account for the `TypeInfo_Struct` demangled name cache.
14+
`TypeInfo_Class.toString()` and others are still `pure`.

‎src/core/internal/gc/impl/conservative/gc.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -4099,7 +4099,7 @@ string debugTypeName(const(TypeInfo) ti) nothrow
40994099
else if (auto ci = cast(TypeInfo_Class)ti)
41004100
name = ci.name;
41014101
else if (auto si = cast(TypeInfo_Struct)ti)
4102-
name = si.name;
4102+
name = si.mangledName; // .name() might GC-allocate, avoid deadlock
41034103
else if (auto ci = cast(TypeInfo_Const)ti)
41044104
static if (__traits(compiles,ci.base)) // different whether compiled with object.di or object.d
41054105
return debugTypeName(ci.base);

‎src/object.d

+38-10
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ struct OffsetTypeInfo
418418
*/
419419
class TypeInfo
420420
{
421-
override string toString() const pure @safe nothrow
421+
override string toString() const @safe nothrow
422422
{
423423
return typeid(this).name;
424424
}
@@ -665,7 +665,7 @@ class TypeInfo
665665

666666
class TypeInfo_Enum : TypeInfo
667667
{
668-
override string toString() const { return name; }
668+
override string toString() const pure { return name; }
669669

670670
override bool opEquals(Object o)
671671
{
@@ -977,7 +977,9 @@ class TypeInfo_StaticArray : TypeInfo
977977
import core.internal.string : unsignedToTempString;
978978

979979
char[20] tmpBuff = void;
980-
return value.toString() ~ "[" ~ unsignedToTempString(len, tmpBuff) ~ "]";
980+
const lenString = unsignedToTempString(len, tmpBuff);
981+
982+
return (() @trusted => cast(string) (value.toString() ~ "[" ~ lenString ~ "]"))();
981983
}
982984

983985
override bool opEquals(Object o)
@@ -1202,7 +1204,7 @@ class TypeInfo_Vector : TypeInfo
12021204

12031205
class TypeInfo_Function : TypeInfo
12041206
{
1205-
override string toString() const @trusted
1207+
override string toString() const pure @trusted
12061208
{
12071209
import core.demangle : demangleType;
12081210

@@ -1279,7 +1281,7 @@ class TypeInfo_Function : TypeInfo
12791281

12801282
class TypeInfo_Delegate : TypeInfo
12811283
{
1282-
override string toString() const @trusted
1284+
override string toString() const pure @trusted
12831285
{
12841286
import core.demangle : demangleType;
12851287

@@ -1399,7 +1401,7 @@ private extern (C) int _d_isbaseof(scope TypeInfo_Class child,
13991401
*/
14001402
class TypeInfo_Class : TypeInfo
14011403
{
1402-
override string toString() const { return info.name; }
1404+
override string toString() const pure { return info.name; }
14031405

14041406
override bool opEquals(Object o)
14051407
{
@@ -1584,7 +1586,7 @@ alias ClassInfo = TypeInfo_Class;
15841586

15851587
class TypeInfo_Interface : TypeInfo
15861588
{
1587-
override string toString() const { return info.name; }
1589+
override string toString() const pure { return info.name; }
15881590

15891591
override bool opEquals(Object o)
15901592
{
@@ -1703,13 +1705,17 @@ class TypeInfo_Struct : TypeInfo
17031705
{
17041706
override string toString() const { return name; }
17051707

1708+
override size_t toHash() const
1709+
{
1710+
return hashOf(this.mangledName);
1711+
}
1712+
17061713
override bool opEquals(Object o)
17071714
{
17081715
if (this is o)
17091716
return true;
17101717
auto s = cast(const TypeInfo_Struct)o;
1711-
return s && this.name == s.name &&
1712-
this.initializer().length == s.initializer().length;
1718+
return s && this.mangledName == s.mangledName;
17131719
}
17141720

17151721
override size_t getHash(scope const void* p) @trusted pure nothrow const
@@ -1794,7 +1800,29 @@ class TypeInfo_Struct : TypeInfo
17941800
(*xpostblit)(p);
17951801
}
17961802

1797-
string name;
1803+
string mangledName;
1804+
1805+
final @property string name() nothrow const @trusted
1806+
{
1807+
import core.demangle : demangleType;
1808+
1809+
if (mangledName is null) // e.g., opaque structs
1810+
return null;
1811+
1812+
const key = cast(const void*) this; // faster lookup than TypeInfo_Struct, at the cost of potential duplicates per binary
1813+
static string[typeof(key)] demangledNamesCache; // per thread
1814+
1815+
// not nothrow:
1816+
//return demangledNamesCache.require(key, cast(string) demangleType(mangledName));
1817+
1818+
if (auto pDemangled = key in demangledNamesCache)
1819+
return *pDemangled;
1820+
1821+
const demangled = cast(string) demangleType(mangledName);
1822+
demangledNamesCache[key] = demangled;
1823+
return demangled;
1824+
}
1825+
17981826
void[] m_init; // initializer; m_init.ptr == null if 0 initialize
17991827

18001828
@safe pure nothrow

‎src/rt/aaA.d

+2-2
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ TypeInfo_Struct fakeEntryTI(ref Impl aa, const TypeInfo keyti, const TypeInfo va
294294
extra[0] = cast() kti;
295295
extra[1] = cast() vti;
296296

297-
static immutable tiName = __MODULE__ ~ ".Entry!(...)";
298-
ti.name = tiName;
297+
static immutable tiMangledName = "S2rt3aaA__T5EntryZ";
298+
ti.mangledName = tiMangledName;
299299

300300
ti.m_RTInfo = rtisize > 0 ? rtinfoEntry(aa, keyinfo, valinfo, cast(size_t*)(extra + 2), rtisize) : rtinfo;
301301
ti.m_flags = ti.m_RTInfo is rtinfoNoPointers ? cast(TypeInfo_Struct.StructFlags)0 : TypeInfo_Struct.StructFlags.hasPointers;

‎src/rt/util/typeinfo.d

+5-5
Original file line numberDiff line numberDiff line change
@@ -464,12 +464,12 @@ class TypeInfo_v : TypeInfoGeneric!ubyte
464464
{
465465
return 1;
466466
}
467+
}
467468

468-
unittest
469-
{
470-
assert(typeid(void).toString == "void");
471-
assert(typeid(void).flags == 1);
472-
}
469+
unittest
470+
{
471+
assert(typeid(void).toString == "void");
472+
assert(typeid(void).flags == 1);
473473
}
474474

475475
// All integrals.

0 commit comments

Comments
 (0)
This repository has been archived.