Skip to content

Commit

Permalink
[GR-29450] Add reporting on native image build artifacts.
Browse files Browse the repository at this point in the history
PullRequest: graal/8324
  • Loading branch information
pejovica committed Feb 23, 2021
2 parents 9d50d86 + c84d59e commit 58ab7f6
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,19 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.function.Consumer;

import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import static java.nio.file.StandardOpenOption.APPEND;

import com.oracle.graal.pointsto.flow.InvokeTypeFlow;
import com.oracle.graal.pointsto.meta.AnalysisField;
import java.io.OutputStream;

import jdk.vm.ci.code.BytecodePosition;
import jdk.vm.ci.common.JVMCIError;
Expand Down Expand Up @@ -107,7 +103,8 @@ private static void reportImpl(String description, Path folder, String fileName,

try (FileWriter fw = new FileWriter(Files.createFile(file).toFile())) {
try (PrintWriter writer = new PrintWriter(fw)) {
System.out.println("Printing " + description + " to " + file.toAbsolutePath());
Path cwd = Paths.get("").toAbsolutePath();
System.out.println("# Printing " + description + " to: " + cwd.relativize(file));
reporter.accept(writer);
}
}
Expand Down Expand Up @@ -148,8 +145,10 @@ private static void reportImpl(String description, Path folder, String fileName,
try {
Path reportDir = Files.createDirectories(folder);
Path file = reportDir.resolve(fileName);
try (OutputStream fos = Files.newOutputStream(file, CREATE, WRITE, append ? APPEND : TRUNCATE_EXISTING)) {
System.out.println("Printing " + description + " to " + file.toAbsolutePath());
try (OutputStream fos = Files.newOutputStream(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE,
append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING)) {
Path cwd = Paths.get("").toAbsolutePath();
System.out.println("# Printing " + description + " to: " + cwd.relativize(file));
reporter.accept(fos);
fos.flush();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core;

import java.nio.file.Path;

import org.graalvm.nativeimage.ImageSingletons;

/** Interface for collecting artifacts produced during native image build. */
public interface BuildArtifacts {
enum ArtifactType {
EXECUTABLE,
SHARED_LIB,
HEADER,
IMPORT_LIB,
DEBUG_INFO,
}

static BuildArtifacts singleton() {
return ImageSingletons.lookup(BuildArtifacts.class);
}

/** Adds an artifact produced during native image build. */
void add(ArtifactType type, Path artifact);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.ListIterator;
Expand All @@ -63,6 +64,7 @@
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugDumpScope;
Expand Down Expand Up @@ -152,6 +154,8 @@
import com.oracle.graal.pointsto.typestate.TypeState;
import com.oracle.graal.pointsto.util.Timer;
import com.oracle.graal.pointsto.util.Timer.StopTimer;
import com.oracle.svm.core.BuildArtifacts;
import com.oracle.svm.core.BuildArtifacts.ArtifactType;
import com.oracle.svm.core.ClassLoaderQuery;
import com.oracle.svm.core.FrameAccess;
import com.oracle.svm.core.JavaMainWrapper.JavaMainSupport;
Expand Down Expand Up @@ -304,7 +308,6 @@ public class NativeImageGenerator {
private AtomicBoolean buildStarted = new AtomicBoolean();

private Pair<Method, CEntryPointData> mainEntryPoint;
private TemporaryBuildDirectoryProviderImpl buildDirectoryProvider;

public NativeImageGenerator(ImageClassLoader loader, HostedOptionProvider optionProvider, Pair<Method, CEntryPointData> mainEntryPoint) {
this.loader = loader;
Expand Down Expand Up @@ -464,31 +467,32 @@ public void run(Map<Method, CEntryPointData> entryPoints,

setSystemPropertiesForImageLate(k);

int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(new OptionValues(optionProvider.getHostedValues()));
this.buildExecutor = createForkJoinPool(maxConcurrentThreads);
buildExecutor.submit(() -> {
ImageSingletonsSupportImpl.HostedManagement.installInThread(new ImageSingletonsSupportImpl.HostedManagement());
this.buildExecutor = createForkJoinPool(compilationExecutor.getParallelism());

Map<ArtifactType, List<Path>> buildArtifacts = new EnumMap<>(ArtifactType.class);
buildExecutor.submit(() -> {
ImageSingletons.add(BuildArtifacts.class, (type, artifact) -> buildArtifacts.computeIfAbsent(type, t -> new ArrayList<>()).add(artifact));
ImageSingletons.add(ClassLoaderQuery.class, new ClassLoaderQueryImpl(loader.getClassLoader()));
ImageSingletons.add(HostedOptionValues.class, new HostedOptionValues(optionProvider.getHostedValues()));
ImageSingletons.add(HostedOptionOverrideValues.class, new HostedOptionOverrideValues());
ImageSingletons.add(RuntimeOptionValues.class, new RuntimeOptionValues(optionProvider.getRuntimeValues(), allOptionNames));
watchdog = new DeadlockWatchdog();
try {
buildDirectoryProvider = new TemporaryBuildDirectoryProviderImpl();
ImageSingletons.add(TemporaryBuildDirectoryProvider.class, buildDirectoryProvider);
try (TemporaryBuildDirectoryProviderImpl tempDirectoryProvider = new TemporaryBuildDirectoryProviderImpl()) {
ImageSingletons.add(TemporaryBuildDirectoryProvider.class, tempDirectoryProvider);
doRun(entryPoints, javaMainSupport, imageName, k, harnessSubstitutions, compilationExecutor, analysisExecutor);
} catch (Throwable t) {
try {
cleanup();
} catch (Throwable ecleanup) {
t.addSuppressed(ecleanup);
}
throw t;
} finally {
watchdog.close();
}
cleanup();
}).get();

Path buildDir = generatedFiles(HostedOptionValues.singleton());
ReportUtils.report("build artifacts", buildDir.resolve(imageName + ".build_artifacts.txt"),
writer -> buildArtifacts.forEach((artifactType, paths) -> {
writer.println("[" + artifactType + "]");
paths.stream().map(buildDir::relativize).forEach(writer::println);
writer.println();
}));
} catch (InterruptedException | CancellationException e) {
System.out.println("Interrupted!");
throw new InterruptImageBuilding(e);
Expand All @@ -503,13 +507,6 @@ public void run(Map<Method, CEntryPointData> entryPoints,
}
}

private void cleanup() {
if (buildDirectoryProvider != null) {
buildDirectoryProvider.clean();
}
featureHandler.forEachFeature(Feature::cleanup);
}

protected static void setSystemPropertiesForImageEarly() {
System.setProperty(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_BUILDTIME);
}
Expand All @@ -529,8 +526,7 @@ protected static void clearSystemPropertiesForImage() {
}

private ForkJoinPool createForkJoinPool(int maxConcurrentThreads) {
ImageSingletonsSupportImpl.HostedManagement vmConfig = new ImageSingletonsSupportImpl.HostedManagement();
ImageSingletonsSupportImpl.HostedManagement.installInThread(vmConfig);
ImageSingletonsSupportImpl.HostedManagement vmConfig = ImageSingletonsSupportImpl.HostedManagement.getAndAssertExists();
return new ForkJoinPool(
maxConcurrentThreads,
pool -> new ForkJoinWorkerThread(pool) {
Expand Down Expand Up @@ -560,7 +556,8 @@ private void doRun(Map<Method, CEntryPointData> entryPoints,

OptionValues options = HostedOptionValues.singleton();
SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
try (DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(originalSnippetReflection)).build()) {
try (DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(originalSnippetReflection)).build();
DebugCloseable featureCleanup = () -> featureHandler.forEachFeature(Feature::cleanup)) {
setupNativeImage(imageName, options, entryPoints, javaMainSupport, harnessSubstitutions, analysisExecutor, originalSnippetReflection, debug);

boolean returnAfterAnalysis = runPointsToAnalysis(imageName, options, debug);
Expand Down Expand Up @@ -695,7 +692,7 @@ private void doRun(Map<Method, CEntryPointData> entryPoints,
return;
}

AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, hUniverse, inv, tmpDir, image.getBootImageKind(), debug);
AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, hUniverse, inv, tmpDir, image.getImageKind(), debug);
featureHandler.forEachFeature(feature -> feature.afterImageWrite(afterConfig));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
*/
package com.oracle.svm.hosted;

import com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider;
import com.oracle.svm.core.util.VMError;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
Expand All @@ -35,7 +32,10 @@
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class TemporaryBuildDirectoryProviderImpl implements TemporaryBuildDirectoryProvider {
import com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider;
import com.oracle.svm.core.util.VMError;

public class TemporaryBuildDirectoryProviderImpl implements TemporaryBuildDirectoryProvider, AutoCloseable {

private Path tempDirectory;
private boolean deleteTempDirectory;
Expand All @@ -60,6 +60,13 @@ public synchronized Path getTemporaryBuildDirectory() {
return tempDirectory.toAbsolutePath();
}

@Override
public void close() {
if (deleteTempDirectory) {
deleteAll(getTemporaryBuildDirectory());
}
}

private static void deleteAll(Path path) {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
Expand All @@ -79,11 +86,4 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
throw VMError.shouldNotReachHere(ex);
}
}

void clean() {
if (deleteTempDirectory) {
deleteAll(getTemporaryBuildDirectory());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public Path writeFile(String fileName) {
try (BufferedWriter writer = Files.newBufferedWriter(outputFile, StandardCharsets.UTF_8)) {
for (String line : lines) {
writer.write(line);
writer.write("\n");
writer.newLine();
}
} catch (ClosedByInterruptException ex) {
throw new InterruptImageBuilding();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static com.oracle.svm.core.util.VMError.shouldNotReachHere;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -78,24 +79,25 @@ public static List<String> readAllLines(InputStream source) {
}
}

public static Process executeCommand(String... args) throws IOException, InterruptedException {
public static int executeCommand(String... args) throws IOException, InterruptedException {
return executeCommand(Arrays.asList(args));
}

public static Process executeCommand(List<String> args) throws IOException, InterruptedException {
@SuppressWarnings("try")
public static int executeCommand(List<String> args) throws IOException, InterruptedException {
ProcessBuilder command = prepareCommand(args, null).redirectErrorStream(true);

traceCommand(command);

Process process = command.start();
try (Closeable ignored = process::destroy) {

try (InputStream inputStream = process.getInputStream()) {
traceCommandOutput(readAllLines(inputStream));
}

process.waitFor();
try (InputStream inputStream = process.getInputStream()) {
traceCommandOutput(readAllLines(inputStream));
}

return process;
return process.waitFor();
}
}

public static ProcessBuilder prepareCommand(List<String> args, Path commandDir) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ public String getFilename(String basename) {
}
}

protected final NativeImageKind kind;
protected final NativeImageKind imageKind;

protected AbstractBootImage(NativeImageKind k, HostedUniverse universe, HostedMetaAccess metaAccess, NativeLibraries nativeLibs, NativeImageHeap heap, NativeImageCodeCache codeCache,
List<HostedMethod> entryPoints, ClassLoader imageClassLoader) {
this.kind = k;
this.imageKind = k;
this.universe = universe;
this.metaAccess = metaAccess;
this.nativeLibs = nativeLibs;
Expand All @@ -107,8 +107,8 @@ protected AbstractBootImage(NativeImageKind k, HostedUniverse universe, HostedMe
this.imageClassLoader = imageClassLoader;
}

public NativeImageKind getBootImageKind() {
return kind;
public NativeImageKind getImageKind() {
return imageKind;
}

public int getImageSize() {
Expand Down Expand Up @@ -164,8 +164,4 @@ public NativeImageHeap getHeap() {
public boolean requiresCustomDebugRelocation() {
return false;
}

public AbstractBootImage.NativeImageKind getKind() {
return kind;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public static class Options {
protected final List<String> libs = new ArrayList<>();
protected Path tempDirectory;
protected Path outputFile;
protected AbstractBootImage.NativeImageKind outputKind;

@Override
public List<Path> getInputFiles() {
Expand All @@ -68,14 +67,6 @@ public void addInputFile(int index, Path filename) {
inputFilenames.add(index, filename);
}

public AbstractBootImage.NativeImageKind getOutputKind() {
return outputKind;
}

public void setOutputKind(AbstractBootImage.NativeImageKind k) {
outputKind = k;
}

@Override
public List<String> getLibPaths() {
return Collections.unmodifiableList(libpaths);
Expand Down
Loading

0 comments on commit 58ab7f6

Please sign in to comment.