Refactor SpeedTracerLogger to use Event objects for controlling start/stop

Review at http://gwt-code-reviews.appspot.com/704803

Review by: zundel@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8500 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/Compiler.java b/dev/core/src/com/google/gwt/dev/Compiler.java
index 09e2bb1..1465db6 100644
--- a/dev/core/src/com/google/gwt/dev/Compiler.java
+++ b/dev/core/src/com/google/gwt/dev/Compiler.java
@@ -36,6 +36,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
 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.util.tools.Utility;
 
 import java.io.File;
@@ -209,20 +210,21 @@
             return false;
           }
 
-          SpeedTracerLogger.start(CompilerEventType.COMPILE_PERMUTATIONS);
+          Event compilePermutationsEvent =
+              SpeedTracerLogger.start(CompilerEventType.COMPILE_PERMUTATIONS);
           Permutation[] allPerms = precompilation.getPermutations();
           List<FileBackedObject<PermutationResult>> resultFiles = CompilePerms.makeResultFiles(
               options.getCompilerWorkDir(moduleName), allPerms);
           CompilePerms.compile(branch, precompilation, allPerms,
               options.getLocalWorkers(), resultFiles);
-          SpeedTracerLogger.end(CompilerEventType.COMPILE_PERMUTATIONS);
+          compilePermutationsEvent.end();
 
           ArtifactSet generatedArtifacts = precompilation.getGeneratedArtifacts();
           JJSOptions precompileOptions = precompilation.getUnifiedAst().getOptions();
 
           precompilation = null; // No longer needed, so save the memory
 
-          SpeedTracerLogger.start(CompilerEventType.LINK);
+          Event linkEvent = SpeedTracerLogger.start(CompilerEventType.LINK);
           File absPath = new File(options.getWarDir(), module.getName());
           absPath = absPath.getAbsoluteFile();
 
@@ -237,7 +239,7 @@
               generatedArtifacts, allPerms, resultFiles, options.getWarDir(),
               options.getExtraDir(), precompileOptions);
 
-          SpeedTracerLogger.end(CompilerEventType.LINK);
+          linkEvent.end();
           long compileDone = System.currentTimeMillis();
           long delta = compileDone - compileStart;
           branch.log(TreeLogger.INFO, "Compilation succeeded -- "
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index ae085c4..32aaca4 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -36,6 +36,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 import com.google.gwt.util.tools.ArgHandlerString;
 import com.google.gwt.util.tools.Utility;
 
@@ -364,7 +365,7 @@
 
     TreeLogger branch = getTopLogger().branch(TreeLogger.TRACE,
         "Loading modules");
-    SpeedTracerLogger.start(DevModeEventType.SLOW_STARTUP);
+    Event slowStartupEvent = SpeedTracerLogger.start(DevModeEventType.SLOW_STARTUP);
     try {
       for (String moduleName : options.getModuleNames()) {
         TreeLogger moduleBranch = branch.branch(TreeLogger.TRACE, moduleName);
@@ -383,7 +384,7 @@
       // Already logged.
       return false;
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.SLOW_STARTUP);
+      slowStartupEvent.end();
     }
     return true;
   }
@@ -398,7 +399,7 @@
       return -1;
     }
 
-    SpeedTracerLogger.start(DevModeEventType.JETTY_STARTUP);
+    Event jettyStartupEvent = SpeedTracerLogger.start(DevModeEventType.JETTY_STARTUP);
     boolean clearCallback = true;
     try {
       ui.setCallback(RestartServerEvent.getType(), this);
@@ -441,7 +442,7 @@
       System.err.println("Unable to start embedded HTTP server");
       e.printStackTrace();
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.JETTY_STARTUP);
+      jettyStartupEvent.end();
       if (clearCallback) {
         // Clear the callback if we failed to start the server
         ui.setCallback(RestartServerEvent.getType(), null);
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index 91d1514..b8f3f75 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -44,6 +44,7 @@
 import com.google.gwt.dev.util.arg.OptionLogLevel;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 import com.google.gwt.util.tools.ArgHandlerFlag;
 import com.google.gwt.util.tools.ArgHandlerString;
 
@@ -89,7 +90,8 @@
 
     public ModuleSpaceHost createModuleSpaceHost(ModuleHandle module,
         String moduleName) throws UnableToCompleteException {
-      SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_HOST_CREATE);
+      Event moduleSpaceHostCreateEvent =
+          SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_HOST_CREATE);
       // TODO(jat): add support for closing an active module
       TreeLogger logger = module.getLogger();
       try {
@@ -105,7 +107,7 @@
         module.unload();
         throw e;
       } finally {
-        SpeedTracerLogger.end(DevModeEventType.MODULE_SPACE_HOST_CREATE);
+        moduleSpaceHostCreateEvent.end();
       }
     }
   }
@@ -1030,64 +1032,66 @@
       throw new IllegalStateException("Startup code has already been run");
     }
 
-    SpeedTracerLogger.start(DevModeEventType.STARTUP);
-    // See if there was a UI specified by command-line args
-    ui = createUI();
-
-    started = true;
-
-    if (!doStartup()) {
-      /*
-       * TODO (amitmanjhi): Adding this redundant logging to narrow down a
-       * failure. Remove soon.
-       */
-      SpeedTracerLogger.end(DevModeEventType.STARTUP);
-      getTopLogger().log(TreeLogger.ERROR, "shell failed in doStartup method");
-      return false;
-    }
-
-    if (!options.isNoServer()) {
-      int resultPort = doStartUpServer();
-      if (resultPort < 0) {
+    Event startupEvent = SpeedTracerLogger.start(DevModeEventType.STARTUP);
+    try {
+      boolean result = false;
+      // See if there was a UI specified by command-line args
+      ui = createUI();
+  
+      started = true;
+  
+      if (!doStartup()) {
+        /*
+         * TODO (amitmanjhi): Adding this redundant logging to narrow down a
+         * failure. Remove soon.
+         */
+        getTopLogger().log(TreeLogger.ERROR, "shell failed in doStartup method");
+        return false;
+      }
+  
+      if (!options.isNoServer()) {
+        int resultPort = doStartUpServer();
+        if (resultPort < 0) {
+          /*
+           * TODO (amitmanjhi): Adding this redundant logging to narrow down a
+           * failure. Remove soon.
+           */
+          getTopLogger().log(TreeLogger.ERROR,
+              "shell failed in doStartupServer method");
+          return false;
+        }
+        options.setPort(resultPort);
+        getTopLogger().log(TreeLogger.TRACE,
+            "Started web server on port " + resultPort);
+      }
+  
+      if (options.getStartupURLs().isEmpty()) {
+        // if no URLs were supplied, try and find plausible ones
+        inferStartupUrls();
+      }
+  
+      if (options.getStartupURLs().isEmpty()) {
+        // TODO(jat): we could walk public resources to find plausible URLs
+        // after the module(s) are loaded
+        warnAboutNoStartupUrls();
+      }
+  
+      setStartupUrls(getTopLogger());
+  
+      if (!doSlowStartup()) {
         /*
          * TODO (amitmanjhi): Adding this redundant logging to narrow down a
          * failure. Remove soon.
          */
         getTopLogger().log(TreeLogger.ERROR,
-            "shell failed in doStartupServer method");
+            "shell failed in doSlowStartup method");
         return false;
       }
-      options.setPort(resultPort);
-      getTopLogger().log(TreeLogger.TRACE,
-          "Started web server on port " + resultPort);
+      
+      return true;
+    } finally {
+      startupEvent.end();
     }
-
-    if (options.getStartupURLs().isEmpty()) {
-      // if no URLs were supplied, try and find plausible ones
-      inferStartupUrls();
-    }
-
-    if (options.getStartupURLs().isEmpty()) {
-      // TODO(jat): we could walk public resources to find plausible URLs
-      // after the module(s) are loaded
-      warnAboutNoStartupUrls();
-    }
-
-    setStartupUrls(getTopLogger());
-
-    if (!doSlowStartup()) {
-      /*
-       * TODO (amitmanjhi): Adding this redundant logging to narrow down a
-       * failure. Remove soon.
-       */
-      SpeedTracerLogger.end(DevModeEventType.STARTUP);
-      getTopLogger().log(TreeLogger.ERROR,
-          "shell failed in doSlowStartup method");
-      return false;
-    }
-
-    SpeedTracerLogger.end(DevModeEventType.STARTUP);
-    return true;
   }
 
   /**
@@ -1113,7 +1117,7 @@
   private DevModeUI createUI() {
     DevModeUI newUI = null;
 
-    SpeedTracerLogger.start(DevModeEventType.CREATE_UI);
+    Event createUIEvent = SpeedTracerLogger.start(DevModeEventType.CREATE_UI);
 
     if (headlessMode) {
       newUI = new HeadlessUI(options);
@@ -1139,7 +1143,7 @@
       baseLogLevelForUI = TreeLogger.Type.INFO;
     }
 
-    SpeedTracerLogger.end(DevModeEventType.CREATE_UI);
+    createUIEvent.end();
     return newUI;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
index a056d6d..a705bf7 100644
--- a/dev/core/src/com/google/gwt/dev/GWTCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
@@ -33,6 +33,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
 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.util.tools.ToolBase;
 import com.google.gwt.util.tools.Utility;
 
@@ -163,7 +164,7 @@
    */
   public boolean run(TreeLogger logger, ModuleDef... modules)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.COMPILE);
+    Event compileEvent = SpeedTracerLogger.start(CompilerEventType.COMPILE);
     boolean tempWorkDir = false;
     try {
       if (options.getWorkDir() == null) {
@@ -219,7 +220,7 @@
           e);
       return false;
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.COMPILE);
+      compileEvent.end();
       if (tempWorkDir) {
         Util.recursiveDelete(options.getWorkDir(), false);
       }
diff --git a/dev/core/src/com/google/gwt/dev/PermutationWorkerFactory.java b/dev/core/src/com/google/gwt/dev/PermutationWorkerFactory.java
index 050a1c4..3488902 100644
--- a/dev/core/src/com/google/gwt/dev/PermutationWorkerFactory.java
+++ b/dev/core/src/com/google/gwt/dev/PermutationWorkerFactory.java
@@ -22,6 +22,7 @@
 import com.google.gwt.dev.util.FileBackedObject;
 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 java.util.ArrayList;
 import java.util.Arrays;
@@ -60,8 +61,8 @@
       }
 
       public void run() {
-        SpeedTracerLogger.start(CompilerEventType.PERMUTATION_WORKER, "name",
-            worker.getName());
+        Event permutationWorkerEvent =
+            SpeedTracerLogger.start(CompilerEventType.PERMUTATION_WORKER, "name", worker.getName());
         Result threadDeathResult = Result.FAIL;
         try {
           while (true) {
@@ -89,7 +90,7 @@
         } catch (InterruptedException e) {
           return;
         } finally {
-          SpeedTracerLogger.end(CompilerEventType.PERMUTATION_WORKER);
+          permutationWorkerEvent.end();
           // Record why I died.
           try {
             resultsQueue.put(threadDeathResult);
@@ -137,9 +138,9 @@
         int workToDo = work.size();
         int aliveWorkers = workers.size();
         waitForWorkers : while (workToDo > 0 && aliveWorkers > 0) {
-          SpeedTracerLogger.start(CompilerEventType.BLOCKED);
+          Event blockedEvent = SpeedTracerLogger.start(CompilerEventType.BLOCKED);
           Result take = resultsQueue.take();
-          SpeedTracerLogger.end(CompilerEventType.BLOCKED);
+          blockedEvent.end();
           switch (take) {
             case SUCCESS:
               --workToDo;
diff --git a/dev/core/src/com/google/gwt/dev/Precompile.java b/dev/core/src/com/google/gwt/dev/Precompile.java
index f976ac1..6ff1d60 100644
--- a/dev/core/src/com/google/gwt/dev/Precompile.java
+++ b/dev/core/src/com/google/gwt/dev/Precompile.java
@@ -70,6 +70,7 @@
 import com.google.gwt.dev.util.collect.Lists;
 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 java.io.File;
 import java.io.Serializable;
@@ -333,7 +334,7 @@
       logger = logger.branch(TreeLogger.DEBUG, msg, null);
 
       Set<String> answers = new HashSet<String>();
-      SpeedTracerLogger.start(CompilerEventType.GET_ALL_REBINDS);
+      Event getAllRebindsEvent = SpeedTracerLogger.start(CompilerEventType.GET_ALL_REBINDS);
       for (int i = 0; i < getPermuationCount(); ++i) {
         String resultTypeName = rebindOracles[i].rebind(logger, requestTypeName);
         answers.add(resultTypeName);
@@ -341,7 +342,7 @@
         permutations[i].putRebindAnswer(requestTypeName, resultTypeName);
       }
       String[] result = Util.toArray(String.class, answers);
-      SpeedTracerLogger.end(CompilerEventType.GET_ALL_REBINDS);
+      getAllRebindsEvent.end();
       return result;
     }
 
@@ -449,8 +450,8 @@
    */
   public static boolean validate(TreeLogger logger, JJSOptions jjsOptions,
       ModuleDef module, File genDir, File dumpSignatureFile) {
+    Event validateEvent = SpeedTracerLogger.start(CompilerEventType.VALIDATE);
     try {
-      SpeedTracerLogger.start(CompilerEventType.VALIDATE);
       CompilationState compilationState = module.getCompilationState(logger);
       if (dumpSignatureFile != null) {
         // Dump early to avoid generated types.
@@ -486,7 +487,7 @@
       // Already logged.
       return false;
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.VALIDATE);
+      validateEvent.end();
     }
   }
 
@@ -494,8 +495,8 @@
       ModuleDef module, int permutationBase,
       PropertyPermutations allPermutations, File genDir, File dumpSignatureFile) {
 
+    Event precompileEvent = SpeedTracerLogger.start(CompilerEventType.PRECOMPILE);
     try {
-      SpeedTracerLogger.start(CompilerEventType.PRECOMPILE);
       CompilationState compilationState = module.getCompilationState(logger);
       if (dumpSignatureFile != null) {
         // Dump early to avoid generated types.
@@ -545,7 +546,7 @@
       // cause has been logged.
       return null;
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.PRECOMPILE);
+      precompileEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
index 0f323d3..f8238821 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -34,6 +34,7 @@
 import com.google.gwt.dev.util.Util;
 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 java.io.File;
 import java.util.ArrayList;
@@ -395,7 +396,7 @@
   }
 
   public synchronized void refresh(TreeLogger logger) {
-    SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "refresh", "module", getName());
+    Event moduleDefEvent = SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "refresh", "module", getName());
     logger = logger.branch(TreeLogger.DEBUG, "Refreshing module '" + getName()
         + "'");
 
@@ -406,7 +407,7 @@
     if (lazyResourcesOracle != null) {
       lazyResourcesOracle.refresh(logger);
     }
-    SpeedTracerLogger.end(CompilerEventType.MODULE_DEF);
+    moduleDefEvent.end();
   }
 
   /**
@@ -445,7 +446,8 @@
    * @param logger Logs the activity.
    */
   synchronized void normalize(TreeLogger logger) {
-    SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "normalize");
+    Event moduleDefNormalize =
+        SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "normalize");
     // Normalize property providers.
     //
     for (Property current : getProperties()) {
@@ -491,7 +493,7 @@
           "No source path entries; expect subsequent failures", null);
     }
 
-    SpeedTracerLogger.end(CompilerEventType.MODULE_DEF);
+    moduleDefNormalize.end();
   }
 
   private void checkForSeedTypes(TreeLogger logger,
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
index 1ee4a40..fc4b521 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
@@ -20,6 +20,7 @@
 import com.google.gwt.dev.util.Util;
 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.xml.ReflectiveParser;
 import com.google.gwt.util.tools.Utility;
 
@@ -129,7 +130,7 @@
    */
   public static ModuleDef loadFromClassPath(TreeLogger logger,
       String moduleName, boolean refresh) throws UnableToCompleteException {
-    SpeedTracerLogger.start(
+    Event moduleDefLoadFromClassPathEvent = SpeedTracerLogger.start(
         CompilerEventType.MODULE_DEF, "phase", "loadFromClassPath", "moduleName", moduleName);
     try {
       // Look up the module's physical name; if null, we are either encountering
@@ -145,7 +146,7 @@
       ModuleDefLoader loader = new ModuleDefLoader();
       return loader.doLoadModule(logger, moduleName);
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.MODULE_DEF);
+      moduleDefLoadFromClassPathEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
index 47fdf30..9747eef 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
@@ -20,6 +20,7 @@
 import com.google.gwt.dev.javac.CompilationStateBuilder.CompileMoreLater;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -83,7 +84,7 @@
 
   public void addGeneratedCompilationUnits(TreeLogger logger,
       Collection<GeneratedUnit> generatedUnits) {
-    SpeedTracerLogger.start(DevModeEventType.GENERATED_UNITS_ADD);
+    Event generatedUnitsAddEvent = SpeedTracerLogger.start(DevModeEventType.GENERATED_UNITS_ADD);
 
     try {
       logger = logger.branch(TreeLogger.DEBUG, "Adding '"
@@ -92,7 +93,7 @@
           logger, generatedUnits);
       assimilateUnits(logger, newUnits);
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.GENERATED_UNITS_ADD);
+      generatedUnitsAddEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index 36a653d..d3ee035 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -24,6 +24,7 @@
 import com.google.gwt.dev.resource.Resource;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import org.apache.commons.collections.map.AbstractReferenceMap;
 import org.apache.commons.collections.map.ReferenceIdentityMap;
@@ -134,11 +135,12 @@
     
     public Collection<CompilationUnit> addGeneratedTypes(TreeLogger logger,
         Collection<GeneratedUnit> generatedUnits) {
-      SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+      Event compilationStateBuilderProcess =
+          SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
       try {
         return doBuildGeneratedTypes(logger, generatedUnits, this);
       } finally {
-        SpeedTracerLogger.end(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+        compilationStateBuilderProcess.end();
       }
     }
 
@@ -194,21 +196,23 @@
 
   public static CompilationState buildFrom(TreeLogger logger,
       Set<Resource> resources) {
-     SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+    Event compilationStateBuilderProcessEvent =
+        SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
      try {
        return instance.doBuildFrom(logger, resources, null);
      } finally {
-       SpeedTracerLogger.end(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+       compilationStateBuilderProcessEvent.end();
      }
   }
 
   public static CompilationState buildFrom(TreeLogger logger,
       Set<Resource> resources, AdditionalTypeProviderDelegate delegate) {
-    SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+    Event compilationStateBuilderProcessEvent =
+        SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
     try {
       return instance.doBuildFrom(logger, resources, delegate);
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+      compilationStateBuilderProcessEvent.end();
     }
   }
 
@@ -283,7 +287,8 @@
    */
   public synchronized CompilationState doBuildFrom(TreeLogger logger,
       Set<Resource> resources, AdditionalTypeProviderDelegate compilerDelegate) {
-    SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+    Event compilationStateBuilderProcess =
+        SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
     
     try {
       Map<String, CompilationUnit> resultUnits = new HashMap<String, CompilationUnit>();
@@ -327,7 +332,7 @@
                                      Collections.<ContentId> emptySet());
       return new CompilationState(logger, resultUnits.values(), compileMoreLater);
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);
+      compilationStateBuilderProcess.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
index c89ca5b..106ffde 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
@@ -22,6 +22,7 @@
 import com.google.gwt.dev.util.collect.Sets;
 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.util.tools.Utility;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -317,7 +318,7 @@
    */
   public static List<CompilationUnit> compile(
       Collection<CompilationUnitBuilder> builders) {
-    SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);
+    Event jdtCompilerEvent = SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);
 
     try {
       DefaultUnitProcessor processor = new DefaultUnitProcessor();
@@ -326,7 +327,7 @@
       compiler.doCompile(builders);
       return processor.getResults();
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.JDT_COMPILER);
+      jdtCompilerEvent.end();
     }
   }
 
@@ -498,11 +499,11 @@
       return false;
     }
 
-    SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER, "phase", "compile");
+    Event jdtCompilerEvent = SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER, "phase", "compile");
     compilerImpl = new CompilerImpl();
     compilerImpl.compile(icus.toArray(new ICompilationUnit[icus.size()]));
     compilerImpl = null;
-    SpeedTracerLogger.end(CompilerEventType.JDT_COMPILER);
+    jdtCompilerEvent.end();
     lazyContentIdMap = null;
     return true;
   }
diff --git a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
index 27b27a1..2cf676c 100644
--- a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
@@ -34,6 +34,7 @@
 import com.google.gwt.dev.util.collect.IdentityHashMap;
 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.util.tools.Utility;
 
 import java.io.ByteArrayOutputStream;
@@ -423,7 +424,7 @@
     setCurrentGenerator(generatorClass);
 
     long before = System.currentTimeMillis();
-    SpeedTracerLogger.start(CompilerEventType.GENERATOR, "class",
+    Event generatorEvent = SpeedTracerLogger.start(CompilerEventType.GENERATOR, "class",
         generator.getClass().getName(), "type", typeName);
     try {
       String className = generator.generate(logger, this, typeName);
@@ -446,7 +447,7 @@
           + "' threw an exception while rebinding '" + typeName + "'", e);
       throw new UnableToCompleteException();
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.GENERATOR);
+      generatorEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
index 2111c51..ec79ee4 100644
--- a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
+++ b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
@@ -58,6 +58,7 @@
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Annotation;
@@ -294,7 +295,7 @@
    */
   public void addNewUnits(TreeLogger logger,
       Collection<CompilationUnit> units) {
-    SpeedTracerLogger.start(CompilerEventType.TYPE_ORACLE_MEDIATOR);
+    Event typeOracleMediatorEvent = SpeedTracerLogger.start(CompilerEventType.TYPE_ORACLE_MEDIATOR);
     // First collect all class data.
     classMap = new HashMap<String, CollectClassData>();
     for (CompilationUnit unit : units) {
@@ -364,7 +365,7 @@
     allMethodArgs = null;
     classMap = null;
     classMapType = null;
-    SpeedTracerLogger.end(CompilerEventType.TYPE_ORACLE_MEDIATOR);
+    typeOracleMediatorEvent.end();
   }
 
   /**
@@ -547,7 +548,7 @@
    * creating JRealClassType/JGenericType objects.
    */
   private CollectClassData processClass(CompiledClass compiledClass) {
-    SpeedTracerLogger.start(DevModeEventType.VISIT_CLASS_FILE);
+    Event visitClassFileEvent = SpeedTracerLogger.start(DevModeEventType.VISIT_CLASS_FILE);
     
     byte[] classBytes = compiledClass.getBytes();
     ClassReader reader = new ClassReader(classBytes);
@@ -558,7 +559,7 @@
     }
     reader.accept(cv, 0);
     
-    SpeedTracerLogger.end(DevModeEventType.VISIT_CLASS_FILE);    
+    visitClassFileEvent.end();    
     return mcv;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java b/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
index e972336..24c6261 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
@@ -24,6 +24,7 @@
 import com.google.gwt.dev.util.Empty;
 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 org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
@@ -47,10 +48,11 @@
       TreeLogger logger, String[] seedTypeNames,
       RebindPermutationOracle rebindPermOracle, TypeLinker linker)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.GET_COMPILATION_UNITS);
+    Event getCompilationUnitsEvent =
+        SpeedTracerLogger.start(CompilerEventType.GET_COMPILATION_UNITS);
     CompilationResults results = new WebModeCompilerFrontEnd(rebindPermOracle,
         linker).getCompilationUnitDeclarations(logger, seedTypeNames);
-    SpeedTracerLogger.end(CompilerEventType.GET_COMPILATION_UNITS);
+    getCompilationUnitsEvent.end();
     return results;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java b/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
index a2ad9f0..8d3ead7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
@@ -31,6 +31,7 @@
 import com.google.gwt.dev.util.JsniRef;
 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 java.util.ArrayList;
 import java.util.Collections;
@@ -124,9 +125,10 @@
   }
 
   public static void exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.ARTIFICIAL_RESCUE_REORDER);
+    Event artificialRescueReorderEvent =
+        SpeedTracerLogger.start(CompilerEventType.ARTIFICIAL_RESCUE_REORDER);
     new ArtificialRescueRecorder(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.ARTIFICIAL_RESCUE_REORDER);
+    artificialRescueReorderEvent.end();
   }
 
   private final JInterfaceType artificialRescueType;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index b6419ba..48025b4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -124,6 +124,7 @@
 import com.google.gwt.dev.util.collect.Maps;
 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.soyc.SoycDashboard;
 import com.google.gwt.soyc.io.ArtifactsOutputDirectory;
 
@@ -221,7 +222,8 @@
   public static PermutationResult compilePermutation(TreeLogger logger,
       UnifiedAst unifiedAst, Permutation permutation)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.JJS_COMPILE_PERMUTATION);
+    Event jjsCompilePermutationEvent =
+        SpeedTracerLogger.start(CompilerEventType.JJS_COMPILE_PERMUTATION);
     InternalCompilerException.preload();
     PropertyOracle[] propertyOracles = permutation.getPropertyOracles();
     int permutationId = permutation.getId();
@@ -412,7 +414,7 @@
     } catch (Throwable e) {
       throw logAndTranslateException(logger, e);
     } finally {
-      SpeedTracerLogger.end(CompilerEventType.JJS_COMPILE_PERMUTATION);
+      jjsCompilePermutationEvent.end();
     }
   }
 
@@ -586,10 +588,10 @@
       Set<String> rebindRequests = new HashSet<String>();
       RecordRebinds.exec(jprogram, rebindRequests);
 
-      SpeedTracerLogger.start(CompilerEventType.CREATE_UNIFIED_AST);
+      Event createUnifiedAstEvent = SpeedTracerLogger.start(CompilerEventType.CREATE_UNIFIED_AST);
       UnifiedAst result = new UnifiedAst(options, new AST(jprogram, jsProgram),
           singlePermutation, rebindRequests);
-      SpeedTracerLogger.end(CompilerEventType.CREATE_UNIFIED_AST);
+      createUnifiedAstEvent.end();
       return result;
     } catch (Throwable e) {
       throw logAndTranslateException(logger, e);
@@ -609,34 +611,34 @@
      */
     jprogram.beginOptimizations();
 
-    SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE);
+    Event draftOptimizeEvent = SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE);
 
-    SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
+    Event draftFinalizerEvent = SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
         "finalizer");
     Finalizer.exec(jprogram);
-    SpeedTracerLogger.end(CompilerEventType.DRAFT_OPTIMIZE);
+    draftFinalizerEvent.end();
 
-    SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
-        "makeCallsStatic");
+    Event draftMakeCallsStaticEvent =
+        SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase", "makeCallsStatic");
     MakeCallsStatic.exec(jprogram);
-    SpeedTracerLogger.end(CompilerEventType.DRAFT_OPTIMIZE);
+    draftMakeCallsStaticEvent.end();
 
-    SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
-        "recomputeAfterOptimizations");
+    Event draftRecomputeEvent = SpeedTracerLogger.start(
+        CompilerEventType.DRAFT_OPTIMIZE, "phase", "recomputeAfterOptimizations");
     jprogram.typeOracle.recomputeAfterOptimizations();
-    SpeedTracerLogger.end(CompilerEventType.DRAFT_OPTIMIZE);
+    draftRecomputeEvent.end();
 
-    SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
+    Event draftDeadCode = SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE, "phase",
         "deadCodeElimination");
     DeadCodeElimination.exec(jprogram);
-    SpeedTracerLogger.end(CompilerEventType.DRAFT_OPTIMIZE);
+    draftDeadCode.end();
 
-    SpeedTracerLogger.end(CompilerEventType.DRAFT_OPTIMIZE);
+    draftOptimizeEvent.end();
   }
 
   protected static void optimize(JJSOptions options, JProgram jprogram)
       throws InterruptedException {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE);
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE);
     /*
      * Record the beginning of optimizations; this turns on certain checks that
      * guard against problematic late construction of things like class
@@ -646,7 +648,7 @@
 
     do {
       if (Thread.interrupted()) {
-        SpeedTracerLogger.end(CompilerEventType.OPTIMIZE);
+        optimizeEvent.end();
         throw new InterruptedException();
       }
       maybeDumpAST(jprogram);
@@ -656,12 +658,12 @@
       // Just run it once, because it is very time consuming
       DataflowOptimizer.exec(jprogram);
     }
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE);
+    optimizeEvent.end();
   }
 
   protected static boolean optimizeLoop(JProgram jprogram,
       boolean isAggressivelyOptimize) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "phase", "loop");
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "phase", "loop");
     // Recompute clinits each time, they can become empty.
     jprogram.typeOracle.recomputeAfterOptimizations();
     // jprogram.methodOracle = MethodOracleBuilder.buildMethodOracle(jprogram);
@@ -698,7 +700,7 @@
 
     // prove that any types that have been culled from the main tree are
     // unreferenced due to type tightening?
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE);
+    optimizeEvent.end();
 
     return didChange;
   }
@@ -706,7 +708,7 @@
   static void checkForErrors(TreeLogger logger,
       CompilationUnitDeclaration[] cuds, boolean itemizeErrors)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.CHECK_FOR_ERRORS);
+    Event checkForErrorsEvent = SpeedTracerLogger.start(CompilerEventType.CHECK_FOR_ERRORS);
     boolean compilationFailed = false;
     if (cuds.length == 0) {
       compilationFailed = true;
@@ -747,7 +749,7 @@
         }
       }
     }
-    SpeedTracerLogger.end(CompilerEventType.CHECK_FOR_ERRORS);
+    checkForErrorsEvent.end();
     if (compilationFailed) {
       logger.log(TreeLogger.ERROR, "Cannot proceed due to previous errors",
           null);
@@ -818,7 +820,7 @@
   private static void findEntryPoints(TreeLogger logger,
       RebindPermutationOracle rpo, String[] mainClassNames, JProgram program)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.FIND_ENTRY_POINTS);
+    Event findEntryPointsEvent = SpeedTracerLogger.start(CompilerEventType.FIND_ENTRY_POINTS);
     SourceInfo sourceInfo = program.createSourceInfoSynthetic(
         JavaToJavaScriptCompiler.class, "Bootstrap method");
     JMethod bootStrapMethod = program.createMethod(sourceInfo, "init",
@@ -880,7 +882,7 @@
       }
     }
     program.addEntryMethod(bootStrapMethod);
-    SpeedTracerLogger.end(CompilerEventType.FIND_ENTRY_POINTS);
+    findEntryPointsEvent.end();
   }
 
   private static JMethod findMainMethod(JDeclaredType declaredType) {
@@ -939,7 +941,7 @@
        * Reorder function decls to improve compression ratios. Also restructures
        * the top level blocks into sub-blocks if they exceed 32767 statements.
        */
-      SpeedTracerLogger.start(CompilerEventType.FUNCTION_CLUSTER);
+      Event functionClusterEvent = SpeedTracerLogger.start(CompilerEventType.FUNCTION_CLUSTER);
       JsFunctionClusterer clusterer = new JsFunctionClusterer(out.toString(),
           v.getStatementRanges());
       // only cluster for obfuscated mode
@@ -947,7 +949,7 @@
           && options.getOutput() == JsOutputOption.OBFUSCATED) {
         clusterer.exec();
       }
-      SpeedTracerLogger.end(CompilerEventType.FUNCTION_CLUSTER);
+      functionClusterEvent.end();
       // rewrite top-level blocks to limit the number of statements
       JsIEBlockTextTransformer ieXformer = new JsIEBlockTextTransformer(
           clusterer);
@@ -1019,38 +1021,38 @@
 
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
-    SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+    Event soycEvent = SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS);
 
-    SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS,
-        "phase", "recordSplitPoints");
+    Event recordSplitPoints = SpeedTracerLogger.start(
+        CompilerEventType.MAKE_SOYC_ARTIFACTS, "phase", "recordSplitPoints");
     SplitPointRecorder.recordSplitPoints(jprogram, baos, logger);
     SyntheticArtifact splitPoints = new SyntheticArtifact(
         SoycReportLinker.class, "splitPoints" + permutationId + ".xml.gz",
         baos.toByteArray());
     soycArtifacts.add(splitPoints);
-    SpeedTracerLogger.end(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+    recordSplitPoints.end();
 
     SyntheticArtifact sizeMaps = null;
     if (sizeBreakdowns != null) {
-      SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS,
-          "phase", "recordSizeMap");
+      Event recordSizeMap =
+          SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS, "phase", "recordSizeMap");
       baos.reset();
       SizeMapRecorder.recordMap(logger, baos, sizeBreakdowns, jjsmap,
           obfuscateMap);
       sizeMaps = new SyntheticArtifact(SoycReportLinker.class, "stories"
           + permutationId + ".xml.gz", baos.toByteArray());
       soycArtifacts.add(sizeMaps);
-      SpeedTracerLogger.end(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+      recordSizeMap.end();
     }
 
     if (sourceInfoMaps != null) {
-      SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS,
-          "phase", "recordStories");
+      Event recordStories =
+          SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS, "phase", "recordStories");
       baos.reset();
       StoryRecorder.recordStories(logger, baos, sourceInfoMaps, js);
       soycArtifacts.add(new SyntheticArtifact(SoycReportLinker.class,
           "detailedStories" + permutationId + ".xml.gz", baos.toByteArray()));
-      SpeedTracerLogger.end(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+      recordStories.end();
     }
 
     if (dependencies != null) {
@@ -1063,8 +1065,8 @@
     }
 
     if (sizeBreakdowns != null) {
-      SpeedTracerLogger.start(CompilerEventType.MAKE_SOYC_ARTIFACTS,
-          "phase", "generateCompileReport");
+      Event generateCompileReport = SpeedTracerLogger.start(
+          CompilerEventType.MAKE_SOYC_ARTIFACTS, "phase", "generateCompileReport");
       ArtifactsOutputDirectory outDir = new ArtifactsOutputDirectory();
       SoycDashboard dashboard = new SoycDashboard(outDir);
       dashboard.startNewPermutation(Integer.toString(permutationId));
@@ -1087,10 +1089,10 @@
       }
       dashboard.generateForOnePermutation();
       soycArtifacts.addAll(outDir.getArtifacts());
-      SpeedTracerLogger.end(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+      generateCompileReport.end();
     }
 
-    SpeedTracerLogger.end(CompilerEventType.MAKE_SOYC_ARTIFACTS);
+    soycEvent.end();
 
     return soycArtifacts;
   }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
index 196c96b..c354397 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
@@ -29,6 +29,7 @@
 import com.google.gwt.dev.jjs.ast.JType;
 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;
 
 /**
  * Removes all assertion statements from the AST.
@@ -56,9 +57,10 @@
   }
 
   public static void exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.ASSERTION_NORMALIZER);
+    Event assertionNormalizerEvent =
+        SpeedTracerLogger.start(CompilerEventType.ASSERTION_NORMALIZER);
     new AssertionNormalizer(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.ASSERTION_NORMALIZER);
+    assertionNormalizerEvent.end();
   }
 
   private static String getAssertMethodSuffix(JExpression arg) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionRemover.java b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionRemover.java
index 71dfb82..70fc984 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionRemover.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionRemover.java
@@ -23,6 +23,7 @@
 import com.google.gwt.dev.jjs.ast.JStatement;
 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;
 
 /**
  * Removes all assertion statements from the AST.
@@ -50,9 +51,9 @@
   }
 
   public static void exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.ASSERTION_REMOVER);
+    Event assertionRemoverEvent = SpeedTracerLogger.start(CompilerEventType.ASSERTION_REMOVER);
     new AssertionRemover(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.ASSERTION_REMOVER);
+    assertionRemoverEvent.end();
   }
 
   private final JProgram program;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index d7d87c5..02ee4e8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -46,6 +46,7 @@
 import com.google.gwt.dev.js.ast.JsProgram;
 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 org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -539,11 +540,11 @@
       CompilationResults results, JsProgram jsProgram, TypeLinker linker) {
     BuildTypeMap btm = new BuildTypeMap(typeMap, jsProgram, linker,
         results.compiledUnits);
-    SpeedTracerLogger.start(CompilerEventType.BUILD_TYPE_MAP);
+    Event buildTypeMapEvent = SpeedTracerLogger.start(CompilerEventType.BUILD_TYPE_MAP);
     btm.createPeersForUnits();
     btm.resolveExternalTypes(results.binaryBindings);
     TypeDeclaration[] result = btm.createPeersForNonTypeDecls();
-    SpeedTracerLogger.end(CompilerEventType.BUILD_TYPE_MAP);
+    buildTypeMapEvent.end();
     return result;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
index e06f873..5ad75c9 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
@@ -57,6 +57,7 @@
 import com.google.gwt.dev.util.collect.HashSet;
 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 java.util.ArrayList;
 import java.util.LinkedHashSet;
@@ -255,11 +256,11 @@
       // Don't do anything if there is no call to runAsync
       return;
     }
-    SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER);
+    Event codeSplitterEvent = SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER);
     dependencyRecorder.open();
     new CodeSplitter(logger, jprogram, jsprogram, map, dependencyRecorder).execImpl();
     dependencyRecorder.close();
-    SpeedTracerLogger.end(CompilerEventType.CODE_SPLITTER);
+    codeSplitterEvent.end();
   }
 
   /**
@@ -268,7 +269,8 @@
    */
   public static int findSplitPoint(String refString, JProgram program,
       TreeLogger branch) throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "findSplitPoint");
+    Event codeSplitterEvent =
+        SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "findSplitPoint");
     Map<JMethod, List<Integer>> methodToSplitPoint = reverseByEnclosingMethod(program.getRunAsyncReplacements());
     Map<String, List<Integer>> nameToSplitPoint = reverseByName(program.getRunAsyncReplacements());
 
@@ -328,7 +330,7 @@
       throw new UnableToCompleteException();
     }
     int result = splitPoints.get(0);
-    SpeedTracerLogger.end(CompilerEventType.CODE_SPLITTER);
+    codeSplitterEvent.end();
     return result;
   }
 
@@ -368,7 +370,8 @@
    */
   public static void pickInitialLoadSequence(TreeLogger logger,
       JProgram program, Properties properties) throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "pickInitialLoadSequence");
+    Event codeSplitterEvent = SpeedTracerLogger.start(
+        CompilerEventType.CODE_SPLITTER, "phase", "pickInitialLoadSequence");
     TreeLogger branch = logger.branch(TreeLogger.TRACE,
         "Looking up initial load sequence for split points");
     LinkedHashSet<Integer> initialLoadSequence = new LinkedHashSet<Integer>();
@@ -400,7 +403,7 @@
     installInitialLoadSequenceField(program, initialLoadSequence);
     program.setSplitPointInitialSequence(new ArrayList<Integer>(
         initialLoadSequence));
-    SpeedTracerLogger.end(CompilerEventType.CODE_SPLITTER);
+    codeSplitterEvent.end();
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
index 4cadb3b..a69eb37 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
@@ -65,6 +65,7 @@
 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
 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 java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -1810,7 +1811,8 @@
   }
 
   private boolean execImpl(JNode node) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "DeadCodeElimination");
+    Event optimizeEvent =
+        SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "DeadCodeElimination");
     boolean didChange = false;
     while (true) {
       DeadCodeVisitor deadCodeVisitor = new DeadCodeVisitor();
@@ -1820,7 +1822,7 @@
       }
       didChange = true;
     }
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Finalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Finalizer.java
index 2f52809..be9a6a3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Finalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Finalizer.java
@@ -37,6 +37,7 @@
 import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
 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 java.util.HashSet;
 import java.util.Set;
@@ -204,10 +205,10 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(
+    Event optimizeEvent = SpeedTracerLogger.start(
         CompilerEventType.OPTIMIZE, "optimizer", "Finalizer");
     boolean didChange = new Finalizer().execImpl(program);
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java b/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
index b9b078f..d784956 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
@@ -27,6 +27,7 @@
 import com.google.gwt.dev.jjs.ast.JProgram;
 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;
 
 /**
  * Most autoboxing is handled by {@link GenerateJavaAST}. The only cases it
@@ -91,10 +92,11 @@
   }
 
   public static void exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.FIX_ASSIGNMENT_TO_UNBOX);
+    Event fixAssignmentToUnboxEvent =
+        SpeedTracerLogger.start(CompilerEventType.FIX_ASSIGNMENT_TO_UNBOX);
     new CompoundAssignmentToUnboxNormalizer(program).accept(program);
     new FixAssignmentToUnbox(program).accept(program);
-    SpeedTracerLogger.end(CompilerEventType.FIX_ASSIGNMENT_TO_UNBOX);
+    fixAssignmentToUnboxEvent.end();
   }
 
   private final AutoboxUtils autoboxUtils;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index 8606170..31c48de 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -105,6 +105,7 @@
 import com.google.gwt.dev.util.collect.Lists;
 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 org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
@@ -3065,7 +3066,7 @@
    */
   public static void exec(TypeDeclaration[] types, TypeMap typeMap,
       JProgram jprogram, JsProgram jsProgram, JJSOptions options) {
-    SpeedTracerLogger.start(CompilerEventType.GENERATE_JAVA_AST);
+    Event generateJavaAstEvent = SpeedTracerLogger.start(CompilerEventType.GENERATE_JAVA_AST);
     // Construct the basic AST.
     JavaASTGenerationVisitor v = new JavaASTGenerationVisitor(typeMap,
         jprogram, options);
@@ -3080,7 +3081,7 @@
     // Process JSNI.
     Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap = v.getJsniMethodMap();
     new JsniRefGenerationVisitor(jprogram, jsProgram, jsniMethodMap).accept(jprogram);
-    SpeedTracerLogger.end(CompilerEventType.GENERATE_JAVA_AST);
+    generateJavaAstEvent.end();
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
index c63b854..f640c4d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
@@ -41,6 +41,7 @@
 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
 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 java.util.Stack;
 
@@ -271,9 +272,9 @@
   }
 
   public static void exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.NORMALIZER);
+    Event normalizerEvent = SpeedTracerLogger.start(CompilerEventType.NORMALIZER);
     new JavaScriptObjectNormalizer(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.NORMALIZER);
+    normalizerEvent.end();
   }
 
   private final JProgram program;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
index 786f9ee..413ccbb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
@@ -45,6 +45,7 @@
 import com.google.gwt.dev.js.ast.JsThisRef;
 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 java.util.ArrayList;
 import java.util.HashSet;
@@ -350,9 +351,9 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "MakeCallsStatic");
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "MakeCallsStatic");
     boolean didChange = new MakeCallsStatic(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java
index 6e69a40..b381676 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java
@@ -29,6 +29,7 @@
 import com.google.gwt.dev.jjs.ast.JReferenceType;
 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;
 
 /**
  * Update polymorphic method calls to tighter bindings based on the type of the
@@ -140,11 +141,10 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(
+    Event optimizeEvent = SpeedTracerLogger.start(
         CompilerEventType.OPTIMIZE, "optimizer", "TypeTightener");
     boolean didChange = new MethodCallTightener(program).execImpl();
-    SpeedTracerLogger.end(
-        CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
index 37043c1..a33ab89 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
@@ -38,6 +38,7 @@
 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
 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 java.util.HashSet;
 import java.util.List;
@@ -490,11 +491,10 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(
+    Event optimizeEvent = SpeedTracerLogger.start(
         CompilerEventType.OPTIMIZE, "optimizer", "MethodInliner");
     boolean didChange = new MethodInliner(program).execImpl();
-    SpeedTracerLogger.end(
-        CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 067d3b9..3efd210 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -52,6 +52,7 @@
 import com.google.gwt.dev.js.ast.JsFunction;
 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 java.util.ArrayList;
 import java.util.HashMap;
@@ -527,9 +528,9 @@
   }
 
   public static boolean exec(JProgram program, boolean noSpecialTypes) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "Pruner");
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "Pruner");
     boolean didChange = new Pruner(program, noSpecialTypes).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/RecordRebinds.java b/dev/core/src/com/google/gwt/dev/jjs/impl/RecordRebinds.java
index d171690..64ff60f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/RecordRebinds.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/RecordRebinds.java
@@ -22,6 +22,7 @@
 import com.google.gwt.dev.jjs.ast.JVisitor;
 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 java.util.Set;
 
@@ -45,9 +46,9 @@
   }
 
   public static void exec(JProgram program, Set<String> liveRebindRequests) {
-    SpeedTracerLogger.start(CompilerEventType.RECORD_REBINDS);
+    Event recordRebindsEvent = SpeedTracerLogger.start(CompilerEventType.RECORD_REBINDS);
     new RecordRebinds(program, liveRebindRequests).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.RECORD_REBINDS);
+    recordRebindsEvent.end();
   }
 
   private final JProgram program;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
index 1eb438d..84302ec 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
@@ -38,6 +38,7 @@
 import com.google.gwt.dev.util.JsniRef;
 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 java.util.ArrayList;
 import java.util.List;
@@ -143,9 +144,9 @@
 
   public static boolean exec(TreeLogger logger, JProgram program,
       RebindPermutationOracle rpo) {
-    SpeedTracerLogger.start(CompilerEventType.REPLACE_REBINDS);
+    Event replaceRebindsEvent = SpeedTracerLogger.start(CompilerEventType.REPLACE_REBINDS);
     boolean didChange = new ReplaceRebinds(logger, program, rpo).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.REPLACE_REBINDS);
+    replaceRebindsEvent.end();
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
index 1c91a5c..e39f4c0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
@@ -32,6 +32,7 @@
 import com.google.gwt.dev.jjs.ast.JType;
 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 java.io.Serializable;
 import java.util.ArrayList;
@@ -228,11 +229,12 @@
 
   public static void exec(TreeLogger logger, JProgram program)
       throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "ReplaceRunAsyncs");
+    Event codeSplitterEvent =
+        SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "ReplaceRunAsyncs");
     TreeLogger branch = logger.branch(TreeLogger.TRACE,
         "Replacing GWT.runAsync with island loader calls");
     new ReplaceRunAsyncs(branch, program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.CODE_SPLITTER);
+    codeSplitterEvent.end();
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/SameParameterValueOptimizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/SameParameterValueOptimizer.java
index a813357..93ca794 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/SameParameterValueOptimizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/SameParameterValueOptimizer.java
@@ -34,6 +34,7 @@
 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
 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 java.util.HashSet;
 import java.util.IdentityHashMap;
@@ -181,11 +182,10 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(
+    Event optimizeEvent = SpeedTracerLogger.start(
         CompilerEventType.OPTIMIZE, "optimizer", "SameParameterValueOptimizer");
     boolean didChange = new SameParameterValueOptimizer(program).execImpl(program);
-    SpeedTracerLogger.end(
-        CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
index 66c8e31..d05bf01 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
@@ -55,6 +55,7 @@
 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
 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 java.util.ArrayList;
 import java.util.HashSet;
@@ -806,10 +807,10 @@
   }
 
   public static boolean exec(JProgram program) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE,
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE,
         "optimizer", "TypeTightener");
     boolean didChange = new TypeTightener(program).execImpl();
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE, "didChange", "" + didChange);
+    optimizeEvent.end("didChange", "" + didChange);
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizer.java
index 4ad55a4..8341e6c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizer.java
@@ -35,14 +35,15 @@
 import com.google.gwt.dev.util.Preconditions;
 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;
 
 /**
  */
 public class DataflowOptimizer {
   public static boolean exec(JProgram jprogram, JNode node) {
-    SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "DataflowOptimizer");
+    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", "DataflowOptimizer");
     boolean didChange = new DataflowOptimizer(jprogram).execImpl(node);
-    SpeedTracerLogger.end(CompilerEventType.OPTIMIZE);
+    optimizeEvent.end();
     return didChange;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
index 18bdf48..2b7e547 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
@@ -20,6 +20,7 @@
 import com.google.gwt.dev.resource.ResourceOracle;
 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.msg.Message0;
 import com.google.gwt.dev.util.msg.Message1String;
 
@@ -306,7 +307,8 @@
    * @param logger status and error details are written here
    */
   public void refresh(TreeLogger logger) {
-    SpeedTracerLogger.start(CompilerEventType.RESOURCE_ORACLE, "phase", "refresh");
+    Event resourceOracle =
+        SpeedTracerLogger.start(CompilerEventType.RESOURCE_ORACLE, "phase", "refresh");
     TreeLogger refreshBranch = Messages.REFRESHING_RESOURCES.branch(logger,
         null);
 
@@ -362,7 +364,7 @@
     exposedResources = Collections.unmodifiableSet(externalSet);
     exposedResourceMap = Collections.unmodifiableMap(externalMap);
     exposedPathNames = Collections.unmodifiableSet(externalMap.keySet());
-    SpeedTracerLogger.end(CompilerEventType.RESOURCE_ORACLE);
+    resourceOracle.end();
   }
 
   public void setPathPrefixes(PathPrefixSet pathPrefixSet) {
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
index a42cd89..744649e 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
@@ -21,6 +21,7 @@
 import com.google.gwt.dev.util.Name.BinaryName;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -315,7 +316,7 @@
    * Runs the module's user startup code.
    */
   public final void onLoad(TreeLogger logger) throws UnableToCompleteException {
-    SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_LOAD);
+    Event moduleSpaceLoad = SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_LOAD);
 
     // Tell the host we're ready for business.
     //
@@ -374,11 +375,11 @@
             invokeNativeVoid("fireOnModuleLoadStart", null,
                 new Class[] {String.class}, new Object[] {entryPointTypeName});
 
-            SpeedTracerLogger.start(DevModeEventType.ON_MODULE_LOAD);
+            Event onModuleLoadEvent = SpeedTracerLogger.start(DevModeEventType.ON_MODULE_LOAD);
             try {
               onModuleLoad.invoke(module);
             } finally {
-              SpeedTracerLogger.end(DevModeEventType.ON_MODULE_LOAD);
+              onModuleLoadEvent.end();
             }
           }
         } finally {
@@ -411,7 +412,7 @@
       logger.log(TreeLogger.ERROR, unableToLoadMessage, caught);
       throw new UnableToCompleteException();
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.MODULE_SPACE_LOAD);
+      moduleSpaceLoad.end();
     }
   }
 
@@ -423,7 +424,8 @@
     String msg = null;
     String resultName = null;
 
-    SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_REBIND_AND_CREATE);
+    Event moduleSpaceRebindAndCreate =
+        SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_REBIND_AND_CREATE);
     try {
       // Rebind operates on source-level names.
       //
@@ -454,7 +456,7 @@
     } catch (InvocationTargetException e) {
       caught = e.getTargetException();
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.MODULE_SPACE_REBIND_AND_CREATE);
+      moduleSpaceRebindAndCreate.end();
     }
 
     // Always log here because sometimes this method gets called from static
@@ -593,7 +595,7 @@
    */
   private Class<?> loadClassFromSourceName(String sourceName)
       throws ClassNotFoundException {
-    SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_CLASS_LOAD);
+    Event moduleSpaceClassLoad = SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_CLASS_LOAD);
     try {
       String toTry = sourceName;
       while (true) {
@@ -611,7 +613,7 @@
         }
       }
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.MODULE_SPACE_CLASS_LOAD);
+      moduleSpaceClassLoad.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
index 0e81845..84560bd 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
@@ -20,6 +20,7 @@
 import com.google.gwt.dev.shell.JsValue.DispatchObject;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.util.List;
 import java.util.Set;
@@ -104,7 +105,7 @@
       Object[] args) throws Throwable {
     TreeLogger branch = host.getLogger().branch(TreeLogger.SPAM,
         "Invoke native method " + name, null);
-    SpeedTracerLogger.start(DevModeEventType.JAVA_TO_JS_CALL);
+    Event javaToJsCallEvent = SpeedTracerLogger.start(DevModeEventType.JAVA_TO_JS_CALL);
 
     CompilingClassLoader isolatedClassLoader = getIsolatedClassLoader();
     JsValueOOPHM jsthis = new JsValueOOPHM();
@@ -129,7 +130,7 @@
       branch.log(TreeLogger.SPAM, "exception thrown", t);
       throw t;
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.JAVA_TO_JS_CALL);
+      javaToJsCallEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java b/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
index 0ce8bc8..8eef148 100644
--- a/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
+++ b/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
@@ -23,6 +23,7 @@
 import com.google.gwt.dev.shell.JsValue.DispatchObject;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.lang.reflect.Member;
 import java.util.Collections;
@@ -98,7 +99,7 @@
   @Override
   public ExceptionOrReturnValue invoke(BrowserChannelServer channel,
       Value thisVal, int methodDispatchId, Value[] args) {
-    SpeedTracerLogger.start(DevModeEventType.JS_TO_JAVA_CALL);
+    Event jsToJavaCallEvent = SpeedTracerLogger.start(DevModeEventType.JS_TO_JAVA_CALL);
     ServerObjectsTable localObjects = channel.getJavaObjectsExposedInBrowser();
     ModuleSpace moduleSpace = moduleMap.get(channel);
     ModuleHandle moduleHandle = moduleHandleMap.get(channel);
@@ -160,7 +161,7 @@
           t.getClass(), t);
     }
     Value retVal = channel.convertFromJsValue(localObjects, jsRetVal);
-    SpeedTracerLogger.end(DevModeEventType.JS_TO_JAVA_CALL);
+    jsToJavaCallEvent.end();
     return new ExceptionOrReturnValue(exception, retVal);
   }
 
@@ -168,7 +169,7 @@
   public synchronized TreeLogger loadModule(BrowserChannelServer channel,
       String moduleName, String userAgent, String url, String tabKey,
       String sessionKey, byte[] userAgentIcon) {
-    SpeedTracerLogger.start(DevModeEventType.MODULE_INIT);
+    Event moduleInit = SpeedTracerLogger.start(DevModeEventType.MODULE_INIT);
     ModuleHandle moduleHandle = host.createModuleLogger(moduleName, userAgent,
         url, tabKey, sessionKey, channel, userAgentIcon);
     TreeLogger logger = moduleHandle.getLogger();
@@ -199,7 +200,7 @@
       moduleHandleMap.remove(channel);
       return null;
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.MODULE_INIT);
+      moduleInit.end();
     }
     return moduleHandle.getLogger();
   }
diff --git a/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java b/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
index c748f75..72d7305 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
@@ -24,6 +24,7 @@
 import com.google.gwt.dev.javac.StandardGeneratorContext;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.io.File;
 
@@ -84,7 +85,7 @@
       throws UnableToCompleteException {
     this.space = readySpace;
 
-    SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_HOST_READY);
+    Event moduleSpaceHostReadyEvent = SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_HOST_READY);
     try {
       // Establish an environment for JavaScript property providers to run.
       //
@@ -112,7 +113,7 @@
       //
       classLoader = new CompilingClassLoader(logger, compilationState, readySpace);
     } finally {
-      SpeedTracerLogger.end(DevModeEventType.MODULE_SPACE_HOST_READY);
+      moduleSpaceHostReadyEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/StandardRebindOracle.java b/dev/core/src/com/google/gwt/dev/shell/StandardRebindOracle.java
index f42e126..03b5059 100644
--- a/dev/core/src/com/google/gwt/dev/shell/StandardRebindOracle.java
+++ b/dev/core/src/com/google/gwt/dev/shell/StandardRebindOracle.java
@@ -26,6 +26,7 @@
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -51,7 +52,7 @@
 
     public String rebind(TreeLogger logger, String typeName,
         ArtifactAcceptor artifactAcceptor) throws UnableToCompleteException {
-      SpeedTracerLogger.start(DevModeEventType.REBIND);
+      Event rebindEvent = SpeedTracerLogger.start(DevModeEventType.REBIND);
       try {
         genCtx.setPropertyOracle(propOracle);
         String result = tryRebind(logger, typeName);
@@ -67,7 +68,7 @@
         }
         return result;
       } finally {
-        SpeedTracerLogger.end(DevModeEventType.REBIND);
+        rebindEvent.end();
       }
     }
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
index 9b7e61c..f85ba0a 100644
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
@@ -24,6 +24,7 @@
 import com.google.gwt.dev.shell.JsValueGlue;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -219,7 +220,7 @@
    */
   public byte[] rewrite(TypeOracle typeOracle, String className,
       byte[] classBytes, Map<String, String> anonymousClassMap) {
-    SpeedTracerLogger.start(DevModeEventType.CLASS_BYTES_REWRITE);
+    Event classBytesRewriteEvent = SpeedTracerLogger.start(DevModeEventType.CLASS_BYTES_REWRITE);
     String desc = toDescriptor(className);
     assert (!jsoIntfDescs.contains(desc));
 
@@ -247,7 +248,7 @@
     }
 
     new ClassReader(classBytes).accept(v, 0);
-    SpeedTracerLogger.end(DevModeEventType.CLASS_BYTES_REWRITE);
+    classBytesRewriteEvent.end();
     return writer.toByteArray();
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/util/Util.java b/dev/core/src/com/google/gwt/dev/util/Util.java
index cf1a3f2..48acd27 100644
--- a/dev/core/src/com/google/gwt/dev/util/Util.java
+++ b/dev/core/src/com/google/gwt/dev/util/Util.java
@@ -20,6 +20,7 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 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.util.tools.Utility;
 
 import org.w3c.dom.Attr;
@@ -1213,7 +1214,7 @@
    */
   public static void writeObjectAsFile(TreeLogger logger, File file,
       Object... objects) throws UnableToCompleteException {
-    SpeedTracerLogger.start(CompilerEventType.WRITE_OBJECT_AS_FILE);
+    Event writeObjectAsFileEvent = SpeedTracerLogger.start(CompilerEventType.WRITE_OBJECT_AS_FILE);
     FileOutputStream stream = null;
     try {
       // No need to check mkdirs result because an IOException will occur anyway
@@ -1226,7 +1227,7 @@
       throw new UnableToCompleteException();
     } finally {
       Utility.close(stream);
-      SpeedTracerLogger.end(CompilerEventType.WRITE_OBJECT_AS_FILE);
+      writeObjectAsFileEvent.end();
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
index d38763c..eb66b10 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
@@ -36,7 +36,7 @@
   PRECOMPILE("Precompile", "CornflowerBlue"), //
   RESOURCE_ORACLE("ResourceOracle", "GoldenRod"), //
   TYPE_ORACLE_MEDIATOR("TypeOracleMediator", "LightSteelBlue"), //
-  CRORE_PRECOMPILE("CroreCompiler", "Crimson"), //
+  PRECOMPILE_CORE("CoreCompiler", "Crimson"), //
   WRITE_OBJECT_AS_FILE("WriteObjectAsFile", "Magenta"), //
   BUILD_AST("BuildAST", "DarkGoldenRod"), //
   FUNCTION_CLUSTER("JsFunctionClusterer","Cornflower"), //
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
index 0cddcc9..4232bd7 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
@@ -56,7 +56,7 @@
   /**
    * Represents a node in a tree of SpeedTracer events.
    */
-  private class Event {
+  public class Event {
     List<Event> children = Lists.create();
     List<String> data;
     long durationNanos;
@@ -89,6 +89,13 @@
       }
     }
 
+    /**
+     * Signals the end of the current event.
+     */
+    public void end(String... data) {
+      SpeedTracerLogger.get().endImpl(this, data);
+    }
+
     @Override
     public String toString() {
       return type.getName();
@@ -123,6 +130,26 @@
       return nanos / 1000000.0d;
     }
   }
+  
+  /**
+   * A dummy implementation to do nothing if logging has not been turned on.
+   */
+  private class DummyEvent extends Event {
+    @Override
+    public void addData(String  ...data) {
+      // do nothing
+    }
+    
+    @Override
+    public void end(String... data) {
+      // do nothing
+    }
+    
+    @Override
+    public String toString() {
+      return "Dummy";
+    }
+  }
 
   /**
    * Initializes the singleton on demand.
@@ -191,13 +218,6 @@
   }
 
   /**
-   * Signals the end of the current event.
-   */
-  public static void end(EventType type, String... data) {
-    SpeedTracerLogger.get().endImpl(type, data);
-  }
-
-  /**
    * Create a new global instance. Force the zero time to be recorded and the
    * log to be opened if the default logging is turned on with the
    * <code>-Dgwt.speedtracerlog</code> VM property.
@@ -209,15 +229,16 @@
   }
 
   /**
-   * Signals that a new event has started. You must call {@link #end} for each
+   * Signals that a new event has started. You must end each event for each
    * corresponding call to {@code start}. You may nest timing calls.
    *
    * @param type the type of event
    * @data a set of key-value pairs (each key is followed by its value) that
    *       contain additional information about the event
+   * @return an Event object to be closed by the caller
    */
-  public static void start(EventType type, String... data) {
-    SpeedTracerLogger.get().startImpl(type, data);
+  public static Event start(EventType type, String... data) {
+    return SpeedTracerLogger.get().startImpl(type, data);
   }
 
   /**
@@ -231,6 +252,7 @@
     return LazySpeedTracerLoggerHolder.singleton;
   }
 
+  private final DummyEvent dummyEvent = new DummyEvent();
   private final BlockingQueue<Event> eventQueue = new LinkedBlockingQueue<Event>();
 
   private final BlockingQueue<Event> eventsToWrite;
@@ -276,7 +298,7 @@
     currentEvent.addData(data);
   }
 
-  void endImpl(EventType type, String... data) {
+  void endImpl(Event event, String... data) {
     if (eventsToWrite == null) {
       return;
     }
@@ -296,15 +318,15 @@
     assert (endTimeNanos >= currentEvent.startTimeNanos);
     currentEvent.durationNanos = endTimeNanos - currentEvent.startTimeNanos;
 
-    while (currentEvent.type != type && !threadPendingEvents.isEmpty()) {
+    while (currentEvent != event && !threadPendingEvents.isEmpty()) {
       // Missed a closing end for one or more frames! Try to sync back up.
-      currentEvent.addData("Missed", "This event was closed without an explicit call to SpeedTracerLogger.end()"); 
+      currentEvent.addData("Missed", "This event was closed without an explicit call to Event.end()"); 
       currentEvent = threadPendingEvents.pop();
       assert (endTimeNanos >= currentEvent.startTimeNanos);
       currentEvent.durationNanos = endTimeNanos - currentEvent.startTimeNanos;
     }
     
-    if (threadPendingEvents.isEmpty() && currentEvent.type != type) {
+    if (threadPendingEvents.isEmpty() && currentEvent != event) {
       currentEvent.addData("Missed", "Fell off the end of the threadPending events");
     }
     
@@ -328,9 +350,9 @@
     }
   }
 
-  void startImpl(EventType type, String... data) {
+  Event startImpl(EventType type, String... data) {
     if (eventsToWrite == null) {
-      return;
+      return dummyEvent;
     }
 
     if (data.length % 2 == 1) {
@@ -345,6 +367,7 @@
 
     Event newEvent = new Event(parent, type, data);
     threadPendingEvents.push(newEvent);
+    return newEvent;
   }
 
   private long normalizedTimeNanos() {
diff --git a/dev/core/test/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLoggerTest.java b/dev/core/test/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLoggerTest.java
index f11bc54..60954ab 100644
--- a/dev/core/test/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLoggerTest.java
+++ b/dev/core/test/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLoggerTest.java
@@ -18,6 +18,7 @@
 import com.google.gwt.dev.json.JsonArray;
 import com.google.gwt.dev.json.JsonException;
 import com.google.gwt.dev.json.JsonObject;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.EventType;
 
 import junit.framework.TestCase;
@@ -64,8 +65,8 @@
     @Override
     public void run() {
       for (int i = 0; i < MAX_EVENT_LOGS; i++) {
-        logger.startImpl(event);
-        logger.endImpl(event);
+        Event e = logger.startImpl(event);
+        logger.endImpl(e);
       }
     }
   }
@@ -81,12 +82,12 @@
   public void testSpeedTracerLogger() throws IOException, JsonException {
     Writer writer = new StringWriter();
     SpeedTracerLogger logger = new SpeedTracerLogger(writer);
-    logger.startImpl(dummyOne);
-    logger.startImpl(dummyTwo);
-    logger.endImpl(dummyTwo);
-    logger.startImpl(dummyThree);
-    logger.endImpl(dummyThree);
-    logger.endImpl(dummyOne);
+    Event dummyOneEvent = logger.startImpl(dummyOne);
+    Event dummyTwoEvent = logger.startImpl(dummyTwo);
+    logger.endImpl(dummyTwoEvent);
+    Event dummyThreeEvent = logger.startImpl(dummyThree);
+    logger.endImpl(dummyThreeEvent);
+    logger.endImpl(dummyOneEvent);
     logger.flush();
 
     Reader jsonReader = extractJsonFromWriter(writer);
@@ -111,9 +112,9 @@
       JsonException {
     Writer writer = new StringWriter();
     SpeedTracerLogger logger = new SpeedTracerLogger(writer);
-    logger.startImpl(dummyOne, "extraStart", "valueStart");
+    Event dummyOneEvent = logger.startImpl(dummyOne, "extraStart", "valueStart");
     logger.addDataImpl("extraMiddle", "valueMiddle");
-    logger.endImpl(dummyOne, "extraEnd", "valueEnd");
+    logger.endImpl(dummyOneEvent, "extraEnd", "valueEnd");
     logger.flush();
 
     Reader jsonReader = extractJsonFromWriter(writer);
@@ -131,12 +132,12 @@
   public void testSpeedTracerLoggerMultiple() throws IOException, JsonException {
     Writer writer = new StringWriter();
     SpeedTracerLogger logger = new SpeedTracerLogger(writer);
-    logger.startImpl(dummyOne);
-    logger.endImpl(dummyOne);
-    logger.startImpl(dummyTwo);
-    logger.endImpl(dummyTwo);
-    logger.startImpl(dummyThree);
-    logger.endImpl(dummyThree);
+    Event dummyOneEvent = logger.startImpl(dummyOne);
+    logger.endImpl(dummyOneEvent);
+    Event dummyTwoEvent = logger.startImpl(dummyTwo);
+    logger.endImpl(dummyTwoEvent);
+    Event dummyThreeEvent = logger.startImpl(dummyThree);
+    logger.endImpl(dummyThreeEvent);
     logger.flush();
 
     Reader jsonReader = extractJsonFromWriter(writer);