Even faster source map generation

Summary:
This replaces a polymorphic method with three separate methods that support the different used invocations.

In isolation, this leads to a 25% speedup.

Shoutout to trueadm for teaching me about this.

Reviewed By: trueadm

Differential Revision: D4436781

fbshipit-source-id: 3dce83556debf19d5305c4566a56b9e9565e85bc
This commit is contained in:
David Aurelio 2017-01-20 07:12:15 -08:00 committed by Facebook Github Bot
parent ec6d380a7a
commit 8139d2a602
2 changed files with 64 additions and 57 deletions

View File

@ -73,22 +73,10 @@ class Generator {
}
/**
* Add a mapping that contains the first 2, 4, or all of the following values:
*
* 1. line offset in the generated source
* 2. column offset in the generated source
* 3. line offset in the original source
* 4. column offset in the original source
* 5. name of the symbol in the original source.
* Adds a mapping for generated code without a corresponding source location.
*/
addMapping(
generatedLine: number,
generatedColumn: number,
sourceLine?: number,
sourceColumn?: number,
name?: string,
): void {
var {last} = this;
addSimpleMapping(generatedLine: number, generatedColumn: number): void {
const last = this.last;
if (this.source === -1 ||
generatedLine === last.generatedLine &&
generatedColumn < last.generatedColumn ||
@ -107,28 +95,47 @@ class Generator {
this.builder.startSegment(generatedColumn - last.generatedColumn);
last.generatedColumn = generatedColumn;
}
if (sourceLine != null) {
if (sourceColumn == null) {
throw new Error(
'Received mapping with source line, but without source column');
}
/**
* Adds a mapping for generated code with a corresponding source location.
*/
addSourceMapping(
generatedLine: number,
generatedColumn: number,
sourceLine: number,
sourceColumn: number,
): void {
this.addSimpleMapping(generatedLine, generatedColumn);
this.builder
.append(this.source - last.source)
.append(sourceLine - last.sourceLine)
.append(sourceColumn - last.sourceColumn);
const last = this.last;
this.builder
.append(this.source - last.source)
.append(sourceLine - last.sourceLine)
.append(sourceColumn - last.sourceColumn);
last.source = this.source;
last.sourceColumn = sourceColumn;
last.sourceLine = sourceLine;
last.source = this.source;
last.sourceColumn = sourceColumn;
last.sourceLine = sourceLine;
}
if (name != null) {
const nameIndex = this.names.indexFor(name);
this.builder.append(nameIndex - last.name);
last.name = nameIndex;
}
}
/**
* Adds a mapping for code with a corresponding source location + symbol name.
*/
addNamedSourceMapping(
generatedLine: number,
generatedColumn: number,
sourceLine: number,
sourceColumn: number,
name: string,
): void {
this.addSourceMapping(
generatedLine, generatedColumn, sourceLine, sourceColumn);
const last = this.last;
const nameIndex = this.names.indexFor(name);
this.builder.append(nameIndex - last.name);
last.name = nameIndex;
}
/**

View File

@ -17,7 +17,7 @@ import type ModuleTransport from '../../lib/ModuleTransport';
import type {RawMapping as BabelRawMapping} from 'babel-generator';
type GeneratedCodeMapping = [number, number];
type SourceMapping = [number, number, number, number, void];
type SourceMapping = [number, number, number, number];
type SourceMappingWithName = [number, number, number, number, string];
export type RawMapping =
@ -59,15 +59,10 @@ function compactMapping(mapping: BabelRawMapping): RawMapping {
}
if (typeof name !== 'string') {
/* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error
* detected during the deployment of v0.38.0. To see the error, remove this
* comment and run flow */
return ([line, column, original.line, original.column]: SourceMapping);
return [line, column, original.line, original.column];
}
return (
[line, column, original.line, original.column, name]: SourceMappingWithName
);
return [line, column, original.line, original.column, name];
}
function addMappingsForFile(generator, mappings, module, carryOver) {
@ -75,27 +70,32 @@ function addMappingsForFile(generator, mappings, module, carryOver) {
const columnOffset = module.code.indexOf('{') + 1;
for (let i = 0, n = mappings.length; i < n; ++i) {
const mapping = mappings[i];
generator.addMapping(
mapping[0] + carryOver,
// lines start at 1, columns start at 0
mapping[0] === 1 && mapping[1] + columnOffset || mapping[1],
/* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error
* detected during the deployment of v0.38.0. To see the error, remove
* this comment and run flow */
mapping[2],
/* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error
* detected during the deployment of v0.38.0. To see the error, remove
* this comment and run flow */
mapping[3],
//$FlowIssue #15417846
mapping[4],
);
addMapping(generator, mappings[i], carryOver, columnOffset);
}
generator.endFile();
}
function addMapping(generator, mapping, carryOver, columnOffset) {
const n = mapping.length;
const line = mapping[0] + carryOver;
// lines start at 1, columns start at 0
const column = mapping[0] === 1 ? mapping[1] + columnOffset : mapping[1];
if (n === 2) {
generator.addSimpleMapping(line, column);
} else if (n === 4) {
// $FlowIssue #15579526
generator.addSourceMapping(line, column, mapping[2], mapping[3]);
} else if (n === 5) {
generator.addNamedSourceMapping(
// $FlowIssue #15579526
line, column, mapping[2], mapping[3], mapping[4]);
} else {
throw new Error(`Invalid mapping: [${mapping.join(', ')}]`);
}
}
function countLines(string) {
return string.split('\n').length;
}