@@ -2,7 +2,9 @@ package ast_test
22
33import (
44 "reflect"
5+ "runtime"
56 "testing"
7+ "unsafe"
68
79 "github.com/microsoft/TypeScript/tsc/internal/ast"
810 "gotest.tools/v3/assert"
@@ -17,6 +19,7 @@ func TestSymbolFieldsArePrivate(t *testing.T) {
1719
1820func TestSymbolAccessors (t * testing.T ) {
1921 t .Parallel ()
22+ var arena ast.SymbolExtraArena
2023 symbol := ast .NewSymbol ()
2124 assert .Equal (t , symbol .Flags (), ast .SymbolFlagsNone )
2225 assert .Equal (t , symbol .CheckFlags (), ast .CheckFlags (0 ))
@@ -43,10 +46,10 @@ func TestSymbolAccessors(t *testing.T) {
4346 symbol .SetName ("C" )
4447 symbol .SetDeclarations (declarations )
4548 symbol .SetValueDeclaration (declaration )
46- symbol .SetMembers (members )
47- symbol .SetExports (exports )
49+ symbol .SetMembers (members , & arena )
50+ symbol .SetExports (exports , & arena )
4851 symbol .SetParent (parent )
49- symbol .SetExportSymbol (exportSymbol )
52+ symbol .SetExportSymbol (exportSymbol , & arena )
5053
5154 assert .Equal (t , symbol .Flags (), ast .SymbolFlagsClass | ast .SymbolFlagsTransient )
5255 assert .Equal (t , symbol .CheckFlags (), ast .CheckFlagsReadonly )
@@ -72,10 +75,10 @@ func TestSymbolAccessors(t *testing.T) {
7275 symbol .SetName ("" )
7376 symbol .SetDeclarations (nil )
7477 symbol .SetValueDeclaration (nil )
75- symbol .SetMembers (nil )
76- symbol .SetExports (nil )
78+ symbol .SetMembers (nil , & arena )
79+ symbol .SetExports (nil , & arena )
7780 symbol .SetParent (nil )
78- symbol .SetExportSymbol (nil )
81+ symbol .SetExportSymbol (nil , & arena )
7982
8083 assert .Equal (t , symbol .Flags (), ast .SymbolFlagsNone )
8184 assert .Equal (t , symbol .CheckFlags (), ast .CheckFlags (0 ))
@@ -90,24 +93,76 @@ func TestSymbolAccessors(t *testing.T) {
9093
9194func TestSymbolTableInitialization (t * testing.T ) {
9295 t .Parallel ()
96+ var arena ast.SymbolExtraArena
9397 symbol := ast .NewSymbol ()
9498 member := ast .NewSymbol ()
9599 export := ast .NewSymbol ()
96100
97- members := ast .GetMembers (symbol )
101+ members := ast .GetMembers (symbol , & arena )
98102 members ["member" ] = member
99103 assert .Equal (t , symbol .Members ()["member" ], member )
100- assert .Equal (t , ast .GetMembers (symbol )["member" ], member )
104+ assert .Equal (t , ast .GetMembers (symbol , & arena )["member" ], member )
101105
102- exports := ast .GetExports (symbol )
106+ exports := ast .GetExports (symbol , & arena )
103107 exports ["export" ] = export
104108 assert .Equal (t , symbol .Exports ()["export" ], export )
105- assert .Equal (t , ast .GetExports (symbol )["export" ], export )
109+ assert .Equal (t , ast .GetExports (symbol , & arena )["export" ], export )
106110
107- symbol .SetMembers (nil )
108- symbol .SetExports (nil )
109- assert .Assert (t , ast .GetMembers (symbol ) != nil )
110- assert .Assert (t , ast .GetExports (symbol ) != nil )
111+ symbol .SetMembers (nil , & arena )
112+ symbol .SetExports (nil , & arena )
113+ assert .Assert (t , ast .GetMembers (symbol , & arena ) != nil )
114+ assert .Assert (t , ast .GetExports (symbol , & arena ) != nil )
111115 assert .Equal (t , len (symbol .Members ()), 0 )
112116 assert .Equal (t , len (symbol .Exports ()), 0 )
113117}
118+
119+ func TestSymbolHotRecordLayout (t * testing.T ) {
120+ t .Parallel ()
121+ assert .Equal (t , unsafe .Sizeof (ast.SymbolWithData {}), unsafe .Sizeof (ast.Symbol {})+ 8 * unsafe .Sizeof ((* ast .Node )(nil )))
122+ }
123+
124+ func TestSymbolNilExtraFieldsDoNotAllocate (t * testing.T ) { //nolint:paralleltest
125+ var arena ast.SymbolExtraArena
126+ symbol := ast .NewSymbol ()
127+ allocs := testing .AllocsPerRun (10 , func () {
128+ symbol .SetMembers (nil , & arena )
129+ symbol .SetExports (nil , & arena )
130+ symbol .SetExportSymbol (nil , & arena )
131+ })
132+ assert .Equal (t , allocs , float64 (0 ))
133+ assert .Assert (t , reflect .ValueOf (symbol ).Elem ().FieldByName ("data" ).Elem ().FieldByName ("extra" ).IsNil ())
134+ }
135+
136+ func TestSymbolSharedExtraData (t * testing.T ) {
137+ t .Parallel ()
138+ var arena ast.SymbolExtraArena
139+ var otherArena ast.SymbolExtraArena
140+ symbol := ast .NewSymbol ()
141+ alias := ast .NewSymbol ()
142+ alias .SetSymbolData (symbol )
143+ member := ast .NewSymbol ()
144+ export := ast .NewSymbol ()
145+ alias .SetMembers (ast.SymbolTable {"member" : member }, & arena )
146+ symbol .SetExports (ast.SymbolTable {"export" : export }, & otherArena )
147+ alias .SetExportSymbol (export , & otherArena )
148+ runtime .GC ()
149+ assert .Equal (t , symbol .Members ()["member" ], member )
150+ assert .Equal (t , alias .Exports ()["export" ], export )
151+ assert .Equal (t , symbol .ExportSymbol (), export )
152+ symbol .SetMembers (nil , & otherArena )
153+ alias .SetExports (nil , & arena )
154+ symbol .SetExportSymbol (nil , & arena )
155+ assert .Assert (t , alias .Members () == nil )
156+ assert .Assert (t , symbol .Exports () == nil )
157+ assert .Assert (t , alias .ExportSymbol () == nil )
158+ ast .GetMembers (alias , & otherArena )["new" ] = export
159+ ast .GetExports (symbol , & arena )["new" ] = member
160+ for range 1024 {
161+ ast .NewSymbol ().SetExports (ast.SymbolTable {"export" : export }, & arena )
162+ }
163+ arena = ast.SymbolExtraArena {}
164+ otherArena = ast.SymbolExtraArena {}
165+ runtime .GC ()
166+ assert .Equal (t , symbol .Members ()["new" ], export )
167+ assert .Equal (t , alias .Exports ()["new" ], member )
168+ }
0 commit comments