Revert "Paralleize jumbo string rewriting"

This reverts commit dd45b8cad6d33bc950e9146f50c789642a3be996.

Revert "Paralleize writing of DEX code bytes"

This reverts commit c24b330022279a51611e3c85fee0c4583f2306ab.

Revert "Temporalily fix test"

This reverts commit efd46c721c987a4db5f949a680f65aee34edd2ad.

Bug: b/422947619
Bug: b/444353673

Change-Id: I7af8ae3134de02e9f6aa2849be0a9119e16bbd1d
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 46011da..bb8d845 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -291,7 +291,7 @@
             virtualFile -> {
               Timing fileTiming =
                   timing.createThreadTiming("VirtualFile " + virtualFile.getId(), options);
-              writeVirtualFile(virtualFile, fileTiming, forcedStrings, executorService);
+              writeVirtualFile(virtualFile, fileTiming, forcedStrings);
               fileTiming.end();
               return fileTiming;
             },
@@ -530,11 +530,7 @@
   }
 
   protected void writeVirtualFile(
-      VirtualFile virtualFile,
-      Timing timing,
-      List<DexString> forcedStrings,
-      ExecutorService executorService)
-      throws ExecutionException {
+      VirtualFile virtualFile, Timing timing, List<DexString> forcedStrings) {
     if (virtualFile.isEmpty()) {
       return;
     }
@@ -571,8 +567,7 @@
     timing.end();
 
     timing.begin("Write bytes");
-    ByteBufferResult result =
-        writeDexFile(objectMapping, byteBufferProvider, virtualFile, timing, executorService);
+    ByteBufferResult result = writeDexFile(objectMapping, byteBufferProvider, virtualFile, timing);
     ByteDataView data =
         new ByteDataView(result.buffer.array(), result.buffer.arrayOffset(), result.length);
     timing.end();
@@ -897,14 +892,12 @@
       ObjectToOffsetMapping objectMapping,
       ByteBufferProvider provider,
       VirtualFile virtualFile,
-      Timing timing,
-      ExecutorService executorService)
-      throws ExecutionException {
+      Timing timing) {
     FileWriter fileWriter = new FileWriter(appView, provider, objectMapping, virtualFile);
     // Collect the non-fixed sections.
     timing.time("collect", fileWriter::collect);
     // Generate and write the bytes.
-    return timing.time("generate", () -> fileWriter.generate(timing, executorService));
+    return timing.time("generate", () -> fileWriter.generate(timing));
   }
 
   private static String mapMainDexListName(DexType type, NamingLens namingLens) {
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriterContainer.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriterContainer.java
index d0a4602..cce512c 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriterContainer.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriterContainer.java
@@ -27,7 +27,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 
 class ApplicationWriterContainer extends ApplicationWriter {
@@ -41,8 +40,7 @@
       ExecutorService executorService,
       List<VirtualFile> virtualFiles,
       List<DexString> forcedStrings,
-      Timing timing)
-      throws ExecutionException {
+      Timing timing) {
     Map<FeatureSplit, List<VirtualFile>> virtualFilesForContainers = new HashMap<>();
     List<VirtualFile> virtualFilesOutsideContainer = new ArrayList<>();
     virtualFiles.forEach(
@@ -62,7 +60,7 @@
     timing.begin("Write non container virtual files");
     for (VirtualFile virtualFile : virtualFilesOutsideContainer) {
       timing.begin("VirtualFile " + virtualFile.getId());
-      writeVirtualFile(virtualFile, timing, forcedStrings, executorService);
+      writeVirtualFile(virtualFile, timing, forcedStrings);
       timing.end();
     }
     timing.end();
@@ -70,17 +68,13 @@
     // Write container virtual files.
     timing.begin("Write container virtual files");
     for (List<VirtualFile> virtualFilesForContainer : virtualFilesForContainers.values()) {
-      writeContainer(forcedStrings, timing, virtualFilesForContainer, executorService);
+      writeContainer(forcedStrings, timing, virtualFilesForContainer);
     }
     timing.end();
   }
 
   private void writeContainer(
-      List<DexString> forcedStrings,
-      Timing timing,
-      List<VirtualFile> virtualFiles,
-      ExecutorService executorService)
-      throws ExecutionException {
+      List<DexString> forcedStrings, Timing timing, List<VirtualFile> virtualFiles) {
     ProgramConsumer consumer;
     ByteBufferProvider byteBufferProvider;
     if (programConsumer != null) {
@@ -115,8 +109,7 @@
                 forcedStrings,
                 offset,
                 dexOutputBuffer,
-                i == virtualFiles.size() - 1,
-                executorService);
+                i == virtualFiles.size() - 1);
 
         if (InternalOptions.assertionsEnabled()) {
           // Check that writing did not modify already written sections.
@@ -232,9 +225,7 @@
       List<DexString> forcedStrings,
       int offset,
       DexOutputBuffer outputBuffer,
-      boolean last,
-      ExecutorService executorService)
-      throws ExecutionException {
+      boolean last) {
     assert !virtualFile.isEmpty();
     assert BitUtils.isAligned(4, offset);
     printItemUseInfo(virtualFile);
@@ -246,8 +237,7 @@
 
     timing.begin("Write bytes");
     DexContainerSection section =
-        writeDexFile(
-            objectMapping, outputBuffer, virtualFile, timing, offset, last, executorService);
+        writeDexFile(objectMapping, outputBuffer, virtualFile, timing, offset, last);
     timing.end();
     return section;
   }
@@ -258,9 +248,7 @@
       VirtualFile virtualFile,
       Timing timing,
       int offset,
-      boolean includeStringData,
-      ExecutorService executorService)
-      throws ExecutionException {
+      boolean includeStringData) {
     FileWriter fileWriter =
         new FileWriter(
             appView,
@@ -271,7 +259,6 @@
     // Collect the non-fixed sections.
     timing.time("collect", fileWriter::collect);
     // Generate and write the bytes.
-    return timing.time(
-        "generate", () -> fileWriter.generate(timing, executorService, offset, CONTAINER_DEX));
+    return timing.time("generate", () -> fileWriter.generate(timing, offset, CONTAINER_DEX));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/dex/DexOutputBuffer.java b/src/main/java/com/android/tools/r8/dex/DexOutputBuffer.java
index 66322ac..0bb99c4 100644
--- a/src/main/java/com/android/tools/r8/dex/DexOutputBuffer.java
+++ b/src/main/java/com/android/tools/r8/dex/DexOutputBuffer.java
@@ -31,35 +31,6 @@
     this(new ByteBufferProvider() {});
   }
 
-  /**
-   * Internal constructor to create a DexOutputBuffer wrapping an existing ByteBuffer disallowing
-   * the buffer to grow thereby ensuring the backing array never changes.
-   */
-  private DexOutputBuffer(CompatByteBuffer byteBuffer) {
-    this.byteBuffer = CompatByteBuffer.wrap(byteBuffer.array());
-    this.byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
-    byteBufferProvider =
-        new ByteBufferProvider() {
-          @Override
-          public ByteBuffer acquireByteBuffer(int capacity) {
-            throw new UnsupportedOperationException();
-          }
-
-          @Override
-          public void releaseByteBuffer(ByteBuffer buffer) {
-            throw new UnsupportedOperationException();
-          }
-        };
-  }
-
-  /**
-   * Creates a DexOutputBuffer wrapping an existing DexOutputBuffer disallowing the buffer to grow
-   * thereby ensuring the backing array never changes.
-   */
-  public DexOutputBuffer nonExpandableWrapper() {
-    return new DexOutputBuffer(byteBuffer);
-  }
-
   public DexOutputBuffer(ByteBufferProvider byteBufferProvider) {
     this.byteBufferProvider = byteBufferProvider;
     byteBuffer = allocateByteBuffer(DEFAULT_BUFFER_SIZE);
@@ -160,10 +131,6 @@
     byteBuffer.putInt(anInteger);
   }
 
-  public byte get() {
-    return byteBuffer.get();
-  }
-
   public short getShort() {
     return byteBuffer.getShort();
   }
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index fd50c92..7cdd5cc 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -5,7 +5,6 @@
 
 import static com.android.tools.r8.utils.DexVersion.Layout.SINGLE_DEX;
 import static com.android.tools.r8.utils.LebUtils.sizeAsUleb128;
-import static com.google.common.base.Predicates.alwaysTrue;
 
 import com.android.tools.r8.ByteBufferProvider;
 import com.android.tools.r8.errors.CompilationError;
@@ -58,7 +57,6 @@
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.IterableUtils;
 import com.android.tools.r8.utils.LebUtils;
-import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.timing.Timing;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
@@ -66,20 +64,18 @@
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap;
 import it.unimi.dsi.fastutil.objects.Reference2IntMap;
-import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
 import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
 import java.util.function.Consumer;
 import java.util.function.ToIntFunction;
 import java.util.zip.Adler32;
@@ -205,70 +201,12 @@
     }
   }
 
-  public ByteBufferResult generate(Timing timing, ExecutorService executorService)
-      throws ExecutionException {
-    DexContainerSection res = generate(timing, executorService, 0, SINGLE_DEX);
+  public ByteBufferResult generate(Timing timing) {
+    DexContainerSection res = generate(timing, 0, SINGLE_DEX);
     return new ByteBufferResult(res.getBuffer().stealByteBuffer(), res.getLayout().getEndOfFile());
   }
 
-  // Class for collecting the codes to write. As the content is populated the codes to write is
-  // split into equally sized buckets for writing on multiple threads.
-  private static class CodesToWrite {
-
-    public static class CodeToWrite {
-      public final ProgramMethod method;
-      public final int offset;
-
-      public CodeToWrite(ProgramMethod method, int offset) {
-        this.method = method;
-        this.offset = offset;
-      }
-
-      private void write(DexOutputBuffer buffer, FileWriter writer) {
-        DexWritableCode dexWritableCode = method.getDefinition().getCode().asDexWritableCode();
-        buffer.moveTo(offset);
-        writer.writeCodeItem(method, dexWritableCode, buffer);
-      }
-    }
-
-    // Minimul number of bytes to include in each bucket.
-    private final int bucketSize;
-    // Mapping of method to the codes offset to write it to. For methods sharing the same code
-    // this only contains one method entry, i.e. the codes offsets are unique. The offsets are
-    // sorted by construction.
-    private final List<List<CodeToWrite>> codesToWrite = new ArrayList<>();
-    private List<CodeToWrite> current = new ArrayList<>();
-    private int currentSize = 0;
-    private int previousOffset = -1;
-
-    private CodesToWrite(int bucketSize) {
-      this.bucketSize = bucketSize;
-    }
-
-    private void add(ProgramMethod method, int codeOffset, int codeSize) {
-      assert previousOffset == -1 || previousOffset < codeOffset;
-      previousOffset = codeOffset;
-      current.add(new CodeToWrite(method, codeOffset));
-      currentSize += codeSize;
-      if (currentSize > bucketSize) {
-        codesToWrite.add(current);
-        current = new ArrayList<>();
-        currentSize = 0;
-      }
-    }
-
-    private List<List<CodeToWrite>> get() {
-      if (!current.isEmpty()) {
-        codesToWrite.add(current);
-        current = Collections.emptyList();
-      }
-      return codesToWrite;
-    }
-  }
-
-  public DexContainerSection generate(
-      Timing timing, ExecutorService executorService, int offset, DexVersion.Layout layoutType)
-      throws ExecutionException {
+  public DexContainerSection generate(Timing timing, int offset, DexVersion.Layout layoutType) {
     // Check restrictions on interface methods.
     checkInterfaceMethods();
 
@@ -280,37 +218,26 @@
     try (Timing t0 = timing.begin("Write codes")) {
       layout.setCodesOffset(layout.dataSectionOffset);
 
-      try (Timing t1 = timing.begin("Sort codes")) {
-        // Sort the codes first, as their order might impact size due to alignment constraints.
-        mixedSectionLayoutStrategy =
-            MixedSectionLayoutStrategy.create(appView, mixedSectionOffsets, virtualFile);
-      }
+      // Sort the codes first, as their order might impact size due to alignment constraints.
+      mixedSectionLayoutStrategy =
+          MixedSectionLayoutStrategy.create(appView, mixedSectionOffsets, virtualFile);
+      Collection<ProgramMethod> codes = mixedSectionLayoutStrategy.getCodeLayout();
 
       // Output the debug_info_items first, as they have no dependencies.
-      Collection<ProgramMethod> codes;
-      try (Timing t1 = timing.begin("Get code layout")) {
-        codes = mixedSectionLayoutStrategy.getCodeLayout();
-      }
-      MethodsCodeSizeAndCount methodsCodeSizeAndCount;
-      try (Timing t1 = timing.begin("Methods code size and count")) {
-        methodsCodeSizeAndCount = methodsCodeSizeAndCount(codes);
-      }
-      try (Timing t1 = timing.begin("Write debug info")) {
-        dest.moveTo(layout.getCodesOffset() + methodsCodeSizeAndCount.getSize());
-        if (mixedSectionOffsets.getDebugInfos().isEmpty()) {
-          layout.setDebugInfosOffset(0);
-        } else {
-          // Ensure deterministic ordering of debug info by sorting consistent with the code
-          // objects.
-          layout.setDebugInfosOffset(dest.align(1));
-          Set<DexDebugInfoForWriting> seen =
-              new HashSet<>(mixedSectionOffsets.getDebugInfos().size());
-          for (ProgramMethod method : codes) {
-            DexWritableCode code = method.getDefinition().getCode().asDexWritableCode();
-            DexDebugInfoForWriting info = code.getDebugInfoForWriting();
-            if (info != null && seen.add(info)) {
-              writeDebugItem(code, info);
-            }
+      SizeAndCount sizeAndCountOfCodeItems = sizeAndCountOfCodeItems(codes);
+      dest.moveTo(layout.getCodesOffset() + sizeAndCountOfCodeItems.size);
+      if (mixedSectionOffsets.getDebugInfos().isEmpty()) {
+        layout.setDebugInfosOffset(0);
+      } else {
+        // Ensure deterministic ordering of debug info by sorting consistent with the code objects.
+        layout.setDebugInfosOffset(dest.align(1));
+        Set<DexDebugInfoForWriting> seen =
+            new HashSet<>(mixedSectionOffsets.getDebugInfos().size());
+        for (ProgramMethod method : codes) {
+          DexWritableCode code = method.getDefinition().getCode().asDexWritableCode();
+          DexDebugInfoForWriting info = code.getDebugInfoForWriting();
+          if (info != null && seen.add(info)) {
+            writeDebugItem(code, info);
           }
         }
       }
@@ -318,81 +245,29 @@
       // Remember the typelist offset for later.
       layout.setTypeListsOffset(dest.align(4)); // type_list are aligned.
 
-      // Output the code.
-      try (Timing t1 = timing.begin("Write codes bytes")) {
-        dest.moveTo(layout.getCodesOffset());
-        assert dest.isAligned(4);
-        final int codeStart = dest.position();
-        // TODO(b/422947619): Adjust this based on available threads. On SystemUI benchmark 100000
-        //  gives approximately code for 1000 methods per task.
-        CodesToWrite codesToWrite = new CodesToWrite(100000);
-        int codeOffset = codeStart;
-        Object2IntMap<DexWritableCacheKey> offsetCache = new Object2IntLinkedOpenHashMap<>();
-        offsetCache.defaultReturnValue(-1);
-        for (ProgramMethod method : codes) {
-          if (!options.canUseCanonicalizedCodeObjects()) {
-            int codeSize = methodsCodeSizeAndCount.getCodeSize(method);
-            codeOffset = alignSize(4, codeOffset);
-            codesToWrite.add(method, codeOffset, codeSize);
-            mixedSectionOffsets.setOffsetFor(method.getDefinition(), codeOffset);
-            codeOffset += codeSize;
+      // Now output the code.
+      dest.moveTo(layout.getCodesOffset());
+      assert dest.isAligned(4);
+      Map<DexWritableCacheKey, Integer> offsetCache = new HashMap<>();
+      for (ProgramMethod method : codes) {
+        DexWritableCode dexWritableCode = method.getDefinition().getCode().asDexWritableCode();
+        if (!options.canUseCanonicalizedCodeObjects()) {
+          writeCodeItem(method, dexWritableCode);
+        } else {
+          DexWritableCacheKey cacheLookupKey =
+              dexWritableCode.getCacheLookupKey(method, appView.dexItemFactory());
+          Integer offsetOrNull = offsetCache.get(cacheLookupKey);
+          if (offsetOrNull != null) {
+            mixedSectionOffsets.setOffsetFor(method.getDefinition(), offsetOrNull);
           } else {
-            DexWritableCode dexWritableCode = method.getDefinition().getCode().asDexWritableCode();
-            DexWritableCacheKey cacheLookupKey =
-                dexWritableCode.getCacheLookupKey(method, appView.dexItemFactory());
-            int canonicalOffset = offsetCache.getInt(cacheLookupKey);
-            if (canonicalOffset > 0) {
-              mixedSectionOffsets.setOffsetFor(method.getDefinition(), canonicalOffset);
-              assert methodsCodeSizeAndCount.getCodeSize(method) == 0;
-            } else {
-              int codeSize = methodsCodeSizeAndCount.getCodeSize(method);
-              codeOffset = alignSize(4, codeOffset);
-              codesToWrite.add(method, codeOffset, codeSize);
-              offsetCache.put(cacheLookupKey, codeOffset);
-              mixedSectionOffsets.setOffsetFor(method.getDefinition(), codeOffset);
-              codeOffset += codeSize;
-            }
+            offsetCache.put(cacheLookupKey, writeCodeItem(method, dexWritableCode));
           }
         }
-        // Move to end of codes section to ensure backing array has been allocated for all codes.
-        int codeSize = codeOffset - codeStart;
-        dest.moveTo(codeStart + codeSize);
-        dest.moveTo(codeStart);
-
-        // Write code into code section.
-        List<List<CodesToWrite.CodeToWrite>> toWrite = codesToWrite.get();
-        int buckets = toWrite.size();
-        ThreadUtils.processItemsThatMatches(
-            toWrite,
-            alwaysTrue(),
-            (list, threadTiming) -> {
-              DexOutputBuffer buffer = dest.nonExpandableWrapper();
-              for (CodesToWrite.CodeToWrite codeToWrite : list) {
-                codeToWrite.write(buffer, this);
-              }
-            },
-            options,
-            executorService,
-            timing,
-            timing.beginMerger("Write codes bytes", executorService),
-            (i, list) ->
-                "Writing "
-                    + list.size()
-                    + " codes for VirtualFile "
-                    + virtualFile.getId()
-                    + " ("
-                    + i
-                    + "/"
-                    + buckets
-                    + ")");
-        // Move position to just after the written code section.
-        dest.moveTo(codeStart + codeSize);
-
-        assert methodsCodeSizeAndCount.getCount()
-            == ImmutableSet.copyOf(mixedSectionOffsets.codes.values()).size();
-        layout.setCodeCount(methodsCodeSizeAndCount.getCount());
-        assert layout.getDebugInfosOffset() == 0 || dest.position() == layout.getDebugInfosOffset();
       }
+      assert sizeAndCountOfCodeItems.getCount()
+          == ImmutableSet.copyOf(mixedSectionOffsets.codes.values()).size();
+      layout.setCodeCount(sizeAndCountOfCodeItems.getCount());
+      assert layout.getDebugInfosOffset() == 0 || dest.position() == layout.getDebugInfosOffset();
     }
 
     // Now the type lists and rest.
@@ -585,15 +460,10 @@
     }
   }
 
-  private static class MethodsCodeSizeAndCount {
+  static class SizeAndCount {
 
     private int size = 0;
     private int count = 0;
-    private final Reference2IntMap<DexMethod> sizes = new Reference2IntOpenHashMap<>();
-
-    private MethodsCodeSizeAndCount() {
-      sizes.defaultReturnValue(0);
-    }
 
     public int getCount() {
       return count;
@@ -602,26 +472,20 @@
     public int getSize() {
       return size;
     }
-
-    public int getCodeSize(ProgramMethod method) {
-      return sizes.getInt(method.getReference());
-    }
   }
 
-  private MethodsCodeSizeAndCount methodsCodeSizeAndCount(Iterable<ProgramMethod> methods) {
-    MethodsCodeSizeAndCount methodsCodeSizeAndCount = new MethodsCodeSizeAndCount();
+  private SizeAndCount sizeAndCountOfCodeItems(Iterable<ProgramMethod> methods) {
+    SizeAndCount sizeAndCount = new SizeAndCount();
     Set<DexWritableCacheKey> cache = new HashSet<>();
     for (ProgramMethod method : methods) {
       DexWritableCode code = method.getDefinition().getCode().asDexWritableCode();
       if (!options.canUseCanonicalizedCodeObjects()
           || cache.add(code.getCacheLookupKey(method, appView.dexItemFactory()))) {
-        int codeSize = sizeOfCodeItem(code);
-        methodsCodeSizeAndCount.count++;
-        methodsCodeSizeAndCount.size = alignSize(4, methodsCodeSizeAndCount.size) + codeSize;
-        methodsCodeSizeAndCount.sizes.put(method.getReference(), codeSize);
+        sizeAndCount.count++;
+        sizeAndCount.size = alignSize(4, sizeAndCount.size) + sizeOfCodeItem(code);
       }
     }
-    return methodsCodeSizeAndCount;
+    return sizeAndCount;
   }
 
   private int sizeOfCodeItem(DexWritableCode code) {
@@ -708,21 +572,10 @@
     dest.putBytes(new DebugBytecodeWriter(debugInfo, mapping, graphLens, codeLens).generate());
   }
 
-  private int writeCodeItem(ProgramMethod method, DexWritableCode code, DexOutputBuffer dest) {
-    return writeCodeItem(method, code, dest, appView, mixedSectionOffsets, mapping, graphLens);
-  }
-
-  private static int writeCodeItem(
-      ProgramMethod method,
-      DexWritableCode code,
-      DexOutputBuffer dest,
-      AppView<?> appView,
-      MixedSectionOffsets mixedSectionOffsets,
-      ObjectToOffsetMapping mapping,
-      GraphLens graphLens) {
-    assert dest.isAligned(4);
-    int codeOffset = dest.position();
+  private int writeCodeItem(ProgramMethod method, DexWritableCode code) {
     GraphLens codeLens = code.getCodeLens(appView);
+    int codeOffset = dest.align(4);
+    mixedSectionOffsets.setOffsetFor(method.getDefinition(), codeOffset);
     // Fixed size header information.
     dest.putShort((short) code.getRegisterSize(method));
     dest.putShort((short) code.getIncomingRegisterSize(method));
diff --git a/src/main/java/com/android/tools/r8/dex/jumbostrings/ContainerJumboStringRewriter.java b/src/main/java/com/android/tools/r8/dex/jumbostrings/ContainerJumboStringRewriter.java
index dc287f8..4cf0940 100644
--- a/src/main/java/com/android/tools/r8/dex/jumbostrings/ContainerJumboStringRewriter.java
+++ b/src/main/java/com/android/tools/r8/dex/jumbostrings/ContainerJumboStringRewriter.java
@@ -37,7 +37,7 @@
     }
     // Compute string layout and handle jumbo strings for the last DEX section.
     timing.begin("Process last virtual file");
-    processVirtualFile(lastFile, timing, executorService);
+    processVirtualFile(lastFile, timing);
     timing.end();
     // Handle jumbo strings for the remaining DEX sections using the string ids in the last DEX
     // section.
@@ -46,7 +46,7 @@
         alwaysTrue(),
         (virtualFile, threadTiming) ->
             rewriteJumboStringsAndComputeDebugRepresentationWithExternalStringIds(
-                virtualFile, lastFile.getObjectMapping(), threadTiming, executorService),
+                virtualFile, lastFile.getObjectMapping(), threadTiming),
         appView.options(),
         executorService,
         timing,
@@ -54,22 +54,13 @@
   }
 
   private void rewriteJumboStringsAndComputeDebugRepresentationWithExternalStringIds(
-      VirtualFile virtualFile,
-      ObjectToOffsetMapping mapping,
-      Timing timing,
-      ExecutorService executorService)
-      throws ExecutionException {
-    computeOffsetMappingAndRewriteJumboStringsWithExternalStringIds(
-        virtualFile, timing, mapping, executorService);
+      VirtualFile virtualFile, ObjectToOffsetMapping mapping, Timing timing) {
+    computeOffsetMappingAndRewriteJumboStringsWithExternalStringIds(virtualFile, timing, mapping);
     DebugRepresentation.computeForFile(appView, virtualFile);
   }
 
   private void computeOffsetMappingAndRewriteJumboStringsWithExternalStringIds(
-      VirtualFile virtualFile,
-      Timing timing,
-      ObjectToOffsetMapping mapping,
-      ExecutorService executorService)
-      throws ExecutionException {
+      VirtualFile virtualFile, Timing timing, ObjectToOffsetMapping mapping) {
     if (virtualFile.isEmpty()) {
       return;
     }
@@ -77,8 +68,7 @@
     virtualFile.computeMapping(appView, lazyDexStrings.size(), timing, mapping);
     timing.end();
     timing.begin("Rewrite jumbo strings");
-    rewriteCodeWithJumboStrings(
-        virtualFile.getObjectMapping(), virtualFile.classes(), executorService);
+    rewriteCodeWithJumboStrings(virtualFile.getObjectMapping(), virtualFile.classes());
     timing.end();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/dex/jumbostrings/JumboStringRewriter.java b/src/main/java/com/android/tools/r8/dex/jumbostrings/JumboStringRewriter.java
index 342b881..22aef00 100644
--- a/src/main/java/com/android/tools/r8/dex/jumbostrings/JumboStringRewriter.java
+++ b/src/main/java/com/android/tools/r8/dex/jumbostrings/JumboStringRewriter.java
@@ -53,23 +53,19 @@
     ThreadUtils.processItemsThatMatches(
         virtualFiles,
         alwaysTrue(),
-        (virtualFile, timing0) -> processVirtualFile(virtualFile, timing0, executorService),
+        this::processVirtualFile,
         options,
         executorService,
         timing,
         timing.beginMerger("Pre-write phase", executorService));
   }
 
-  protected final void processVirtualFile(
-      VirtualFile virtualFile, Timing timing, ExecutorService executorService)
-      throws ExecutionException {
-    computeOffsetMappingAndRewriteJumboStrings(virtualFile, timing, executorService);
+  protected final void processVirtualFile(VirtualFile virtualFile, Timing timing) {
+    computeOffsetMappingAndRewriteJumboStrings(virtualFile, timing);
     DebugRepresentation.computeForFile(appView, virtualFile);
   }
 
-  private void computeOffsetMappingAndRewriteJumboStrings(
-      VirtualFile virtualFile, Timing timing, ExecutorService executorService)
-      throws ExecutionException {
+  private void computeOffsetMappingAndRewriteJumboStrings(VirtualFile virtualFile, Timing timing) {
     if (virtualFile.isEmpty()) {
       return;
     }
@@ -77,8 +73,7 @@
     virtualFile.computeMapping(appView, lazyDexStrings.size(), timing);
     timing.end();
     timing.begin("Rewrite jumbo strings");
-    rewriteCodeWithJumboStrings(
-        virtualFile.getObjectMapping(), virtualFile.classes(), executorService);
+    rewriteCodeWithJumboStrings(virtualFile.getObjectMapping(), virtualFile.classes());
     timing.end();
   }
 
@@ -90,10 +85,7 @@
    * be used.
    */
   protected final void rewriteCodeWithJumboStrings(
-      ObjectToOffsetMapping mapping,
-      Collection<DexProgramClass> classes,
-      ExecutorService executorService)
-      throws ExecutionException {
+      ObjectToOffsetMapping mapping, Collection<DexProgramClass> classes) {
     // Do not bail out early if forcing jumbo string processing.
     if (!options.getTestingOptions().forceJumboStringProcessing) {
       // If there are no strings with jumbo indices at all this is a no-op.
@@ -101,23 +93,19 @@
         return;
       }
     }
-
-    ThreadUtils.processItems(
-        classes,
-        clazz ->
-            clazz.forEachProgramMethodMatching(
-                DexEncodedMethod::hasCode,
-                method -> {
-                  DexWritableCode code = method.getDefinition().getCode().asDexWritableCode();
-                  DexWritableCode rewrittenCode =
-                      code.rewriteCodeWithJumboStrings(
-                          method,
-                          mapping,
-                          appView,
-                          options.getTestingOptions().forceJumboStringProcessing);
-                  method.setCode(rewrittenCode.asCode(), appView);
-                }),
-        options.getThreadingModule(),
-        executorService);
+    for (DexProgramClass clazz : classes) {
+      clazz.forEachProgramMethodMatching(
+          DexEncodedMethod::hasCode,
+          method -> {
+            DexWritableCode code = method.getDefinition().getCode().asDexWritableCode();
+            DexWritableCode rewrittenCode =
+                code.rewriteCodeWithJumboStrings(
+                    method,
+                    mapping,
+                    appView,
+                    options.getTestingOptions().forceJumboStringProcessing);
+            method.setCode(rewrittenCode.asCode(), appView);
+          });
+    }
   }
 }
diff --git a/src/test/java/com/android/tools/r8/dex/DexOutputBufferTest.java b/src/test/java/com/android/tools/r8/dex/DexOutputBufferTest.java
deleted file mode 100644
index 30c9413..0000000
--- a/src/test/java/com/android/tools/r8/dex/DexOutputBufferTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.dex;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.android.tools.r8.ByteBufferProvider;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class DexOutputBufferTest extends TestBase {
-
-  private final TestParameters parameters;
-
-  @Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withNoneRuntime().build();
-  }
-
-  public DexOutputBufferTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testNonExpandableWrapperByte() {
-    DexOutputBuffer buffer = new DexOutputBuffer(new ByteBufferProvider() {});
-    DexOutputBuffer wrapper1 = buffer.nonExpandableWrapper();
-    DexOutputBuffer wrapper2 = buffer.nonExpandableWrapper();
-    int defaultBufferSize = 256 * 1024; // private DEFAULT_BUFFER_SIZE in DexOutputBuffer.
-    for (int i = 0; i < defaultBufferSize; i++) {
-      wrapper1.putByte((byte) 1);
-      assertEquals(1, wrapper2.get());
-    }
-    try {
-      wrapper1.putByte((byte) 1);
-      fail("Unexpected successful operation.");
-    } catch (UnsupportedOperationException e) {
-      // Expected.
-    }
-    try {
-      wrapper2.putByte((byte) 1);
-      fail("Unexpected successful operation.");
-    } catch (UnsupportedOperationException e) {
-      // Expected.
-    }
-  }
-
-  @Test
-  public void testNonExpandableWrapperShort() {
-    DexOutputBuffer buffer = new DexOutputBuffer(new ByteBufferProvider() {});
-    DexOutputBuffer wrapper1 = buffer.nonExpandableWrapper();
-    DexOutputBuffer wrapper2 = buffer.nonExpandableWrapper();
-    int defaultBufferSize = 256 * 1024; // private DEFAULT_BUFFER_SIZE in DexOutputBuffer.
-    for (int i = 0; i < defaultBufferSize; i += 2 * 2) {
-      wrapper1.putShort(Short.MAX_VALUE);
-      assertEquals(Short.MAX_VALUE, wrapper2.getShort());
-      wrapper1.putShort(Short.MIN_VALUE);
-      assertEquals(Short.MIN_VALUE, wrapper2.getShort());
-    }
-    try {
-      wrapper1.putShort((short) 1);
-      fail("Unexpected successful operation.");
-    } catch (UnsupportedOperationException e) {
-      // Expected.
-    }
-    try {
-      wrapper2.putShort((short) 1);
-      fail("Unexpected successful operation.");
-    } catch (UnsupportedOperationException e) {
-      // Expected.
-    }
-  }
-}
diff --git a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
index 2d30a5e..7ecd693 100644
--- a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
@@ -2700,7 +2700,7 @@
 
   public static void writeApplication(AppView<?> appView) throws ExecutionException {
     appView.options().tool = Tool.R8;
-    R8.writeApplication(appView, null, Executors.newFixedThreadPool(2));
+    R8.writeApplication(appView, null, Executors.newSingleThreadExecutor());
   }
 
   public static void disassemble(AndroidApp app, PrintStream ps) throws IOException {