Skip to content

Commit 584610c

Browse files
ted-xiecopybara-github
authored andcommitted
Merge #360 by ted-xie: Enable persistent workers in DesugarDexSharding
Closes #360 COPYBARA_INTEGRATE_REVIEW=#360 from ted-xie:mi_workers 15ef95d PiperOrigin-RevId: 751045306 Change-Id: Id5d238f5b5f5bc40cfa0de46291e48ca05785185
1 parent 3115eee commit 584610c

File tree

4 files changed

+87
-9
lines changed

4 files changed

+87
-9
lines changed

mobile_install/utils.bzl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ def dex(ctx, jar, out_dex_shards, deps = None):
196196
outputs = out_dex_shards,
197197
mnemonic = "DesugarDexSharding",
198198
progress_message = "MI Desugar, dex and sharding " + jar.path,
199+
execution_requirements = {
200+
"worker-key-mnemonic": "DesugarDexSharding",
201+
"supports-workers": "1",
202+
"supports-multiplex-workers": "1",
203+
},
199204
toolchain = None,
200205
)
201206

src/tools/java/com/google/devtools/build/android/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ java_library(
138138
":android_builder_lib",
139139
"//src/tools/java/com/google/devtools/build/android/r8",
140140
"//src/tools/java/com/google/devtools/build/android/r8:constants",
141+
"@bazel_worker_java//src/main/java/com/google/devtools/build/lib/worker:work_request_handlers",
141142
"@rules_android_maven//:com_beust_jcommander",
142143
"@rules_android_maven//:com_google_guava_guava",
143144
],

src/tools/java/com/google/devtools/build/android/DesugarDexShardingAction.java

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,38 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.android;
1515

16+
import static java.lang.Math.min;
1617
import static java.nio.charset.StandardCharsets.UTF_8;
1718
import static java.util.concurrent.TimeUnit.MILLISECONDS;
1819

1920
import com.beust.jcommander.JCommander;
2021
import com.beust.jcommander.Parameter;
2122
import com.beust.jcommander.ParameterException;
2223
import com.beust.jcommander.Parameters;
24+
import com.google.common.cache.Cache;
25+
import com.google.common.cache.CacheBuilder;
26+
import com.google.common.cache.Weigher;
2327
import com.google.common.collect.Sets;
2428
import com.google.common.io.ByteStreams;
2529
import com.google.devtools.build.android.Converters.CompatExistingPathConverter;
2630
import com.google.devtools.build.android.Converters.CompatPathConverter;
2731
import com.google.devtools.build.android.r8.CompatDexBuilder;
32+
import com.google.devtools.build.android.r8.CompatDexBuilder.DexingKeyR8;
2833
import com.google.devtools.build.android.r8.Constants;
2934
import com.google.devtools.build.android.r8.Desugar;
35+
import com.google.devtools.build.lib.worker.ProtoWorkerMessageProcessor;
36+
import com.google.devtools.build.lib.worker.WorkRequestHandler;
3037
import java.io.BufferedReader;
3138
import java.io.FileInputStream;
3239
import java.io.FileOutputStream;
3340
import java.io.IOException;
3441
import java.io.InputStream;
42+
import java.io.PrintStream;
43+
import java.io.PrintWriter;
3544
import java.nio.file.Files;
3645
import java.nio.file.Path;
3746
import java.nio.file.attribute.FileTime;
47+
import java.time.Duration;
3848
import java.util.ArrayList;
3949
import java.util.Arrays;
4050
import java.util.Enumeration;
@@ -169,8 +179,27 @@ private static void dexbuilder(Options options, Path jar, Path outputZip)
169179
args.add(Integer.toString(options.minSdkVersion));
170180
}
171181

182+
// Set up dexer cache
183+
Cache<DexingKeyR8, byte[]> dexCache = null;
184+
if (options.persistentWorker) {
185+
final long ONE_MEG = 1024 * 1024;
186+
dexCache =
187+
CacheBuilder.newBuilder()
188+
// Use at most 200 MB for cache and leave at least 25 MB of heap space alone. For
189+
// reference:
190+
// .class & class.dex files are around 1-5 KB, so this fits ~30K-35K class-dex pairs.
191+
.maximumWeight(min(Runtime.getRuntime().maxMemory() - 25 * ONE_MEG, 200 * ONE_MEG))
192+
.weigher(
193+
new Weigher<DexingKeyR8, byte[]>() {
194+
@Override
195+
public int weigh(DexingKeyR8 key, byte[] value) {
196+
return key.classfileContent().length + value.length;
197+
}
198+
})
199+
.build();
200+
}
172201
CompatDexBuilder compatDexBuilder = new CompatDexBuilder();
173-
compatDexBuilder.dexEntries(args);
202+
compatDexBuilder.dexEntries(dexCache, args);
174203
}
175204

176205
private static int indexAny(String s, char[] chars) {
@@ -272,25 +301,68 @@ private static void zipShard(Path zip, List<Path> outs) throws IOException {
272301

273302
public static void main(String[] args) throws Exception {
274303
List<String> argsList = new ArrayList<>(Arrays.asList(args));
275-
Options options = new Options();
276304

277-
final String flagfilePrefix = "-flagfile=";
305+
if (argsList.contains("--persistent_worker")) {
306+
System.exit(runPersistentWorker());
307+
} else {
308+
processRequest(argsList);
309+
}
310+
}
278311

312+
private static int runPersistentWorker() {
313+
PrintStream realStdErr = System.err;
314+
315+
try {
316+
WorkRequestHandler workerHandler =
317+
new WorkRequestHandler.WorkRequestHandlerBuilder(
318+
new WorkRequestHandler.WorkRequestCallback(
319+
(request, pw) -> processRequestForWorker(request.getArgumentsList(), pw, realStdErr)),
320+
realStdErr,
321+
new ProtoWorkerMessageProcessor(System.in, System.out))
322+
.setCpuUsageBeforeGc(Duration.ofSeconds(10))
323+
.build();
324+
workerHandler.processRequests();
325+
} catch (IOException e) {
326+
realStdErr.println(e);
327+
e.printStackTrace(realStdErr);
328+
return 1;
329+
}
330+
return 0;
331+
}
332+
333+
private static int processRequestForWorker(List<String> argsList, PrintWriter pw, PrintStream ps) {
334+
try {
335+
processRequest(argsList);
336+
} catch (Exception e) {
337+
// In worker mode, if we catch an exception, don't throw it, just write it to the PrintStream
338+
ps.println(e);
339+
e.printStackTrace(pw);
340+
341+
return 1;
342+
}
343+
344+
return 0;
345+
}
346+
347+
private static void processRequest(List<String> argsList) throws Exception {
348+
final String flagfilePrefix = "-flagfile=";
279349
// Deal with param files.
280-
if (args.length >= 1 && args[0].startsWith(flagfilePrefix)) {
281-
argsList.clear();
350+
if (argsList.size() >= 1 && argsList.get(0).startsWith(flagfilePrefix)) {
351+
List<String> argsListTmp = new ArrayList<>();
282352
// Check if the first argument is a flagfile
283-
String flagfile = args[0].substring(flagfilePrefix.length());
353+
String flagfile = argsList.get(0).substring(flagfilePrefix.length());
284354

285355
// Read the flagfile
286356
try (BufferedReader reader = Files.newBufferedReader(Path.of(flagfile))) {
287357
String line;
288358
while ((line = reader.readLine()) != null) {
289-
argsList.add(line);
359+
argsListTmp.add(line);
290360
}
291361
}
362+
argsList = argsListTmp;
292363
}
293364

365+
Options options = new Options();
294366
JCommander.newBuilder().addObject(options).build().parse(argsList.toArray(new String[0]));
295367

296368
if (options.androidJar == null) {

src/tools/java/com/google/devtools/build/android/r8/CompatDexBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ private int processRequest(
208208
}
209209
}
210210

211-
public void dexEntries(List<String> args) throws ExecutionException {
211+
public void dexEntries(@Nullable Cache<DexingKeyR8, byte[]> dexCache, List<String> args) throws ExecutionException {
212212
try {
213-
dexEntries(/* dexCache= */ null, args, new DexDiagnosticsHandler(System.err));
213+
dexEntries(dexCache, args, new DexDiagnosticsHandler(System.err));
214214
} catch (Exception e) {
215215
throw new ExecutionException(
216216
"CompatDexBuilder raised exception with args: '" + args + "'", e);

0 commit comments

Comments
 (0)