diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java index c843ff9cd9d1..a3d5e6cef694 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java @@ -136,6 +136,7 @@ public void execute(Project project) { } } + // TODO: this has lot of common code with default case, refactor to common method if (project.buildOptions().optimizeCodegen()) { Path relativePathToExecutable = currentDir.relativize(executablePath); String relativePathToExecutableString = diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BuildOptions.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BuildOptions.java index 5b342a861d39..362e5644f5bc 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BuildOptions.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BuildOptions.java @@ -262,7 +262,7 @@ public enum OptionName { EXPORT_COMPONENT_MODEL("exportComponentModel"), GRAAL_VM_BUILD_OPTIONS("graalvmBuildOptions"), SHOW_DEPENDENCY_DIAGNOSTICS("showDependencyDiagnostics"), - OPTIMIZE_DEPENDENCY_COMPILATION("optimizeDependencyCompilation"); + OPTIMIZE_DEPENDENCY_COMPILATION("optimizeDependencyCompilation"), OPTIMIZE_CODEGEN("optimizeCodegen"), OPTIMIZE_REPORT("optimizeReport"); diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CodeGenOptimizationReportEmitter.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CodeGenOptimizationReportEmitter.java index 61e79d06559f..ec373d6ea7f8 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CodeGenOptimizationReportEmitter.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CodeGenOptimizationReportEmitter.java @@ -43,7 +43,7 @@ /** * Emits time durations and optimized node details for codegen optimization. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class CodeGenOptimizationReportEmitter { @@ -70,7 +70,7 @@ public static CodeGenOptimizationReportEmitter getInstance(CompilerContext compi return codegenOptimizationReportEmitter; } - protected void flipBirOptimizationTimer(PackageID pkgId) { + void flipBirOptimizationTimer(PackageID pkgId) { long currentTime = System.currentTimeMillis(); if (this.birOptimizationDurations.containsKey(pkgId)) { long totalDuration = currentTime - this.birOptimizationDurations.get(pkgId); @@ -80,7 +80,7 @@ protected void flipBirOptimizationTimer(PackageID pkgId) { } } - protected void flipNativeOptimizationTimer() { + void flipNativeOptimizationTimer() { if (this.nativeOptimizationDuration == 0) { this.nativeOptimizationDuration = System.currentTimeMillis(); } else { @@ -88,30 +88,31 @@ protected void flipNativeOptimizationTimer() { } } - protected void emitBirOptimizationDuration() { + void emitBirOptimizationDuration() { long totalDuration = this.birOptimizationDurations.values().stream().mapToLong(Long::longValue).sum(); this.out.printf("Duration for unused BIR node analysis : %dms%n", totalDuration); this.birOptimizationDurations.forEach((key, value) -> this.out.printf(" %s : %dms%n", key, value)); this.out.println(); } - protected void emitNativeOptimizationDuration() { + void emitNativeOptimizationDuration() { this.out.println( "Duration for Bytecode optimization (analysis + deletion) : " + this.nativeOptimizationDuration + "ms"); this.nativeOptimizationDuration = 0; } - protected void emitOptimizedExecutableSize(Path executableFilePath) { + void emitOptimizedExecutableSize(Path executableFilePath) { + float optimizedJarSize; try { - float optimizedJarSize = Files.size(executableFilePath) / (1024f * 1024f); - System.out.printf("Optimized file size : %f MB%n", optimizedJarSize); + optimizedJarSize = Files.size(executableFilePath) / (1024f * 1024f); } catch (IOException e) { throw new ProjectException("Failed to emit optimized executable size ", e); } + System.out.printf("Optimized file size : %f MB%n", optimizedJarSize); } - protected void emitCodegenOptimizationReport(Map invocationDataMap, - Path targetDirectoryPath) { + void emitCodegenOptimizationReport(Map invocationDataMap, + Path targetDirectoryPath) { if (!Files.exists(targetDirectoryPath)) { try { Files.createDirectories(targetDirectoryPath); @@ -119,7 +120,7 @@ protected void emitCodegenOptimizationReport(Map reports = new LinkedHashMap<>(invocationDataMap.size()); invocationDataMap.forEach((key, value) -> reports.put(key.toString(), getCodegenOptimizationReport(value))); Path jsonFilePath = targetDirectoryPath.resolve(CODEGEN_OPTIMIZATION_REPORT); @@ -134,8 +135,7 @@ protected void emitCodegenOptimizationReport(Map usedNativeClassPaths) { + TypeDefinitions usedTypeDefNames, TypeDefinitions unusedTypeDefNames, + Set usedNativeClassPaths) { /** * @param sourceFunctions BIR functions directly derived from source diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CompilationOptions.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CompilationOptions.java index 381bc76e9178..fc620c5f2e4a 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CompilationOptions.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/CompilationOptions.java @@ -43,13 +43,22 @@ public class CompilationOptions { Boolean optimizeDependencyCompilation; Boolean optimizeCodegen; Boolean optimizeReport; - + private CompilationOptions(Boolean offlineBuild, Boolean observabilityIncluded, Boolean dumpBir, + Boolean dumpBirFile, String cloud, Boolean listConflictedClasses, Boolean sticky, + Boolean dumpGraph, Boolean dumpRawGraphs, Boolean withCodeGenerators, + Boolean withCodeModifiers, Boolean configSchemaGen, Boolean exportOpenAPI, + Boolean exportComponentModel, Boolean enableCache, Boolean disableSyntaxTree, + Boolean remoteManagement, Boolean optimizeDependencyCompilation, + Boolean optimizeCodegen, Boolean optimizeReport) { + this.offlineBuild = offlineBuild; + this.observabilityIncluded = observabilityIncluded; this.dumpBir = dumpBir; this.dumpBirFile = dumpBirFile; this.cloud = cloud; this.listConflictedClasses = listConflictedClasses; this.sticky = sticky; this.dumpGraph = dumpGraph; + this.dumpRawGraphs = dumpRawGraphs; this.withCodeGenerators = withCodeGenerators; this.withCodeModifiers = withCodeModifiers; this.configSchemaGen = configSchemaGen; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java index ac184f6ab95e..9a3dbce79ef7 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java @@ -32,7 +32,6 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntryPredicate; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipFile; -import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.apache.commons.io.FilenameUtils; import org.ballerinalang.maven.Dependency; import org.ballerinalang.maven.MavenResolver; @@ -41,7 +40,6 @@ import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; import org.ballerinalang.model.types.SelectivelyImmutableReferenceType; -import org.wso2.ballerinalang.compiler.CompiledJarFile; import org.wso2.ballerinalang.compiler.bir.codegen.CodeGenerator; import org.wso2.ballerinalang.compiler.bir.codegen.CompiledJarFile; import org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil; @@ -60,13 +58,11 @@ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.channels.SeekableByteChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -86,7 +82,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.JarInputStream; @@ -115,6 +110,8 @@ public class JBallerinaBackend extends CompilerBackend { private static final String JAR_FILE_NAME_SUFFIX = ""; private static final HashSet excludeExtensions = new HashSet<>(Lists.of("DSA", "SF")); private static final String OS = System.getProperty("os.name").toLowerCase(Locale.getDefault()); + public static final String JAR_NAME_SEPARATOR = "-"; + private final PackageResolution pkgResolution; private final JvmTarget jdkVersion; private final PackageContext packageContext; @@ -131,7 +128,6 @@ public class JBallerinaBackend extends CompilerBackend { private final SymbolTable symbolTable; private final UsedBIRNodeAnalyzer usedBIRNodeAnalyzer; private final CodeGenOptimizationReportEmitter codeGenOptimizationReportEmitter; - private final Map optimizedJarStreams; private final Set unusedCompilerLevelPackageIds; final Set unusedProjectLevelPackageIds; final Set unusedModuleIds; @@ -171,13 +167,11 @@ private JBallerinaBackend(PackageCompilation packageCompilation, JvmTarget jdkVe this.usedBIRNodeAnalyzer = UsedBIRNodeAnalyzer.getInstance(compilerContext); this.codeGenOptimizationReportEmitter = CodeGenOptimizationReportEmitter.getInstance(compilerContext); if (packageCompilation.compilationOptions().optimizeCodegen()) { - this.optimizedJarStreams = new HashMap<>(); this.unusedCompilerLevelPackageIds = new HashSet<>(); this.unusedProjectLevelPackageIds = new HashSet<>(); this.unusedModuleIds = new HashSet<>(); this.pkgWiseUsedNativeClassPaths = new LinkedHashMap<>(); } else { - this.optimizedJarStreams = Collections.emptyMap(); this.unusedCompilerLevelPackageIds = Collections.emptySet(); this.unusedProjectLevelPackageIds = Collections.emptySet(); this.unusedModuleIds = Collections.emptySet(); @@ -195,8 +189,7 @@ private void performCodeGen(boolean shrink) { return; } - if (this.packageContext.project().buildOptions().optimizeCodegen() && - !this.packageContext.project().buildOptions().skipTests()) { + if (shouldOptimizeTestDependencies()) { markTestDependenciesForDuplicateBIRGen(); } List diagnostics = new ArrayList<>(); @@ -214,8 +207,7 @@ private void performCodeGen(boolean shrink) { if (moduleContext.moduleId().packageId().equals(packageContext.packageId()) && packageCompilation.diagnosticResult().hasErrors()) { for (Diagnostic diagnostic : moduleContext.diagnostics()) { - moduleDiagnostics.add( - new PackageDiagnostic(diagnostic, moduleContext.descriptor(), project)); + moduleDiagnostics.add(new PackageDiagnostic(diagnostic, moduleContext.descriptor(), project)); } continue; } @@ -227,17 +219,12 @@ private void performCodeGen(boolean shrink) { if (this.packageContext.project().buildOptions().showDependencyDiagnostics() || !ProjectKind.BALA_PROJECT.equals(project.kind()) || (diagnostic.diagnosticInfo().severity() == DiagnosticSeverity.ERROR)) { - moduleDiagnostics.add( - new PackageDiagnostic(diagnostic, moduleContext.descriptor(), project)); + moduleDiagnostics.add(new PackageDiagnostic(diagnostic, moduleContext.descriptor(), project)); } } - if (moduleContext.project().kind() == ProjectKind.BALA_PROJECT) { - moduleContext.cleanBLangPackage(); - } - if (shrink) { - ModuleContext.shrinkDocuments(moduleContext); - } - // Codegen happens later when --optimize flag is active. We cannot clean the BlangPkgs until then. + + // Codegen happens later in {@code optimizeAndCodeGen} when --optimize flag is + // active. if (!project.buildOptions().optimizeCodegen() && project.kind() == ProjectKind.BALA_PROJECT) { moduleContext.cleanBLangPackage(); } @@ -258,8 +245,16 @@ private void performCodeGen(boolean shrink) { codeGenCompleted = true; } + private boolean shouldOptimizeTestDependencies() { + return this.packageContext.project().buildOptions().optimizeCodegen() && + !this.packageContext.project().buildOptions().skipTests(); + } + private void registerUnusedBIRNodes() { List topologicallySortedModuleList = pkgResolution.topologicallySortedModuleList(); + // TODO: refactor this, + // get all modules for which isRootModule is true, analyze them while passing a + // context // Reversed the for loop because used BIRNode analysis should start from the root module. // Root module is usually found last in the topologicallySortedModuleList. for (int i = topologicallySortedModuleList.size() - 1; i >= 0; i--) { @@ -315,7 +310,6 @@ private void markCommonDependencies(BLangPackage bLangPackage) { .filter(testablePkgDependencies::contains).filter(pkgSymbol -> !isWhiteListedModule(pkgSymbol.pkgID)) .forEach(pkgSymbol -> { pkgSymbol.shouldGenerateDuplicateBIR = true; - // Have to use a hashmap because the pkgIds get mutated later JvmCodeGenUtil.duplicatePkgsMap.put( pkgSymbol.pkgID.orgName + pkgSymbol.pkgID.getNameComps().toString(), pkgSymbol.pkgID); @@ -369,11 +363,11 @@ private boolean platformLibraryGenerated(ModuleContext moduleContext) { return moduleContext.currentCompilationState() == ModuleCompilationState.PLATFORM_LIBRARY_GENERATED; } - private void updateUnusedPkgMaps(ModuleContext ususedModuleContext) { - unusedModuleIds.add(ususedModuleContext.moduleId()); - unusedCompilerLevelPackageIds.add(ususedModuleContext.bLangPackage().symbol.pkgID); - if (ususedModuleContext.isDefaultModule()) { - unusedProjectLevelPackageIds.add(ususedModuleContext.moduleId().packageId()); + private void updateUnusedPkgMaps(ModuleContext unusedModuleContext) { + unusedModuleIds.add(unusedModuleContext.moduleId()); + unusedCompilerLevelPackageIds.add(unusedModuleContext.bLangPackage().symbol.pkgID); + if (unusedModuleContext.isDefaultModule()) { + unusedProjectLevelPackageIds.add(unusedModuleContext.moduleId().packageId()); } } @@ -434,7 +428,7 @@ public EmitResult emit(TestEmitArgs testEmitArgs) { } private EmitResult getEmitResult(Path filePath, Path generatedArtifact, BalCommand balCommand, - List emitDiagnostics) { + List emitDiagnostics) { if (filePath != null) { List pluginDiagnostics = notifyCompilationCompletion(filePath, balCommand); if (!pluginDiagnostics.isEmpty()) { @@ -592,7 +586,7 @@ public void performCodeGen(ModuleContext moduleContext, CompilationCache compila } } - public void performOptimizedCodeGen(ModuleContext moduleContext) { + private void performOptimizedCodeGen(ModuleContext moduleContext) { BLangPackage bLangPackage = moduleContext.bLangPackage(); boolean isRemoteMgtEnabled = moduleContext.project().buildOptions().compilationOptions().remoteManagement(); @@ -601,7 +595,7 @@ public void performOptimizedCodeGen(ModuleContext moduleContext) { } if (isRootModule(moduleContext)) { - JvmCodeGenUtil.markIsRootPackage(); + JvmCodeGenUtil.markAsRootPackage(); } optimizeBirPackage(bLangPackage.symbol); @@ -620,12 +614,8 @@ public void performOptimizedCodeGen(ModuleContext moduleContext) { jarFileName = getJarFileName(moduleContext) + "_OPTIMIZED" + JAR_FILE_NAME_SUFFIX; } try { - ByteArrayOutputStream byteStream = JarWriter.write(compiledJarFile, getResources(moduleContext)); - if (!this.packageContext.project().buildOptions().skipTests()) { - moduleContext.getCompilationCache().cachePlatformSpecificLibrary(this, jarFileName, byteStream, true); - } else { - optimizedJarStreams.putIfAbsent(jarFileName, byteStream); - } + ByteArrayOutputStream byteStream = compiledJarFile.toByteArrayStream(); + moduleContext.getCompilationCache().cachePlatformSpecificLibrary(this, jarFileName, byteStream, true); } catch (IOException e) { throw new ProjectException("Failed to cache generated jar, module: " + moduleContext.moduleName()); } @@ -644,7 +634,7 @@ public void performOptimizedCodeGen(ModuleContext moduleContext) { CompiledJarFile compiledTestJarFile = jvmCodeGenerator.generateTestModule(bLangPackage.testablePkgs.get(0), isRemoteMgtEnabled); try { - ByteArrayOutputStream byteStream = JarWriter.write(compiledTestJarFile, getAllResources(moduleContext)); + ByteArrayOutputStream byteStream = compiledTestJarFile.toByteArrayStream(); moduleContext.getCompilationCache().cachePlatformSpecificLibrary(this, testJarFileName, byteStream, true); } catch (IOException e) { throw new ProjectException("Failed to cache generated test jar, module: " + moduleContext.moduleName()); @@ -667,7 +657,7 @@ private void duplicateCodegen(ModuleContext moduleContext, boolean isRemoteMgtEn bLangPackage.symbol.bir = optimizableBirPkg; String jarFileName = getJarFileName(moduleContext) + JAR_FILE_NAME_SUFFIX; try { - ByteArrayOutputStream byteStream = JarWriter.write(originalJarFile, getResources(moduleContext)); + ByteArrayOutputStream byteStream = originalJarFile.toByteArrayStream(); moduleContext.getCompilationCache().cachePlatformSpecificLibrary(this, jarFileName, byteStream, false); } catch (IOException e) { throw new ProjectException("Failed to cache generated jar, module: " + moduleContext.moduleName()); @@ -749,8 +739,8 @@ private String getJarFileName(ModuleContext moduleContext) { jarName = getFileNameWithoutExtension(documentName); } else { jarName = getThinJarFileName(moduleContext.descriptor().org(), - moduleContext.moduleName().toString(), - moduleContext.descriptor().version()); + moduleContext.moduleName().toString(), + moduleContext.descriptor().version()); } return jarName; @@ -843,23 +833,21 @@ private void sortAndCopyJars(Collection jarLibraries, ZipArchiveOutp } } - private void assembleOptimizedExecutableJar(Path executableFilePath, - Manifest manifest, - Collection jarLibraries) throws IOException { + private void assembleOptimizedExecutableJar(Path executableFilePath, Manifest manifest, + Collection jarLibraries) throws IOException { String birOptimizedJarPath = executableFilePath.toString() .replace(ProjectConstants.BLANG_COMPILED_JAR_EXT, ProjectConstants.BIR_OPTIMIZED_JAR_SUFFIX); String bytecodeOptimizedJarPath = executableFilePath.toString() .replace(ProjectConstants.BLANG_COMPILED_JAR_EXT, ProjectConstants.BYTECODE_OPTIMIZED_JAR_SUFFIX); - ZipArchiveOutputStream outStream = new ZipArchiveOutputStream( - new BufferedOutputStream(new FileOutputStream(birOptimizedJarPath))); - try { + try (ZipArchiveOutputStream outStream = new ZipArchiveOutputStream( + new BufferedOutputStream(new FileOutputStream(birOptimizedJarPath)))) { writeManifest(manifest, outStream); // Sort jar libraries list to avoid inconsistent jar reporting List sortedJarLibraries = jarLibraries.stream() .sorted(Comparator.comparing(jarLibrary -> jarLibrary.path().getFileName())) - .collect(Collectors.toList()); + .toList(); // Used to prevent adding duplicated entries during the final jar creation. HashMap copiedEntries = new HashMap<>(); @@ -872,45 +860,39 @@ private void assembleOptimizedExecutableJar(Path executableFilePath, copyJar(outStream, library, copiedEntries, serviceEntries); } - // Clean optimized JAR byte streams - optimizedJarStreams.clear(); - // Copy merged spi services. - for (Map.Entry entry : serviceEntries.entrySet()) { - String s = entry.getKey(); - StringBuilder service = entry.getValue(); - JarArchiveEntry e = new JarArchiveEntry(s); - outStream.putArchiveEntry(e); - outStream.write(service.toString().getBytes(StandardCharsets.UTF_8)); - outStream.closeArchiveEntry(); - } - outStream.close(); - + copyMergedSpiServices(serviceEntries, outStream); + // end this.codeGenOptimizationReportEmitter.flipNativeOptimizationTimer(); - ZipFile birOptimizedFatJar = new ZipFile(birOptimizedJarPath); + } + ZipFile birOptimizedFatJar = ZipFile.builder().setFile(birOptimizedJarPath).get(); - Set startPoints = new LinkedHashSet<>(); - startPoints.add(getMainClassFileName(this.packageContext())); - ZipArchiveOutputStream optimizedJarStream = - new ZipArchiveOutputStream(new FileOutputStream(bytecodeOptimizedJarPath)); + Set startPoints = new LinkedHashSet<>(); + startPoints.add(getMainClassFileName(this.packageContext())); + NativeDependencyOptimizer nativeDependencyOptimizer = + getNativeDependencyOptimizer(bytecodeOptimizedJarPath, startPoints, birOptimizedFatJar); + this.codeGenOptimizationReportEmitter.flipNativeOptimizationTimer(); + this.codeGenOptimizationReportEmitter.emitNativeOptimizationDuration(); + this.codeGenOptimizationReportEmitter.emitOptimizedExecutableSize(Path.of(bytecodeOptimizedJarPath)); + if (this.packageContext.project().buildOptions().optimizeReport()) { + NativeDependencyOptimizationReportEmitter.emitCodegenOptimizationReport( + nativeDependencyOptimizer.getNativeDependencyOptimizationReport(), + getOptimizationReportParentPath()); + } + } + + private static NativeDependencyOptimizer getNativeDependencyOptimizer(String bytecodeOptimizedJarPath, + Set startPoints, + ZipFile birOptimizedFatJar) + throws IOException { + try (ZipArchiveOutputStream optimizedJarStream = new ZipArchiveOutputStream( + new FileOutputStream(bytecodeOptimizedJarPath))) { NativeDependencyOptimizer nativeDependencyOptimizer = new NativeDependencyOptimizer(startPoints, birOptimizedFatJar, optimizedJarStream); - nativeDependencyOptimizer.analyzeWhiteListedClasses(); nativeDependencyOptimizer.analyzeUsedClasses(); nativeDependencyOptimizer.copyUsedEntries(); - optimizedJarStream.close(); - - this.codeGenOptimizationReportEmitter.flipNativeOptimizationTimer(); - this.codeGenOptimizationReportEmitter.emitNativeOptimizationDuration(); - this.codeGenOptimizationReportEmitter.emitOptimizedExecutableSize(Path.of(bytecodeOptimizedJarPath)); - if (this.packageContext.project().buildOptions().optimizeReport()) { - NativeDependencyOptimizationReportEmitter.emitCodegenOptimizationReport( - nativeDependencyOptimizer.getNativeDependencyOptimizationReport(), - getOptimizationReportParentPath()); - } - } catch (IOException e) { - throw new IOException(e); + return nativeDependencyOptimizer; } } @@ -929,21 +911,14 @@ private void writeManifest(Manifest manifest, ZipArchiveOutputStream outStream) outStream.closeArchiveEntry(); } - private Manifest createManifest(boolean optimizeCodegen) { + private Manifest createManifest() { // Getting the jarFileName of the root module of this executable PlatformLibrary rootModuleJarFile = codeGeneratedLibrary(packageContext.packageId(), packageContext.defaultModuleContext().moduleName()); String mainClassName; - try { - JarInputStream jarStream; - if (optimizeCodegen) { - jarStream = getOptimizedJarInputStream(rootModuleJarFile.path().toString()); - } else { - jarStream = new JarInputStream(Files.newInputStream(rootModuleJarFile.path())); - } + try (JarInputStream jarStream = new JarInputStream(Files.newInputStream(rootModuleJarFile.path()))) { Manifest mf = jarStream.getManifest(); - jarStream.close(); mainClassName = (String) mf.getMainAttributes().get(Attributes.Name.MAIN_CLASS); } catch (IOException e) { throw new RuntimeException("Generated jar file cannot be found for the module: " + @@ -966,23 +941,6 @@ private Manifest createTestManifest() { return manifest; } - // TODO Optimize the condition to lookup the byteArrayOutputStream - private JarInputStream getOptimizedJarInputStream(String jarPath) { - AtomicReference jarInputStream = new AtomicReference<>(); - optimizedJarStreams.forEach((key, value) -> { - if (jarPath.contains(key)) { - ByteArrayInputStream tempInStream = new ByteArrayInputStream(value.toByteArray()); - try { - jarInputStream.set(new JarInputStream(tempInStream)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - - return jarInputStream.get(); - } - /** * Copies a given jar file into the executable fat jar. * @@ -995,30 +953,20 @@ private JarInputStream getOptimizedJarInputStream(String jarPath) { private void copyJar(ZipArchiveOutputStream outStream, JarLibrary jarLibrary, HashMap copiedEntries, HashMap services) throws IOException { - ZipFile zipFile = getZipFile(jarLibrary); - ZipArchiveEntryPredicate predicate = entry -> { - String entryName = entry.getName(); - if (entryName.equals("META-INF/MANIFEST.MF")) { - return false; - } - if (entryName.equals("module-info.class")) { - return false; - } - if (entryName.startsWith("META-INF/services")) { - StringBuilder s = services.get(entryName); - if (s == null) { - s = new StringBuilder(); - services.put(entryName, s); + if (Thread.currentThread().isInterrupted()) { + return; + } + try (ZipFile zipFile = new ZipFile(jarLibrary.path().toFile())) { + ZipArchiveEntryPredicate predicate = entry -> { + String entryName = entry.getName(); + if (entryName.equals("META-INF/MANIFEST.MF")) { + return false; } if (entryName.equals("module-info.class")) { return false; } if (entryName.startsWith("META-INF/services")) { - StringBuilder s = services.get(entryName); - if (s == null) { - s = new StringBuilder(); - services.put(entryName, s); - } + StringBuilder s = services.computeIfAbsent(entryName, k -> new StringBuilder()); char c = '\n'; int len; @@ -1034,7 +982,8 @@ private void copyJar(ZipArchiveOutputStream outStream, JarLibrary jarLibrary, s.append('\n'); } - // Its not required to copy SPI entries in here as we'll be adding merged SPI related entries + // Its not required to copy SPI entries in here as we'll be adding merged SPI + // related entries // separately. Therefore the predicate should be set as false. return false; } @@ -1052,45 +1001,11 @@ private void copyJar(ZipArchiveOutputStream outStream, JarLibrary jarLibrary, return true; }; - // Skip already copied files or excluded extensions. - if (isCopiedEntry(entryName, copiedEntries)) { - addConflictedJars(jarLibrary, copiedEntries, entryName); - return false; - } - if (isExcludedEntry(entryName)) { - return false; - } - // SPIs will be merged first and then put into jar separately. - copiedEntries.put(entryName, jarLibrary); - return true; - }; - - // Transfers selected entries from this zip file to the output stream, while preserving its compression and - // all the other original attributes. - zipFile.copyRawEntries(outStream, predicate); - zipFile.close(); - } - - private ZipFile getZipFile(JarLibrary jarLibrary) throws IOException { - ByteArrayOutputStream optimizedStream = getOptimizedStream(jarLibrary.path().toString()); - if (optimizedStream.size() == 0) { - return new ZipFile(jarLibrary.path().toFile()); + // Transfers selected entries from this zip file to the output stream, while + // preserving its compression and + // all the other original attributes. + zipFile.copyRawEntries(outStream, predicate); } - SeekableByteChannel seekableByteChannel = new SeekableInMemoryByteChannel(optimizedStream.toByteArray()); - return new ZipFile(seekableByteChannel); - } - - private ByteArrayOutputStream getOptimizedStream(String pathName) { - if (this.optimizedJarStreams == null) { - return new ByteArrayOutputStream(0); - } - - for (Map.Entry entry : this.optimizedJarStreams.entrySet()) { - if (pathName.contains(entry.getKey())) { - return entry.getValue(); - } - } - return new ByteArrayOutputStream(0); } private static boolean isCopiedEntry(String entryName, HashMap copiedEntries) { @@ -1117,7 +1032,7 @@ private PlatformLibrary codeGeneratedLibrary(PackageId packageId, } private Path emitExecutable(Path executableFilePath, List emitResultDiagnostics) { - Manifest manifest = createManifest(false); + Manifest manifest = createManifest(); Collection jarLibraries = jarResolver.getJarFilePathsRequiredForExecution(); // Add warning when provided platform dependencies are found addProvidedDependencyWarning(emitResultDiagnostics); @@ -1144,10 +1059,14 @@ private Path emitTestExecutable(Path executableFilePath, HashSet jar return executableFilePath; } + // TODO: merge this with emitExecutable private Path emitOptimizedExecutable(Path executableFilePath) { - Manifest manifest = createManifest(true); + Manifest manifest = createManifest(); Collection jarLibraries = jarResolver.getJarFilePathsRequiredForExecution(true); + List diagnostics = new ArrayList<>(); + // Add warning when provided platform dependencies are found + addProvidedDependencyWarning(diagnostics); try { assembleOptimizedExecutableJar(executableFilePath, manifest, jarLibraries); } catch (IOException e) { @@ -1315,8 +1234,7 @@ public enum OutputType { BALA("bala"), GRAAL_EXEC("graal_exec"), TEST("test"), - OPTIMIZE_CODEGEN("optimize_codegen") - ; + OPTIMIZE_CODEGEN("optimize_codegen"); private final String value; @@ -1421,7 +1339,7 @@ private PlatformLibrary codeGeneratedResourcesLibrary(PackageId packageId, Platf Package pkg = packageCache.getPackageOrThrow(packageId); CompilationCache compilationCache = pkg.project().projectEnvironmentContext().getService( CompilationCache.class); - return compilationCache.getPlatformSpecificLibrary(this, RESOURCE_DIR_NAME) + return compilationCache.getPlatformSpecificLibrary(this, RESOURCE_DIR_NAME, false) .map(path -> new JarLibrary(path, scope)) .orElse(null); } @@ -1513,7 +1431,7 @@ private void cacheResources(CompilationCache compilationCache, boolean skipTests CompiledJarFile resourceJar = new CompiledJarFile(""); resourceJar.jarEntries.putResourceEntries(resources); try (ByteArrayOutputStream byteStream = resourceJar.toByteArrayStream()) { - compilationCache.cachePlatformSpecificLibrary(this, resourceJarName, byteStream); + compilationCache.cachePlatformSpecificLibrary(this, resourceJarName, byteStream, false); } } catch (IOException e) { throw new ProjectException("Failed to cache resources jar, package: " + diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java index f8e25e5abd22..73d306e9294d 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java @@ -36,7 +36,6 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Path; -import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -128,10 +127,15 @@ public Collection getJarFilePathsRequiredForExecution(boolean optimi }); // 3) Add the runtime library path + String packageName = getPackageName(rootPackageContext); jarFiles.add(new JarLibrary(jBalBackend.runtimeLibrary().path(), PlatformLibraryScope.DEFAULT, - getPackageName(rootPackageContext))); - + packageName)); + // Add resources + Optional.ofNullable(jBalBackend.codeGeneratedResourcesLibrary(rootPackageContext.packageId())) + .ifPresent(library -> jarFiles.add( + new JarLibrary(library.path(), PlatformLibraryScope.DEFAULT, + packageName))); // TODO Filter out duplicate jar entries return jarFiles; } @@ -158,6 +162,7 @@ private void addCodeGeneratedLibraryPaths(PackageContext packageContext, Platfor ModuleContext moduleContext = packageContext.moduleContext(moduleId); PackageID pkgID = moduleContext.descriptor().moduleCompilationId(); + // TODO: extract this condition out if (packageContext.project().buildOptions().optimizeCodegen() && !this.rootPackageContext.project().buildOptions().skipTests() && this.jBalBackend.getOptimizedPackageIDs().contains(pkgID)) { @@ -175,7 +180,7 @@ private void addOptimizedLibraryPaths(PackageContext packageContext, PlatformLib PackageID pkgID) { PlatformLibrary generatedOptimizedLibrary = jBalBackend.codeGeneratedOptimizedLibrary( packageContext.packageId(), moduleContext.moduleName()); - Path optimizedJarLibraryPath = Paths.get(generatedOptimizedLibrary.path().toAbsolutePath().toString()); + Path optimizedJarLibraryPath = generatedOptimizedLibrary.path().toAbsolutePath(); if (JvmCodeGenUtil.duplicatePkgsMap.containsKey(pkgID.orgName + pkgID.getNameComps().toString())) { // Package is an optimized duplicated pkg. @@ -208,7 +213,6 @@ private void addPlatformLibraryPaths(PackageContext packageContext, if (addProvidedJars) { providedPlatformLibs.addAll(otherJarDependencies); } - for (PlatformLibrary otherJarDependency : otherJarDependencies) { JarLibrary newEntry = (JarLibrary) otherJarDependency; @@ -328,6 +332,7 @@ public Collection getJarFilePathsRequiredForTestExecution(ModuleName addCodeGeneratedLibraryPaths(pkgContext, PlatformLibraryScope.DEFAULT, allJarFileForTestExec); // All platform-specific libraries(specified in Ballerina.toml) having the default scope addPlatformLibraryPaths(pkgContext, PlatformLibraryScope.DEFAULT, allJarFileForTestExec, false); + addPlatformLibraryPaths(pkgContext, PlatformLibraryScope.PROVIDED, allJarFileForTestExec, false); }); // 6 Add other dependencies required to run Ballerina test cases diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java index 241870656deb..b5c8bb0c6d9b 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java @@ -46,9 +46,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -267,10 +268,8 @@ ModuleCompilationState currentCompilationState() { // TODO This logic needs to be updated. We need a proper way to decide on the initial state if (compilationCache.getBir(moduleDescriptor.name()).length == 0) { moduleCompState = ModuleCompilationState.LOADED_FROM_SOURCES; - } else if (this.project().kind() == ProjectKind.BUILD_PROJECT - && !this.project.buildOptions().enableCache()) { - moduleCompState = ModuleCompilationState.LOADED_FROM_SOURCES; - } else if (this.shouldOptimizeCodegen()) { + } else if ((this.project().kind() == ProjectKind.BUILD_PROJECT + && !this.project.buildOptions().enableCache()) || this.shouldOptimizeCodegen()) { moduleCompState = ModuleCompilationState.LOADED_FROM_SOURCES; } else { moduleCompState = ModuleCompilationState.LOADED_FROM_CACHE; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedBIRNodeAnalyzer.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedBIRNodeAnalyzer.java index 51989e5ee6d1..ac423bb6cec3 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedBIRNodeAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedBIRNodeAnalyzer.java @@ -58,7 +58,7 @@ /** * Analyses the BIR and marks unused functions and type definitions. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class UsedBIRNodeAnalyzer extends BIRVisitor { @@ -221,8 +221,7 @@ public void visit(BIRNode.BIRBasicBlock birBasicBlock) { @Override public void visit(BIRTerminator.Call call) { // If function pointers are passed as parameters, they will be bound to the parent function - List argVars = getUsedLocalFPHolders(call.args); - argVars.forEach(var -> { + getUsedLocalFPHolders(call.args).forEach(var -> { FunctionPointerData fpData = currentInvocationData.getFPData(var); if (fpData != null && fpData.lambdaFunction != null) { visitNode(fpData.lambdaFunction); @@ -491,9 +490,6 @@ private void addDependentFunctionAndVisit(BIRNode.BIRDocumentableNode parentNode public static class InvocationData { // Following Sets are used to whitelist the bal types called through ValueCreator in native dependencies - private static final Set WHITELSITED_FILE_NAMES = Set.of("types.bal", "error.bal", "stream_types.bal"); - private static final Set PKGS_WITH_WHITELSITED_FILES = - Set.of("ballerinax/mysql", "ballerina/sql", "ballerinax/persist.sql"); private static final String BALLERINA_TEST_PKG_NAME = "ballerina/test:0.0.0"; private static final String MOCK_FUNCTION_PREFIX = "$MOCK_"; final Set usedFunctions = new LinkedHashSet<>(); diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedTypeDefAnalyzer.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedTypeDefAnalyzer.java index 8355ca8a86c2..0fb5137c051d 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedTypeDefAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/UsedTypeDefAnalyzer.java @@ -33,7 +33,7 @@ /** * Analyses a given type definition and marks its dependencies. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class UsedTypeDefAnalyzer extends SimpleBTypeAnalyzer { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java index b4ba629a2323..2992e0769836 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java @@ -19,7 +19,6 @@ import io.ballerina.runtime.internal.util.RuntimeUtils; import org.ballerinalang.compiler.CompilerPhase; -import org.wso2.ballerinalang.compiler.PackageCache; import org.wso2.ballerinalang.compiler.bir.BIRGen; import org.wso2.ballerinalang.compiler.bir.emit.BIREmitter; import org.wso2.ballerinalang.compiler.desugar.ConstantPropagation; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java index 850f757254f0..9e325ffeae7d 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java @@ -63,7 +63,7 @@ public enum ProjectDiagnosticErrorCode implements DiagnosticCode { PROVIDED_PLATFORM_JAR_IN_EXECUTABLE("BCE5502", "provided.platform.jars"), // Error codes used in resources resolution - CONFLICTING_RESOURCE_FILE("BCE5601", "conflicting.resources.type") + CONFLICTING_RESOURCE_FILE("BCE5601", "conflicting.resources.type"), // Error codes for invalid flag combinations. INVALID_VERBOSE_FLAG_USAGE("BCE5701", "invalid.verbose.flag.usage"), diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/repos/FileSystemCache.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/repos/FileSystemCache.java index 702e259f4bf0..dbc3503518b3 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/repos/FileSystemCache.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/repos/FileSystemCache.java @@ -101,12 +101,11 @@ public Optional getPlatformSpecificLibrary(CompilerBackend compilerBackend Path targetPlatformCacheDirPath = isOptimizedLibrary ? getOptimizedTargetPlatformCacheDirPath(compilerBackend) : getTargetPlatformCacheDirPath(compilerBackend); Path jarFilePath = targetPlatformCacheDirPath.resolve(libraryFileName); - return Optional.of(jarFilePath); + return Files.exists(jarFilePath) ? Optional.of(jarFilePath) : Optional.empty(); } @Override - public void cachePlatformSpecificLibrary(CompilerBackend compilerBackend, - String libraryName, + public void cachePlatformSpecificLibrary(CompilerBackend compilerBackend, String libraryName, ByteArrayOutputStream libraryContent, boolean isOptimizedLibrary) { String libraryFileName = libraryName + compilerBackend.libraryFileExtension(); Path targetPlatformCacheDirPath = isOptimizedLibrary ? getOptimizedTargetPlatformCacheDirPath(compilerBackend) : diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/CodegenOptimizationUtils.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/CodegenOptimizationUtils.java index 26ea76557b8e..9209e3c42938 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/CodegenOptimizationUtils.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/CodegenOptimizationUtils.java @@ -45,8 +45,8 @@ public final class CodegenOptimizationUtils { private static final String ENV_OPTION_BAL_JAVA_DEBUG = "BAL_DISABLE_HARDCODED_OPTIMIZATIONS"; private static final boolean DISABLE_HARDCODED_OPTIMIZATIONS = System.getenv().containsKey(ENV_OPTION_BAL_JAVA_DEBUG); - private static final Set WHITELSITED_FILE_NAMES = Set.of("types.bal", "error.bal", "stream_types.bal"); - private static final Set PKGS_WITH_WHITELSITED_FILES = + private static final Set WHITELISTED_FILE_NAMES = Set.of("types.bal", "error.bal", "stream_types.bal"); + private static final Set PKGS_WITH_WHITELISTED_FILES = Set.of("ballerinax/mysql", "ballerina/sql", "ballerinax/persist.sql"); // These directories are whitelisted due to usages of "sun.misc.Unsafe" class @@ -105,14 +105,14 @@ public static boolean isPackageWithWhiteListedFiles(String packageName) { if (DISABLE_HARDCODED_OPTIMIZATIONS) { return false; } - return PKGS_WITH_WHITELSITED_FILES.contains(packageName); + return PKGS_WITH_WHITELISTED_FILES.contains(packageName); } public static boolean isWhiteListedFile(String fileName) { if (DISABLE_HARDCODED_OPTIMIZATIONS) { return false; } - return WHITELSITED_FILE_NAMES.contains(fileName); + return WHITELISTED_FILE_NAMES.contains(fileName); } public static boolean isWhiteListedDirectory(String path) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java index 916c33247aa3..c29c33712cda 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java @@ -163,6 +163,7 @@ public final class JvmCodeGenUtil { public static final NameHashComparator NAME_HASH_COMPARATOR = new NameHashComparator(); public static Boolean isOptimizedCodeGen = false; public static Boolean isRootPkgCodeGen = false; + // TODO: fix the key public static Map duplicatePkgsMap = new HashMap<>(); static void visitInvokeDynamic(MethodVisitor mv, String currentClass, String lambdaName, int size) { @@ -829,7 +830,8 @@ public static String getSig(Class c) { } } } - public static void markIsRootPackage() { + + public static void markAsRootPackage() { isRootPkgCodeGen = true; } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/AnnotationNodeVisitor.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/AnnotationNodeVisitor.java index 8cd852442baf..485425e00589 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/AnnotationNodeVisitor.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/AnnotationNodeVisitor.java @@ -26,7 +26,7 @@ /** * A visitor class used to visit annotations and collect used class types. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class AnnotationNodeVisitor extends AnnotationVisitor { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/ClassNodeVisitor.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/ClassNodeVisitor.java index a05b0172838d..74b8957aa389 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/ClassNodeVisitor.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/ClassNodeVisitor.java @@ -35,10 +35,10 @@ import static org.objectweb.asm.Opcodes.ASM9; /** - * A class node visitor to visit the class attributes and annotations of a graph node. - * Also adds the names of all the methods in the class to the method list. + * A class node visitor to visit the class attributes and annotations of a graph node. Also adds the names of all the + * methods in the class to the method list. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class ClassNodeVisitor extends ClassNode { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/DependencyCollector.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/DependencyCollector.java index d3e275c92f0f..abeaa74271bb 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/DependencyCollector.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/DependencyCollector.java @@ -31,7 +31,7 @@ /** * Collects the dependent classes used by a particular class. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class DependencyCollector { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/FieldNodeVisitor.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/FieldNodeVisitor.java index 4ae184c6dd8b..eeec9a75f6c5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/FieldNodeVisitor.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/FieldNodeVisitor.java @@ -26,7 +26,7 @@ /** * A visitor class used to visit fields and collect used class types. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class FieldNodeVisitor extends FieldVisitor { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/MethodNodeVisitor.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/MethodNodeVisitor.java index d4a01f037121..6a7f80e85511 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/MethodNodeVisitor.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/MethodNodeVisitor.java @@ -30,7 +30,7 @@ /** * A visitor class used to visit methods collect used class types. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class MethodNodeVisitor extends MethodVisitor { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizationReport.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizationReport.java index d5f770bcc442..1b8dd53f5193 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizationReport.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizationReport.java @@ -23,14 +23,13 @@ /** * Java record to store class level native optimization report data to JSON. * - * @param startPointClasses start points identified by the NativeDependencyOptimizer + * @param startPointClasses start points identified by the NativeDependencyOptimizer * @param usedExternalClasses used classes which are not present in the executable JAR (JRE classes) - * @param usedClasses used classes present in the executable JAR - * @param unusedClasses unused classes present in the executable JAR - * - * @since 2201.10.0 + * @param usedClasses used classes present in the executable JAR + * @param unusedClasses unused classes present in the executable JAR + * @since 2201.11.0 */ -record NativeDependencyOptimizationReport(Set startPointClasses, Set usedExternalClasses, - Set usedClasses, Set unusedClasses) { +public record NativeDependencyOptimizationReport(Set startPointClasses, Set usedExternalClasses, + Set usedClasses, Set unusedClasses) { } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizer.java index c1c9ada43e3a..d471f2346ede 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/bytecodeoptimizer/NativeDependencyOptimizer.java @@ -48,7 +48,7 @@ /** * Optimizes a given JAR on class file level. * - * @since 2201.10.0 + * @since 2201.11.0 */ public final class NativeDependencyOptimizer { @@ -74,8 +74,8 @@ public NativeDependencyOptimizer(Set startPointClasses, ZipFile original this.usedClassesStack = new Stack<>(); } - private static Iterable getServiceProviderImplementations(ZipFile originalJarFile, - ZipArchiveEntry entry) throws IOException { + private static Iterable getServiceProviderImplementations(ZipFile originalJarFile, ZipArchiveEntry entry) + throws IOException { String allImplString = IOUtils.toString(originalJarFile.getInputStream(entry), StandardCharsets.UTF_8); Pattern pattern = Pattern.compile("\n"); return pattern.splitAsStream(allImplString) diff --git a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BCompileUtil.java b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BCompileUtil.java index 227192ea746c..115d726bd4bd 100644 --- a/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BCompileUtil.java +++ b/tests/ballerina-test-utils/src/main/java/org/ballerinalang/test/BCompileUtil.java @@ -124,7 +124,7 @@ public static CompileResult compileOptimized(String sourceFilePath) { BuildOptions.BuildOptionsBuilder buildOptionsBuilder = BuildOptions.builder(); BuildOptions buildOptions = buildOptionsBuilder.setOptimizeCodegen(Boolean.TRUE).setOptimizeReport(Boolean.TRUE).build(); - Project project = ProjectLoader.loadProject(testSourcesDirectory.resolve(sourceFilePath), buildOptions); + Project project = ProjectLoader.loadProject(TEST_SOURCES_DIRECTORY.resolve(sourceFilePath), buildOptions); Package currentPackage = project.currentPackage(); JBallerinaBackend jBallerinaBackend = jBallerinaBackend(currentPackage);