Add a bit more profiler coverage

The intent is that the main thread has ~zero gaps in the profile (though there
may still be small gaps due to the time between one try block and an
immediately subsequent try block).

We need to be careful not to wrap markPhase calls (or methods that call
markPhase) in try blocks for the profiler - the Profiler requires that all
markPhase calls happen at top level, and throws an exception if not.

This should not have any performance impact - all of these are once per build,
or at most once per module per build, and we don't expect a very large number
of modules (and if we see an increasing number, we need to change the module
API to not have to call every single module, but only those that are actually
interested in certain events, maybe with an EventBus-based setup).

PiperOrigin-RevId: 200712677
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index b88952a..6eddca5 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -64,6 +64,7 @@
 import com.google.devtools.build.lib.pkgcache.LoadingResult;
 import com.google.devtools.build.lib.profiler.ProfilePhase;
 import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.runtime.BlazeRuntime;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
 import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
@@ -134,15 +135,24 @@
       throws BuildFailedException, InterruptedException, ViewCreationFailedException,
           TargetParsingException, LoadingFailedException, AbruptExitException,
           InvalidConfigurationException, TestExecException, PostAnalysisQueryCommandLineException {
-    validateOptions(request);
-    BuildOptions buildOptions = runtime.createBuildOptions(request);
+    try (SilentCloseable c = Profiler.instance().profile("validateOptions")) {
+      validateOptions(request);
+    }
+    BuildOptions buildOptions;
+    try (SilentCloseable c = Profiler.instance().profile("createBuildOptions")) {
+      buildOptions = runtime.createBuildOptions(request);
+    }
     // Sync the package manager before sending the BuildStartingEvent in runLoadingPhase()
-    env.setupPackageCache(request, DefaultsPackage.getDefaultsPackageContent(buildOptions));
+    try (SilentCloseable c = Profiler.instance().profile("setupPackageCache")) {
+      env.setupPackageCache(request, DefaultsPackage.getDefaultsPackageContent(buildOptions));
+    }
 
     ExecutionTool executionTool = null;
     boolean catastrophe = false;
     try {
-      env.getEventBus().post(new BuildStartingEvent(env, request));
+      try (SilentCloseable c = Profiler.instance().profile("BuildStartingEvent")) {
+        env.getEventBus().post(new BuildStartingEvent(env, request));
+      }
       logger.info("Build identifier: " + request.getId());
 
       // Error out early if multi_cpus is set, but we're not in build or test command.
@@ -162,11 +172,17 @@
       env.throwPendingException();
 
       // Target pattern evaluation.
-      LoadingResult loadingResult = evaluateTargetPatterns(request, validator);
+      LoadingResult loadingResult;
+      Profiler.instance().markPhase(ProfilePhase.LOAD);
+      try (SilentCloseable c = Profiler.instance().profile("evaluateTargetPatterns")) {
+        loadingResult = evaluateTargetPatterns(request, validator);
+      }
       env.setWorkspaceName(loadingResult.getWorkspaceName());
       executionTool = new ExecutionTool(env, request);
       if (needsExecutionPhase(request.getBuildOptions())) {
-        executionTool.init();
+        try (SilentCloseable closeable = Profiler.instance().profile("ExecutionTool.init")) {
+          executionTool.init();
+        }
       }
 
       // Compute the heuristic instrumentation filter if needed.
@@ -191,14 +207,17 @@
       // Configuration creation.
       // TODO(gregce): Consider dropping this phase and passing on-the-fly target / host configs as
       // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
-      BuildConfigurationCollection configurations =
-          env.getSkyframeExecutor()
-              .createConfigurations(
-                  env.getReporter(),
-                  runtime.getConfigurationFragmentFactories(),
-                  buildOptions,
-                  request.getMultiCpus(),
-                  request.getKeepGoing());
+      BuildConfigurationCollection configurations;
+      try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
+        configurations =
+            env.getSkyframeExecutor()
+                .createConfigurations(
+                    env.getReporter(),
+                    runtime.getConfigurationFragmentFactories(),
+                    buildOptions,
+                    request.getMultiCpus(),
+                    request.getKeepGoing());
+      }
 
       env.throwPendingException();
       if (configurations.getTargetConfigurations().size() == 1) {
@@ -211,7 +230,24 @@
       logger.info("Configurations created");
 
       if (request.getBuildOptions().performAnalysisPhase) {
-        AnalysisResult analysisResult = runAnalysisPhase(request, loadingResult, configurations);
+        Profiler.instance().markPhase(ProfilePhase.ANALYZE);
+        AnalysisResult analysisResult;
+        try (SilentCloseable c = Profiler.instance().profile("runAnalysisPhase")) {
+          analysisResult = runAnalysisPhase(request, loadingResult, configurations);
+        }
+
+        // Check licenses.
+        // We check licenses if the first target configuration has license checking enabled. Right
+        // now, it is not possible to have multiple target configurations with different settings
+        // for this flag, which allows us to take this short cut.
+        boolean checkLicenses = configurations.getTargetConfigurations().get(0).checkLicenses();
+        if (checkLicenses) {
+          Profiler.instance().markPhase(ProfilePhase.LICENSE);
+          try (SilentCloseable c = Profiler.instance().profile("validateLicensingForTargets")) {
+            validateLicensingForTargets(analysisResult.getTargetsToBuild(), request.getKeepGoing());
+          }
+        }
+
         result.setBuildConfigurationCollection(configurations);
         result.setActualTargets(analysisResult.getTargetsToBuild());
         result.setTestTargets(analysisResult.getTargetsToTest());
@@ -229,7 +265,9 @@
                   AbortReason.SKIPPED,
                   String.format("Target %s build was skipped.", label), label));
         }
-        postProcessAnalysisResult(request, analysisResult);
+        try (SilentCloseable c = Profiler.instance().profile("postProcessAnalysisResult")) {
+          postProcessAnalysisResult(request, analysisResult);
+        }
         // Execution phase.
         if (needsExecutionPhase(request.getBuildOptions())) {
           executionTool.executeBuild(
@@ -335,7 +373,6 @@
   public BuildResult processRequest(
       BuildRequest request, TargetValidator validator) {
     BuildResult result = new BuildResult(request.getStartTime());
-    env.getEventBus().register(result);
     maybeSetStopOnFirstFailure(request, result);
     Throwable catastrophe = null;
     ExitCode exitCode = ExitCode.BLAZE_INTERNAL_ERROR;
@@ -412,7 +449,6 @@
   private final LoadingResult evaluateTargetPatterns(
       final BuildRequest request, final TargetValidator validator)
       throws LoadingFailedException, TargetParsingException, InterruptedException {
-    Profiler.instance().markPhase(ProfilePhase.LOAD);
     initializeOutputFilter(request);
 
     final boolean keepGoing = request.getKeepGoing();
@@ -465,7 +501,6 @@
       throws InterruptedException, ViewCreationFailedException {
     Stopwatch timer = Stopwatch.createStarted();
     getReporter().handle(Event.progress("Loading complete.  Analyzing..."));
-    Profiler.instance().markPhase(ProfilePhase.ANALYZE);
 
     BuildView view = new BuildView(env.getDirectories(), runtime.getRuleClassProvider(),
         env.getSkyframeExecutor(), runtime.getCoverageReportActionFactory(request));
@@ -510,17 +545,6 @@
                 analysisResult.getTargetsToBuild(),
                 analysisResult.getTargetsToTest(),
                 configurationMap));
-
-    // Check licenses.
-    // We check licenses if the first target configuration has license checking enabled. Right now,
-    // it is not possible to have multiple target configurations with different settings for this
-    // flag, which allows us to take this short cut.
-    boolean checkLicenses = configurations.getTargetConfigurations().get(0).checkLicenses();
-    if (checkLicenses) {
-      Profiler.instance().markPhase(ProfilePhase.LICENSE);
-      validateLicensingForTargets(analysisResult.getTargetsToBuild(), request.getKeepGoing());
-    }
-
     return analysisResult;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index 58afd6b..78b350b 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -128,11 +128,15 @@
 
     // Create tools before getting the strategies from the modules as some of them need tools to
     // determine whether the host actually supports certain strategies (e.g. sandboxing).
-    createToolsSymlinks();
+    try (SilentCloseable closeable = Profiler.instance().profile("createToolsSymlinks")) {
+      createToolsSymlinks();
+    }
 
     ExecutorBuilder builder = new ExecutorBuilder();
     for (BlazeModule module : runtime.getBlazeModules()) {
-      module.executorInit(env, request, builder);
+      try (SilentCloseable closeable = Profiler.instance().profile(module + ".executorInit")) {
+        module.executorInit(env, request, builder);
+      }
     }
     builder.addActionContext(new SymlinkTreeStrategy(
                 env.getOutputService(), env.getBlazeWorkspace().getBinTools()));
@@ -151,7 +155,9 @@
 
     this.actionContextProviders = builder.getActionContextProviders();
     for (ActionContextProvider provider : actionContextProviders) {
-      provider.init(fileCache);
+      try (SilentCloseable closeable = Profiler.instance().profile(provider + ".init")) {
+        provider.init(fileCache);
+      }
     }
 
     // There are many different SpawnActions, and we want to control the action context they use
@@ -226,12 +232,16 @@
     OutputService outputService = env.getOutputService();
     ModifiedFileSet modifiedOutputFiles = ModifiedFileSet.EVERYTHING_MODIFIED;
     if (outputService != null) {
-      modifiedOutputFiles =
-          outputService.startBuild(
-              env.getReporter(), buildId, request.getBuildOptions().finalizeActions);
+      try (SilentCloseable c = Profiler.instance().profile("outputService.startBuild")) {
+        modifiedOutputFiles =
+            outputService.startBuild(
+                env.getReporter(), buildId, request.getBuildOptions().finalizeActions);
+      }
     } else {
       // TODO(bazel-team): this could be just another OutputService
-      startLocalOutputBuild();
+      try (SilentCloseable c = Profiler.instance().profile("startLocalOutputBuild")) {
+        startLocalOutputBuild();
+      }
     }
 
     // Must be created after the output path is created above.
@@ -255,16 +265,22 @@
                 analysisResult.getConfigurationCollection().getTargetConfigurations());
     String productName = runtime.getProductName();
     String workspaceName = env.getWorkspaceName();
-    OutputDirectoryLinksUtils.createOutputDirectoryLinks(
-        workspaceName, env.getWorkspace(), env.getDirectories().getExecRoot(workspaceName),
-        env.getDirectories().getOutputPath(workspaceName), getReporter(), targetConfigurations,
-        request.getBuildOptions().getSymlinkPrefix(productName), productName);
+    try (SilentCloseable c =
+        Profiler.instance().profile("OutputDirectoryLinksUtils.createOutputDirectoryLinks")) {
+      OutputDirectoryLinksUtils.createOutputDirectoryLinks(
+          workspaceName, env.getWorkspace(), env.getDirectories().getExecRoot(workspaceName),
+          env.getDirectories().getOutputPath(workspaceName), getReporter(), targetConfigurations,
+          request.getBuildOptions().getSymlinkPrefix(productName), productName);
+    }
 
     ActionCache actionCache = getActionCache();
     actionCache.resetStatistics();
     SkyframeExecutor skyframeExecutor = env.getSkyframeExecutor();
-    Builder builder = createBuilder(
-        request, actionCache, skyframeExecutor, modifiedOutputFiles);
+    Builder builder;
+    try (SilentCloseable c = Profiler.instance().profile("createBuilder")) {
+      builder = createBuilder(
+          request, actionCache, skyframeExecutor, modifiedOutputFiles);
+    }
 
     //
     // Execution proper.  All statements below are logically nested in
@@ -272,7 +288,9 @@
     //
 
     Collection<ConfiguredTarget> configuredTargets = buildResult.getActualTargets();
-    env.getEventBus().post(new ExecutionStartingEvent(configuredTargets));
+    try (SilentCloseable c = Profiler.instance().profile("ExecutionStartingEvent")) {
+      env.getEventBus().post(new ExecutionStartingEvent(configuredTargets));
+    }
 
     getReporter().handle(Event.progress("Building..."));
 
@@ -307,7 +325,10 @@
     boolean buildCompleted = false;
     try {
       for (ActionContextProvider actionContextProvider : actionContextProviders) {
-        actionContextProvider.executionPhaseStarting(actionGraph, allArtifactsForProviders);
+        try (SilentCloseable c =
+            Profiler.instance().profile(actionContextProvider + ".executionPhaseStarting")) {
+          actionContextProvider.executionPhaseStarting(actionGraph, allArtifactsForProviders);
+        }
       }
       executor.executionPhaseStarting();
       skyframeExecutor.drainChangedFiles();
@@ -315,11 +336,15 @@
       if (request.getViewOptions().discardAnalysisCache
           || !skyframeExecutor.tracksStateForIncrementality()) {
         // Free memory by removing cache entries that aren't going to be needed.
-        env.getSkyframeBuildView()
-            .clearAnalysisCache(analysisResult.getTargetsToBuild(), analysisResult.getAspects());
+        try (SilentCloseable c = Profiler.instance().profile("clearAnalysisCache")) {
+          env.getSkyframeBuildView()
+              .clearAnalysisCache(analysisResult.getTargetsToBuild(), analysisResult.getAspects());
+        }
       }
 
-      configureResourceManager(request);
+      try (SilentCloseable c = Profiler.instance().profile("configureResourceManager")) {
+        configureResourceManager(request);
+      }
 
       Profiler.instance().markPhase(ProfilePhase.EXECUTE);
 
@@ -411,7 +436,7 @@
     Profiler.instance().markPhase(ProfilePhase.PREPARE);
 
     // Plant the symlink forest.
-    try {
+    try (SilentCloseable c = Profiler.instance().profile("plantSymlinkForest")) {
       new SymlinkForest(
               packageRootMap.get(), getExecRoot(), runtime.getProductName(), env.getWorkspaceName())
           .plantSymlinkForest();
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
index 797f337..b49aae9 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
@@ -37,6 +37,8 @@
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
+import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.skyframe.ActionExecutionInactivityWatchdog;
 import com.google.devtools.build.lib.skyframe.AspectValue;
 import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
@@ -116,8 +118,12 @@
       @Nullable Range<Long> lastExecutionTimeRange,
       TopLevelArtifactContext topLevelArtifactContext)
       throws BuildFailedException, AbruptExitException, TestExecException, InterruptedException {
-    skyframeExecutor.detectModifiedOutputFiles(modifiedOutputFiles, lastExecutionTimeRange);
-    skyframeExecutor.configureActionExecutor(fileCache, actionInputPrefetcher);
+    try (SilentCloseable c = Profiler.instance().profile("detectModifiedOutputFiles")) {
+      skyframeExecutor.detectModifiedOutputFiles(modifiedOutputFiles, lastExecutionTimeRange);
+    }
+    try (SilentCloseable c = Profiler.instance().profile("configureActionExecutor")) {
+      skyframeExecutor.configureActionExecutor(fileCache, actionInputPrefetcher);
+    }
     // Note that executionProgressReceiver accesses builtTargets concurrently (after wrapping in a
     // synchronized collection), so unsynchronized access to this variable is unsafe while it runs.
     ExecutionProgressReceiver executionProgressReceiver =
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
index 5c55d83..75c8d4b 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
@@ -32,6 +32,8 @@
 import com.google.devtools.build.lib.events.PrintingEventHandler;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.events.StoredEventHandler;
+import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
 import com.google.devtools.build.lib.util.AbruptExitException;
 import com.google.devtools.build.lib.util.AnsiStrippingOutputStream;
@@ -466,7 +468,10 @@
       env.getEventBus().post(commonOptions.toolCommandLine);
 
       for (BlazeModule module : runtime.getBlazeModules()) {
-        env.getSkyframeExecutor().injectExtraPrecomputedValues(module.getPrecomputedValues());
+        try (SilentCloseable closeable =
+            Profiler.instance().profile(module + ".injectExtraPrecomputedValues")) {
+          env.getSkyframeExecutor().injectExtraPrecomputedValues(module.getPrecomputedValues());
+        }
       }
 
       result = command.exec(env, options);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index 12276f4..f073fda 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -47,6 +47,7 @@
 import com.google.devtools.build.lib.profiler.Profiler;
 import com.google.devtools.build.lib.profiler.Profiler.ProfiledTaskKinds;
 import com.google.devtools.build.lib.profiler.ProfilerTask;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
 import com.google.devtools.build.lib.query2.QueryEnvironmentFactory;
 import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
@@ -481,7 +482,9 @@
     notifyCommandComplete(exitCode);
 
     for (BlazeModule module : blazeModules) {
-      module.afterCommand();
+      try (SilentCloseable c = Profiler.instance().profile(module + ".afterCommand")) {
+        module.afterCommand();
+      }
     }
 
     // Wipe the dependency graph if requested. Note that this method always runs at the end of
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/BuildCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/BuildCommand.java
index 14b6c19..b217e93 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/BuildCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/BuildCommand.java
@@ -21,6 +21,8 @@
 import com.google.devtools.build.lib.exec.local.LocalExecutionOptions;
 import com.google.devtools.build.lib.pkgcache.LoadingOptions;
 import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
+import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.runtime.BlazeCommand;
 import com.google.devtools.build.lib.runtime.BlazeCommandResult;
 import com.google.devtools.build.lib.runtime.BlazeRuntime;
@@ -65,13 +67,19 @@
   @Override
   public BlazeCommandResult exec(CommandEnvironment env, OptionsProvider options) {
     BlazeRuntime runtime = env.getRuntime();
-    List<String> targets = ProjectFileSupport.getTargets(runtime.getProjectFileProvider(), options);
+    List<String> targets;
+    try (SilentCloseable closeable = Profiler.instance().profile("ProjectFileSupport.getTargets")) {
+      targets = ProjectFileSupport.getTargets(runtime.getProjectFileProvider(), options);
+    }
 
-    BuildRequest request = BuildRequest.create(
-        getClass().getAnnotation(Command.class).name(), options,
-        runtime.getStartupOptionsProvider(),
-        targets,
-        env.getReporter().getOutErr(), env.getCommandId(), env.getCommandStartTime());
+    BuildRequest request;
+    try (SilentCloseable closeable = Profiler.instance().profile("BuildRequest.create")) {
+      request = BuildRequest.create(
+          getClass().getAnnotation(Command.class).name(), options,
+          runtime.getStartupOptionsProvider(),
+          targets,
+          env.getReporter().getOutErr(), env.getCommandId(), env.getCommandStartTime());
+    }
     ExitCode exitCode = new BuildTool(env).processRequest(request, null).getExitCondition();
     return BlazeCommandResult.exitCode(exitCode);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/BUILD b/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
index ae11fa4..49dfba6 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
@@ -28,6 +28,7 @@
         "//src/main/java/com/google/devtools/build/lib/exec/apple",
         "//src/main/java/com/google/devtools/build/lib/exec/local",
         "//src/main/java/com/google/devtools/build/lib/exec/local:options",
+        "//src/main/java/com/google/devtools/build/lib/profiler",
         "//src/main/java/com/google/devtools/build/lib/shell",
         "//src/main/java/com/google/devtools/build/lib/standalone",
         "//src/main/java/com/google/devtools/build/lib/vfs",
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
index ce3c8a3..b0a7ed6 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
@@ -28,6 +28,8 @@
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.exec.local.LocalEnvProvider;
 import com.google.devtools.build.lib.exec.local.PosixLocalEnvProvider;
+import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
 import com.google.devtools.build.lib.shell.Command;
 import com.google.devtools.build.lib.shell.CommandException;
@@ -67,7 +69,7 @@
     File cwd = execRoot.getPathFile();
 
     Command cmd = new Command(linuxSandboxArgv.toArray(new String[0]), env, cwd);
-    try {
+    try (SilentCloseable c = Profiler.instance().profile("LinuxSandboxedSpawnRunner.isSupported")) {
       cmd.execute(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream());
     } catch (CommandException e) {
       return false;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index b7c9386..ac6e8d1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -119,6 +119,8 @@
 import com.google.devtools.build.lib.pkgcache.TestFilter;
 import com.google.devtools.build.lib.pkgcache.TransitivePackageLoader;
 import com.google.devtools.build.lib.profiler.AutoProfiler;
+import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey;
 import com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker;
 import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
@@ -1309,9 +1311,12 @@
     checkActive();
     Preconditions.checkState(actionLogBufferPathGenerator != null);
 
-    skyframeActionExecutor.prepareForExecution(
-        reporter, executor, keepGoing, explain, actionCacheChecker,
-        finalizeActionsToOutputService ? outputService : null);
+    try (SilentCloseable c =
+        Profiler.instance().profile("skyframeActionExecutor.prepareForExecution")) {
+      skyframeActionExecutor.prepareForExecution(
+          reporter, executor, keepGoing, explain, actionCacheChecker,
+          finalizeActionsToOutputService ? outputService : null);
+    }
 
     resourceManager.resetResourceUsage();
     try {