Skip to content

Commit

Permalink
preallocate the line offset table
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Aug 8, 2020
1 parent 23c8569 commit 81ce1d5
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 6 deletions.
3 changes: 2 additions & 1 deletion internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,8 @@ type ImportRecord struct {
}

type AST struct {
HasLazyExport bool
ApproximateLineCount int32
HasLazyExport bool

// This is a list of CommonJS features. When a file uses CommonJS features,
// it's not a candidate for "flat bundling" and must be wrapped in its own
Expand Down
11 changes: 11 additions & 0 deletions internal/lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ type Lexer struct {
current int
start int
end int
ApproximateNewlineCount int
Token T
HasNewlineBefore bool
HasPureCommentBefore bool
Expand Down Expand Up @@ -2198,6 +2199,16 @@ func (lexer *Lexer) step() {
codePoint = -1
}

// Track the approximate number of newlines in the file so we can preallocate
// the line offset table in the printer for source maps. The line offset table
// is the #1 highest allocation in the heap profile, so this is worth doing.
// This count is approximate because it handles "\n" and "\r\n" (the common
// cases) but not "\r" or "\u2028" or "\u2029". Getting this wrong is harmless
// because it's only a preallocation. The array will just grow if it's too small.
if codePoint == '\n' {
lexer.ApproximateNewlineCount++
}

lexer.codePoint = codePoint
lexer.end = lexer.current
lexer.current += width
Expand Down
1 change: 1 addition & 0 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8947,6 +8947,7 @@ func (p *parser) toAST(source logging.Source, parts []ast.Part, hashbang string,
TopLevelSymbolToParts: p.topLevelSymbolToParts,
ExportStarImportRecords: p.exportStarImportRecords,
ImportRecords: p.importRecords,
ApproximateLineCount: int32(p.lexer.ApproximateNewlineCount) + 1,

// CommonJS features
HasTopLevelReturn: p.hasTopLevelReturn,
Expand Down
13 changes: 8 additions & 5 deletions internal/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,14 +550,16 @@ func (p *printer) updateGeneratedLineAndColumn() {
p.lastGeneratedUpdate = len(p.js)
}

func generateLineOffsetTables(contents string) []lineOffsetTable {
var lineOffsetTables []lineOffsetTable
func generateLineOffsetTables(contents string, approximateLineCount int32) []lineOffsetTable {
var columnsForNonASCII []int32
byteOffsetToFirstNonASCII := int32(0)
lineByteOffset := 0
columnByteOffset := 0
column := int32(0)

// Preallocate the top-level table using the approximate line count from the lexer
lineOffsetTables := make([]lineOffsetTable, 0, approximateLineCount)

for i, c := range contents {
// Mark the start of the next line
if column == 0 {
Expand Down Expand Up @@ -2870,6 +2872,7 @@ func createPrinter(
symbols ast.SymbolMap,
importRecords []ast.ImportRecord,
options PrintOptions,
approximateLineCount int32,
) *printer {
p := &printer{
symbols: symbols,
Expand Down Expand Up @@ -2900,7 +2903,7 @@ func createPrinter(
// If we're writing out a source map, prepare a table of line start indices
// to do binary search on to figure out what line a given AST node came from
if options.SourceForSourceMap != nil {
p.lineOffsetTables = generateLineOffsetTables(options.SourceForSourceMap.Contents)
p.lineOffsetTables = generateLineOffsetTables(options.SourceForSourceMap.Contents, approximateLineCount)
}

return p
Expand All @@ -2918,7 +2921,7 @@ type PrintResult struct {
}

func Print(tree ast.AST, symbols ast.SymbolMap, options PrintOptions) PrintResult {
p := createPrinter(symbols, tree.ImportRecords, options)
p := createPrinter(symbols, tree.ImportRecords, options, tree.ApproximateLineCount)

for _, part := range tree.Parts {
for _, stmt := range part.Stmts {
Expand All @@ -2943,7 +2946,7 @@ func Print(tree ast.AST, symbols ast.SymbolMap, options PrintOptions) PrintResul
}

func PrintExpr(expr ast.Expr, symbols ast.SymbolMap, options PrintOptions) PrintResult {
p := createPrinter(symbols, nil, options)
p := createPrinter(symbols, nil, options, 0)

p.printExpr(expr, ast.LLowest, 0)

Expand Down

0 comments on commit 81ce1d5

Please sign in to comment.