Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
df972ed
Deprecate more of speedtracer
niloc132 Sep 10, 2025
b8de7a3
Correctly read process cpu time
niloc132 Sep 10, 2025
e649580
Provide overrides to more easily track calls to log events
niloc132 Sep 10, 2025
ef6e8ff
Sample of how this JFR code could look
niloc132 Sep 11, 2025
672ed57
Attempt at reworking optimizer stats
niloc132 Nov 11, 2025
378cd32
Overhaul how optstats are used in the compiler:
niloc132 Nov 16, 2025
e27b913
JS loop should behave roughly like Java loop
niloc132 Nov 16, 2025
c86870c
Remove unused PerfLogging
niloc132 Nov 17, 2025
1a2e160
Revert "Remove unused PerfLogging"
niloc132 Nov 17, 2025
193ede9
Deprecate PerfCounter and PerfLogger
niloc132 Nov 17, 2025
2af10e4
Clean up opt loops, various other passes, translate more event types
niloc132 Nov 19, 2025
6e719be
Replace all remaining ST events with JFT - except legacy dev mode
niloc132 Nov 19, 2025
bf2ce69
Delete dashboard/speedtracer tests
niloc132 Nov 19, 2025
978f355
Finish replacing events, remove Experimental (hides all events)
niloc132 Nov 20, 2025
04b80f9
checkstyle
niloc132 Nov 20, 2025
6101edd
Revert "Deprecate PerfCounter and PerfLogger"
niloc132 Nov 21, 2025
5ab8ad3
Revert local testing changes to samples build
niloc132 Nov 21, 2025
161eaa0
Remove BooleanSettingControl
niloc132 Nov 21, 2025
385329e
Remove unused imports
niloc132 Nov 21, 2025
e3c4b57
More import cleanup
niloc132 Nov 21, 2025
4b47173
Merge branch 'main' into 10007-jfr-test
niloc132 Nov 21, 2025
baf06a7
Temporarily comment out all gwt-user events so we compile again
niloc132 Nov 23, 2025
8cd5eda
Fix checkstyle, use strings instead of getting too cute with an enum
niloc132 Nov 23, 2025
f82a36a
Rework SimpleEvent so it can be referenced from java8, but not used.
niloc132 Nov 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ public class StandardLinkerContext extends Linker implements LinkerContext {
*/
private static class TopFunctionStringInterner extends JsModVisitor {

public static boolean exec(JsProgram program) {
public static void exec(JsProgram program) {
TopFunctionStringInterner v = new TopFunctionStringInterner(program);
v.accept(program);
return v.didChange();
}

private final JsProgram program;
Expand All @@ -94,7 +93,7 @@ public TopFunctionStringInterner(JsProgram program) {

@Override
public boolean visit(JsFunction x, JsContext ctx) {
didChange |= JsLiteralInterner.exec(program, x.getBody(), x.getScope(), true);
JsLiteralInterner.exec(program, x.getBody(), x.getScope(), true);
return false;
}
}
Expand Down
48 changes: 23 additions & 25 deletions dev/core/src/com/google/gwt/core/ext/soyc/SourceMapRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
import com.google.gwt.dev.jjs.JsSourceMap;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.SourceInfoCorrelation;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.dev.util.log.perf.SimpleEvent;
import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapGeneratorV3;
import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapParseException;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
Expand Down Expand Up @@ -85,30 +83,30 @@ private SourceMapRecorder(int permutationId, List<JsSourceMap> fragmentMaps, Str

private List<SyntheticArtifact> createArtifacts()
throws IOException, SourceMapParseException {
Event event = SpeedTracerLogger.start(CompilerEventType.SOURCE_MAP_RECORDER);
List<SyntheticArtifact> toReturn = Lists.newArrayList();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SourceMapGeneratorV3 generator = new SourceMapGeneratorV3();
int fragment = 0;
for (JsSourceMap sourceMap : fragmentMaps) {
generator.reset();

if (sourceRoot != null) {
generator.setSourceRoot(sourceRoot);
try (SimpleEvent ignored = new SimpleEvent("SourceMap Recorder")) {
List<SyntheticArtifact> toReturn = Lists.newArrayList();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SourceMapGeneratorV3 generator = new SourceMapGeneratorV3();
int fragment = 0;
for (JsSourceMap sourceMap : fragmentMaps) {
generator.reset();

if (sourceRoot != null) {
generator.setSourceRoot(sourceRoot);
}
addExtensions(generator, fragment);
addMappings(new SourceMappingWriter(generator), sourceMap);

baos.reset();
OutputStreamWriter out = new OutputStreamWriter(baos);
generator.appendTo(out, "sourceMap" + fragment);
out.flush();
toReturn.add(new SymbolMapsLinker.SourceMapArtifact(permutationId, fragment,
baos.toByteArray(), sourceRoot));
fragment++;
}
addExtensions(generator, fragment);
addMappings(new SourceMappingWriter(generator), sourceMap);

baos.reset();
OutputStreamWriter out = new OutputStreamWriter(baos);
generator.appendTo(out, "sourceMap" + fragment);
out.flush();
toReturn.add(new SymbolMapsLinker.SourceMapArtifact(permutationId, fragment,
baos.toByteArray(), sourceRoot));
fragment++;
return toReturn;
}
event.end();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here now it used to end the event, but now it just commit it. Is this a change in the how SpeedTracer vs JFR handling things. see my comment on SimpleEvent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In short, yes. Since (as above) commit() calls end(), we get an end() automatically here - and while speedtracer has its own separate "write the buffer to disk" thread, when we call commit() we leave it to jfr to write when it wants to.

return toReturn;
}

private void addExtensions(SourceMapGeneratorV3 generator, int fragment)
Expand Down
150 changes: 73 additions & 77 deletions dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@
import com.google.gwt.dev.cfg.ResourceLoader;
import com.google.gwt.dev.cfg.ResourceLoaders;
import com.google.gwt.dev.util.collect.HashMap;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.dev.util.log.perf.SimpleEvent;
import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapConsumerV3;
import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapGeneratorV3;
import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapParseException;
Expand Down Expand Up @@ -261,99 +259,97 @@ public ArtifactSet link(TreeLogger logger, LinkerContext context,
artifacts = new ArtifactSet(artifacts);
Map<Integer, String> permMap = new HashMap<Integer, String>();

Event writeSymbolMapsEvent =
SpeedTracerLogger.start(CompilerEventType.WRITE_SYMBOL_MAPS);
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (CompilationResult result : artifacts.find(CompilationResult.class)) {
try (SimpleEvent ignored = new SimpleEvent("Write SymbolMaps")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract a constant maybe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really want to have a single big file of constants - but maybe constants for event names at the top of each class that uses simple events?

ByteArrayOutputStream out = new ByteArrayOutputStream();
for (CompilationResult result : artifacts.find(CompilationResult.class)) {

boolean makeSymbolMaps = true;
boolean makeSymbolMaps = true;

for (SoftPermutation perm : result.getSoftPermutations()) {
for (Entry<SelectionProperty, String> propMapEntry : perm.getPropertyMap().entrySet()) {
if (propMapEntry.getKey().getName().equals(MAKE_SYMBOL_MAPS)) {
makeSymbolMaps = Boolean.valueOf(propMapEntry.getValue());
for (SoftPermutation perm : result.getSoftPermutations()) {
for (Entry<SelectionProperty, String> propMapEntry : perm.getPropertyMap().entrySet()) {
if (propMapEntry.getKey().getName().equals(MAKE_SYMBOL_MAPS)) {
makeSymbolMaps = Boolean.valueOf(propMapEntry.getValue());
}
}
}
}

permMap.put(result.getPermutationId(), result.getStrongName());
permMap.put(result.getPermutationId(), result.getStrongName());

if (makeSymbolMaps) {
PrintWriter pw = new PrintWriter(out);
doWriteSymbolMap(logger, result, pw);
pw.close();
if (makeSymbolMaps) {
PrintWriter pw = new PrintWriter(out);
doWriteSymbolMap(logger, result, pw);
pw.close();

doEmitSymbolMap(logger, artifacts, result, out);
out.reset();
doEmitSymbolMap(logger, artifacts, result, out);
out.reset();
}
}
}
writeSymbolMapsEvent.end();

Event writeSourceMapsEvent =
SpeedTracerLogger.start(CompilerEventType.WRITE_SOURCE_MAPS);
StandardLinkerContext stdContext = (StandardLinkerContext) context;
for (SourceMapArtifact se : artifacts.find(SourceMapArtifact.class)) {
// filename is permutation_id/sourceMap<fragmentNumber>.json
final String sourceMapString;
try (InputStream in = se.getContents(logger)) {
sourceMapString = new String(in.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException ex) {
logger.log(TreeLogger.ERROR, "Error reading source map from cache", ex);
throw new UnableToCompleteException();
}
String strongName = permMap.get(se.getPermutationId());
String partialPath = strongName + "_sourceMap" + se.getFragment() + ".json";

int fragment = se.getFragment();
ScriptFragmentEditsArtifact editArtifact = null;
for (ScriptFragmentEditsArtifact mp : artifacts.find(ScriptFragmentEditsArtifact.class)) {
if (mp.getStrongName().equals(strongName) && mp.getFragment() == fragment) {
editArtifact = mp;
artifacts.remove(editArtifact);
break;

try (SimpleEvent ignored = new SimpleEvent("Write SourceMaps")) {
StandardLinkerContext stdContext = (StandardLinkerContext) context;
for (SourceMapArtifact se : artifacts.find(SourceMapArtifact.class)) {
// filename is permutation_id/sourceMap<fragmentNumber>.json
final String sourceMapString;
try (InputStream in = se.getContents(logger)) {
sourceMapString = new String(in.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException ex) {
logger.log(TreeLogger.ERROR, "Error reading source map from cache", ex);
throw new UnableToCompleteException();
}
String strongName = permMap.get(se.getPermutationId());
String partialPath = strongName + "_sourceMap" + se.getFragment() + ".json";

int fragment = se.getFragment();
ScriptFragmentEditsArtifact editArtifact = null;
for (ScriptFragmentEditsArtifact mp : artifacts.find(ScriptFragmentEditsArtifact.class)) {
if (mp.getStrongName().equals(strongName) && mp.getFragment() == fragment) {
editArtifact = mp;
artifacts.remove(editArtifact);
break;
}
}
}

SyntheticArtifact emArt = null;
// no need to adjust source map
if (editArtifact == null) {
emArt = emitSourceMapString(logger, sourceMapString, partialPath);
} else {
SourceMapGeneratorV3 sourceMapGenerator = new SourceMapGeneratorV3();
SyntheticArtifact emArt = null;
// no need to adjust source map
if (editArtifact == null) {
emArt = emitSourceMapString(logger, sourceMapString, partialPath);
} else {
SourceMapGeneratorV3 sourceMapGenerator = new SourceMapGeneratorV3();

if (se.getSourceRoot() != null) {
// Reapply source root since mergeMapSection() will not copy it.
sourceMapGenerator.setSourceRoot(se.getSourceRoot());
}
if (se.getSourceRoot() != null) {
// Reapply source root since mergeMapSection() will not copy it.
sourceMapGenerator.setSourceRoot(se.getSourceRoot());
}

try {
int totalPrefixLines = 0;
for (ScriptFragmentEditsArtifact.EditOperation op : editArtifact.editOperations) {
if (op.getOp() == ScriptFragmentEditsArtifact.Edit.PREFIX) {
totalPrefixLines += op.getNumLines();
try {
int totalPrefixLines = 0;
for (ScriptFragmentEditsArtifact.EditOperation op : editArtifact.editOperations) {
if (op.getOp() == ScriptFragmentEditsArtifact.Edit.PREFIX) {
totalPrefixLines += op.getNumLines();
}
}
}

// TODO(cromwellian): apply insert and remove edits
if (stdContext.getModule().shouldEmbedSourceMapContents()) {
embedSourcesInSourceMaps(logger, stdContext, artifacts, sourceMapGenerator,
totalPrefixLines, sourceMapString, partialPath);
} else {
sourceMapGenerator.mergeMapSection(totalPrefixLines, 0, sourceMapString,
(extKey, oldVal, newVal) -> newVal);
}
// TODO(cromwellian): apply insert and remove edits
if (stdContext.getModule().shouldEmbedSourceMapContents()) {
embedSourcesInSourceMaps(logger, stdContext, artifacts, sourceMapGenerator,
totalPrefixLines, sourceMapString, partialPath);
} else {
sourceMapGenerator.mergeMapSection(totalPrefixLines, 0, sourceMapString,
(extKey, oldVal, newVal) -> newVal);
}

StringWriter stringWriter = new StringWriter();
sourceMapGenerator.appendTo(stringWriter, "sourceMap");
emArt = emitSourceMapString(logger, stringWriter.toString(), partialPath);
} catch (Exception e) {
logger.log(TreeLogger.Type.WARN, "Can't write source map " + partialPath, e);
StringWriter stringWriter = new StringWriter();
sourceMapGenerator.appendTo(stringWriter, "sourceMap");
emArt = emitSourceMapString(logger, stringWriter.toString(), partialPath);
} catch (Exception e) {
logger.log(TreeLogger.Type.WARN, "Can't write source map " + partialPath, e);
}
}
artifacts.add(emArt);
artifacts.remove(se);
}
artifacts.add(emArt);
artifacts.remove(se);
}
writeSourceMapsEvent.end();
}
return artifacts;
}
Expand Down
36 changes: 15 additions & 21 deletions dev/core/src/com/google/gwt/dev/AnalyzeModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
import com.google.gwt.dev.cfg.PropertyCombinations;
import com.google.gwt.dev.util.Memory;
import com.google.gwt.dev.util.StringInterningObjectInputStream;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.dev.util.log.perf.SimpleEvent;

import java.io.BufferedInputStream;
import java.io.File;
Expand Down Expand Up @@ -98,19 +96,18 @@ private interface AnalyzeModuleOptions extends PrecompileTaskOptions {
*/
public static void main(String[] args) {
Memory.initialize();
SpeedTracerLogger.init();
Event analyzeModuleEvent = SpeedTracerLogger.start(CompilerEventType.ANALYZE_MODULE);
final AnalyzeModuleOptions options = new AnalyzeModuleOptionsImpl();
if (new ArgProcessor(options).processArgs(args)) {
CompileTask task = new CompileTask() {
@Override
public boolean run(TreeLogger logger) throws UnableToCompleteException {
return new AnalyzeModule(options).run(logger);
}
};
CompileTaskRunner.runWithAppropriateLogger(options, task);
try (SimpleEvent ignored = new SimpleEvent("AnalyzeModule")) {
final AnalyzeModuleOptions options = new AnalyzeModuleOptionsImpl();
if (new ArgProcessor(options).processArgs(args)) {
CompileTask task = new CompileTask() {
@Override
public boolean run(TreeLogger logger) throws UnableToCompleteException {
return new AnalyzeModule(options).run(logger);
}
};
CompileTaskRunner.runWithAppropriateLogger(options, task);
}
}
analyzeModuleEvent.end();
}

/**
Expand Down Expand Up @@ -139,7 +136,7 @@ public static PrecompileTaskOptions readAnalyzeModuleOptionsFile(

private final AnalyzeModuleOptionsImpl options;

public AnalyzeModule(AnalyzeModuleOptions options) {
private AnalyzeModule(AnalyzeModuleOptions options) {
this.options = new AnalyzeModuleOptionsImpl(options);
}

Expand Down Expand Up @@ -168,16 +165,13 @@ public boolean run(TreeLogger logger) throws UnableToCompleteException {
}

File optFile = new File(compilerWorkDir, AnalyzeModule.OPTIONS_FILENAME);
Event writeObjectAsFileEvent = SpeedTracerLogger.start(
CompilerEventType.WRITE_OBJECT_AS_FILE);
try (OutputStream stream = new FileOutputStream(optFile);
try (SimpleEvent ignored = new SimpleEvent("Write analyze module options to file");
OutputStream stream = new FileOutputStream(optFile);
ObjectOutputStream objectStream = new ObjectOutputStream(stream)) {
objectStream.writeObject(options);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Unable to write file: " + optFile.getAbsolutePath(), e);
throw new UnableToCompleteException();
} finally {
writeObjectAsFileEvent.end();
}

// TODO(zundel): Serializing the ModuleDef structure would save time in
Expand Down
Loading