Implement a --compile command for the engine runner (#1998)

This commit is contained in:
Ara Adkins 2021-09-24 12:24:44 +01:00 committed by GitHub
parent 8d676259b9
commit d6465e9e97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 441 additions and 148 deletions

View File

@ -241,6 +241,39 @@ jobs:
run: |
sleep 1
sbt buildEngineDistribution
- name: Compile the Standard Libraries (Unix)
working-directory: repo
shell: bash
if: runner.os != 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
- name: Compile the Standard Libraries (Windows)
working-directory: repo
shell: bash
if: runner.os == 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
- name: Prepare Project Manager Distribution
working-directory: repo
shell: bash

View File

@ -195,6 +195,39 @@ jobs:
run: |
sleep 1
sbt buildEngineDistribution
- name: Compile the Standard Libraries (Unix)
working-directory: repo
shell: bash
if: runner.os != 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
- name: Compile the Standard Libraries (Windows)
working-directory: repo
shell: bash
if: runner.os == 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
- name: Prepare Project Manager Distribution
working-directory: repo
shell: bash

View File

@ -22,7 +22,7 @@ jobs:
test_and_publish:
name: Build and Test
runs-on: ${{ matrix.os }}
timeout-minutes: 100
timeout-minutes: 120
strategy:
matrix:
os: [macOS-latest, ubuntu-18.04, windows-latest]
@ -279,12 +279,27 @@ jobs:
shell: bash
if: runner.os != 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Tests
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Table_Tests
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Database_Tests
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Geo_Tests
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Visualization_Tests
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-read-ir-caches --run test/Image_Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Table_Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Database_Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Geo_Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Visualization_Tests
$ENGINE_DIST_DIR/bin/enso --no-ir-caches --run test/Image_Tests
- name: Compile the Standard Libraries (Unix)
shell: bash
if: runner.os != 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
- name: Test Engine Distribution With Caches (Unix)
shell: bash
@ -301,12 +316,27 @@ jobs:
shell: bash
if: runner.os == 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Tests
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Table_Tests
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Database_Tests
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Geo_Tests
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Visualization_Tests
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-read-ir-caches --run test/Image_Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Table_Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Database_Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Geo_Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Visualization_Tests
$ENGINE_DIST_DIR/bin/enso.bat --no-ir-caches --run test/Image_Tests
- name: Compile the Standard Libraries (Windows)
shell: bash
if: runner.os == 'Windows'
run: |
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Base/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Database/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Examples/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Geo/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Google_Api/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Image/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Searcher/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Table/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Test/$DIST_VERSION
$ENGINE_DIST_DIR/bin/enso.bat --ir-caches --no-compile-dependencies --no-global-cache --compile $ENGINE_DIST_DIR/lib/Standard/Visualization/$DIST_VERSION
- name: Test Engine Distribution With Caches (Windows)
shell: bash

View File

@ -1,5 +1,12 @@
# Enso Next
## Interpreter/Runtime
- Added support for compiling Enso packages without execution
([#1998](https://github.com/enso-org/enso/pull/1998)). This allows the
distribution of precompiled libraries which greatly improves language start-up
time.
## Enso 0.2.30 (2021-09-23)
## Interpreter/Runtime

View File

@ -8,6 +8,7 @@ public class MethodNames {
public static final String LEAK_CONTEXT = "leak_context";
public static final String REGISTER_MODULE = "register_module";
public static final String UNREGISTER_MODULE = "unregister_module";
public static final String COMPILE = "compile";
}
public static class Module {

View File

@ -78,10 +78,11 @@ public class RuntimeOptions {
WAIT_FOR_PENDING_SERIALIZATION_JOBS_KEY, WAIT_FOR_PENDING_SERIALIZATION_JOBS)
.build();
public static final String NO_READ_IR_CACHES = optionName("onlyGenerateIrCaches");
public static final OptionKey<Boolean> NO_READ_IR_CACHES_KEY = new OptionKey<>(false);
private static final OptionDescriptor NO_READ_IR_CACHES_DESCRIPTOR =
OptionDescriptor.newBuilder(NO_READ_IR_CACHES_KEY, NO_READ_IR_CACHES).build();
public static final String USE_GLOBAL_IR_CACHE_LOCATION = optionName("useGlobalIrCacheLocation");
public static final OptionKey<Boolean> USE_GLOBAL_IR_CACHE_LOCATION_KEY = new OptionKey<>(true);
public static final OptionDescriptor USE_GLOBAL_IR_CACHE_LOCATION_DESCRIPTOR =
OptionDescriptor.newBuilder(USE_GLOBAL_IR_CACHE_LOCATION_KEY, USE_GLOBAL_IR_CACHE_LOCATION)
.build();
public static final OptionDescriptors OPTION_DESCRIPTORS =
OptionDescriptors.create(
@ -98,7 +99,7 @@ public class RuntimeOptions {
INTERPRETER_SEQUENTIAL_COMMAND_EXECUTION_DESCRIPTOR,
DISABLE_IR_CACHES_DESCRIPTOR,
WAIT_FOR_PENDING_SERIALIZATION_JOBS_DESCRIPTOR,
NO_READ_IR_CACHES_DESCRIPTOR));
USE_GLOBAL_IR_CACHE_LOCATION_DESCRIPTOR));
/**
* Canonicalizes the option name by prefixing it with the language name.

View File

@ -33,4 +33,8 @@ class TopScope(private val value: Value) {
def unregisterModule(qualifiedName: String): Unit = {
value.invokeMember(UNREGISTER_MODULE, qualifiedName): Unit
}
def compile(shouldCompileDependencies: Boolean): Unit = {
value.invokeMember(COMPILE, shouldCompileDependencies)
}
}

View File

@ -1,8 +1,5 @@
package org.enso.runner
import java.io.InputStream
import java.io.OutputStream
import org.enso.loggingservice.{JavaLoggingLogHandler, LogLevel}
import org.enso.polyglot.debugger.{
DebugServerInfo,
@ -11,6 +8,8 @@ import org.enso.polyglot.debugger.{
import org.enso.polyglot.{PolyglotContext, RuntimeOptions}
import org.graalvm.polyglot.Context
import java.io.{InputStream, OutputStream}
/** Utility class for creating Graal polyglot contexts.
*/
class ContextFactory {
@ -24,9 +23,9 @@ class ContextFactory {
* @param repl the Repl manager to use for this context
* @param logLevel the log level for this context
* @param enableIrCaches whether or not IR caching should be enabled
* @param enableIrCacheReading whether or not IR cache reading should be
* enabled
* @param strictErrors whether or not to use strict errors
* @param useGlobalIrCacheLocation whether or not to use the global IR cache
* location
* @return configured Context instance
*/
def create(
@ -37,8 +36,8 @@ class ContextFactory {
logLevel: LogLevel,
logMasking: Boolean,
enableIrCaches: Boolean,
enableIrCacheReading: Boolean,
strictErrors: Boolean = false
strictErrors: Boolean = false,
useGlobalIrCacheLocation: Boolean = true
): PolyglotContext = {
val context = Context
.newBuilder()
@ -47,11 +46,11 @@ class ContextFactory {
.option(RuntimeOptions.PROJECT_ROOT, projectRoot)
.option(RuntimeOptions.STRICT_ERRORS, strictErrors.toString)
.option(RuntimeOptions.WAIT_FOR_PENDING_SERIALIZATION_JOBS, "true")
.option(RuntimeOptions.DISABLE_IR_CACHES, (!enableIrCaches).toString)
.option(
RuntimeOptions.NO_READ_IR_CACHES,
(!enableIrCacheReading).toString
RuntimeOptions.USE_GLOBAL_IR_CACHE_LOCATION,
useGlobalIrCacheLocation.toString
)
.option(RuntimeOptions.DISABLE_IR_CACHES, (!enableIrCaches).toString)
.option(DebugServerInfo.ENABLE_OPTION, "true")
.option(RuntimeOptions.LOG_MASKING, logMasking.toString)
.option("js.foreign-object-prototype", "true")

View File

@ -25,34 +25,37 @@ import scala.util.Try
/** The main CLI entry point class. */
object Main {
private val RUN_OPTION = "run"
private val HELP_OPTION = "help"
private val NEW_OPTION = "new"
private val PROJECT_NAME_OPTION = "new-project-name"
private val PROJECT_TEMPLATE_OPTION = "new-project-template"
private val PROJECT_AUTHOR_NAME_OPTION = "new-project-author-name"
private val PROJECT_AUTHOR_EMAIL_OPTION = "new-project-author-email"
private val REPL_OPTION = "repl"
private val DOCS_OPTION = "docs"
private val LANGUAGE_SERVER_OPTION = "server"
private val DAEMONIZE_OPTION = "daemon"
private val INTERFACE_OPTION = "interface"
private val RPC_PORT_OPTION = "rpc-port"
private val DATA_PORT_OPTION = "data-port"
private val ROOT_ID_OPTION = "root-id"
private val ROOT_PATH_OPTION = "path"
private val IN_PROJECT_OPTION = "in-project"
private val VERSION_OPTION = "version"
private val JSON_OPTION = "json"
private val IR_CACHES_OPTION = "ir-caches"
private val NO_IR_CACHES_OPTION = "no-ir-caches"
private val NO_READ_IR_CACHES_OPTION = "no-read-ir-caches"
private val LOG_LEVEL = "log-level"
private val LOGGER_CONNECT = "logger-connect"
private val NO_LOG_MASKING = "no-log-masking"
private val UPLOAD_OPTION = "upload"
private val HIDE_PROGRESS = "hide-progress"
private val AUTH_TOKEN = "auth-token"
private val RUN_OPTION = "run"
private val HELP_OPTION = "help"
private val NEW_OPTION = "new"
private val PROJECT_NAME_OPTION = "new-project-name"
private val PROJECT_TEMPLATE_OPTION = "new-project-template"
private val PROJECT_AUTHOR_NAME_OPTION = "new-project-author-name"
private val PROJECT_AUTHOR_EMAIL_OPTION = "new-project-author-email"
private val REPL_OPTION = "repl"
private val DOCS_OPTION = "docs"
private val LANGUAGE_SERVER_OPTION = "server"
private val DAEMONIZE_OPTION = "daemon"
private val INTERFACE_OPTION = "interface"
private val RPC_PORT_OPTION = "rpc-port"
private val DATA_PORT_OPTION = "data-port"
private val ROOT_ID_OPTION = "root-id"
private val ROOT_PATH_OPTION = "path"
private val IN_PROJECT_OPTION = "in-project"
private val VERSION_OPTION = "version"
private val JSON_OPTION = "json"
private val IR_CACHES_OPTION = "ir-caches"
private val NO_IR_CACHES_OPTION = "no-ir-caches"
private val NO_READ_IR_CACHES_OPTION = "no-read-ir-caches"
private val COMPILE_OPTION = "compile"
private val NO_COMPILE_DEPENDENCIES_OPTION = "no-compile-dependencies"
private val NO_GLOBAL_CACHE_OPTION = "no-global-cache"
private val LOG_LEVEL = "log-level"
private val LOGGER_CONNECT = "logger-connect"
private val NO_LOG_MASKING = "no-log-masking"
private val UPLOAD_OPTION = "upload"
private val HIDE_PROGRESS = "hide-progress"
private val AUTH_TOKEN = "auth-token"
private lazy val logger = Logger[Main.type]
@ -243,6 +246,25 @@ object Main {
"Disables the reading of IR caches in the runtime if IR caching is enabled."
)
.build()
val compileOption = CliOption.builder
.hasArg(true)
.numberOfArgs(1)
.argName("package")
.longOpt(COMPILE_OPTION)
.desc("Compile the provided package without executing it.")
.build()
val noCompileDependenciesOption = CliOption.builder
.longOpt(NO_COMPILE_DEPENDENCIES_OPTION)
.desc(
"Tells the compiler to not compile dependencies when performing static compilation."
)
.build()
val noGlobalCacheOption = CliOption.builder
.longOpt(NO_GLOBAL_CACHE_OPTION)
.desc(
"Tells the compiler not to write compiled data to the global cache locations."
)
.build()
val irCachesOption = CliOption.builder
.longOpt(IR_CACHES_OPTION)
@ -293,6 +315,9 @@ object Main {
.addOption(hideProgressOption)
.addOption(authTokenOption)
.addOption(noReadIrCachesOption)
.addOption(compileOption)
.addOption(noCompileDependenciesOption)
.addOption(noGlobalCacheOption)
.addOptionGroup(cacheOptionsGroup)
options
@ -369,6 +394,46 @@ object Main {
exitSuccess()
}
/** Handles the `--compile` CLI option.
*
* @param packagePath the path to the package being compiled
* @param shouldCompileDependencies whether the dependencies of that package
* should also be compiled
* @param shouldUseGlobalCache whether or not the compilation result should
* be written to the global cache
* @param logLevel the logging level
* @param logMasking whether or not log masking is enabled
*/
private def compile(
packagePath: String,
shouldCompileDependencies: Boolean,
shouldUseGlobalCache: Boolean,
logLevel: LogLevel,
logMasking: Boolean
): Unit = {
val file = new File(packagePath)
if (!file.exists || !file.isDirectory) {
println(s"No package exists at $file.")
exitFail()
}
val context = new ContextFactory().create(
packagePath,
System.in,
System.out,
Repl(TerminalIO()),
logLevel,
logMasking,
enableIrCaches = true,
useGlobalIrCacheLocation = shouldUseGlobalCache
)
val topScope = context.getTopScope
topScope.compile(shouldCompileDependencies)
context.context.close()
exitSuccess()
}
/** Handles the `--run` CLI option.
*
* If `path` is a directory, so a project is run, a conflicting (pointing to
@ -380,16 +445,13 @@ object Main {
* @param logLevel log level to set for the engine runtime
* @param logMasking is the log masking enabled
* @param enableIrCaches are IR caches enabled
* @param readIrCaches whether IR caches should be read from if caching is
* enabled
*/
private def run(
path: String,
projectPath: Option[String],
logLevel: LogLevel,
logMasking: Boolean,
enableIrCaches: Boolean,
readIrCaches: Boolean
enableIrCaches: Boolean
): Unit = {
val file = new File(path)
if (!file.exists) {
@ -419,7 +481,6 @@ object Main {
logLevel,
logMasking,
enableIrCaches,
readIrCaches,
strictErrors = true
)
if (projectMode) {
@ -449,14 +510,12 @@ object Main {
* @param logLevel log level to set for the engine runtime
* @param logMasking is the log masking enabled
* @param enableIrCaches are the IR caches enabled
* @param readIrCaches should the IR caches be read from if enabled
*/
private def genDocs(
projectPath: Option[String],
logLevel: LogLevel,
logMasking: Boolean,
enableIrCaches: Boolean,
readIrCaches: Boolean
enableIrCaches: Boolean
): Unit = {
if (projectPath.isEmpty) {
println("Path hasn't been provided.")
@ -466,8 +525,7 @@ object Main {
projectPath.get,
logLevel,
logMasking,
enableIrCaches,
readIrCaches
enableIrCaches
)
exitSuccess()
}
@ -479,8 +537,7 @@ object Main {
path: String,
logLevel: LogLevel,
logMasking: Boolean,
enableIrCaches: Boolean,
readIrCaches: Boolean
enableIrCaches: Boolean
): Unit = {
val executionContext = new ContextFactory().create(
path,
@ -489,8 +546,7 @@ object Main {
Repl(TerminalIO()),
logLevel,
logMasking,
enableIrCaches,
readIrCaches
enableIrCaches
)
val file = new File(path)
@ -609,14 +665,12 @@ object Main {
* @param logLevel log level to set for the engine runtime
* @param logMasking is the log masking enabled
* @param enableIrCaches are IR caches enabled
* @param readIrCaches should IR caches be read from if enabled
*/
private def runRepl(
projectPath: Option[String],
logLevel: LogLevel,
logMasking: Boolean,
enableIrCaches: Boolean,
readIrCaches: Boolean
enableIrCaches: Boolean
): Unit = {
val mainMethodName = "internal_repl_entry_point___"
val dummySourceToTriggerRepl =
@ -634,8 +688,7 @@ object Main {
Repl(TerminalIO()),
logLevel,
logMasking,
enableIrCaches,
readIrCaches
enableIrCaches
)
val mainModule =
context.evalModule(dummySourceToTriggerRepl, replModuleName)
@ -799,14 +852,28 @@ object Main {
}
}
if (line.hasOption(COMPILE_OPTION)) {
val packagePaths = line.getOptionValue(COMPILE_OPTION)
val shouldCompileDependencies =
!line.hasOption(NO_COMPILE_DEPENDENCIES_OPTION);
val shouldUseGlobalCache = !line.hasOption(NO_GLOBAL_CACHE_OPTION)
compile(
packagePaths,
shouldCompileDependencies,
shouldUseGlobalCache,
logLevel,
logMasking
)
}
if (line.hasOption(RUN_OPTION)) {
run(
line.getOptionValue(RUN_OPTION),
Option(line.getOptionValue(IN_PROJECT_OPTION)),
logLevel,
logMasking,
shouldEnableIrCaches(line),
shouldReadIrCaches(line)
shouldEnableIrCaches(line)
)
}
if (line.hasOption(REPL_OPTION)) {
@ -814,8 +881,7 @@ object Main {
Option(line.getOptionValue(IN_PROJECT_OPTION)),
logLevel,
logMasking,
shouldEnableIrCaches(line),
shouldReadIrCaches(line)
shouldEnableIrCaches(line)
)
}
if (line.hasOption(DOCS_OPTION)) {
@ -823,8 +889,7 @@ object Main {
Option(line.getOptionValue(IN_PROJECT_OPTION)),
logLevel,
logMasking,
shouldEnableIrCaches(line),
shouldReadIrCaches(line)
shouldEnableIrCaches(line)
)
}
if (line.hasOption(LANGUAGE_SERVER_OPTION)) {
@ -853,13 +918,4 @@ object Main {
!isDevBuild
}
}
/** Determines whether IR caches should be read from if caching is enabled.
*
* @param line the command line
* @return `true` if caches should be read from, `false` otherwise
*/
private def shouldReadIrCaches(line: CommandLine): Boolean = {
!line.hasOption(NO_READ_IR_CACHES_OPTION)
}
}

View File

@ -53,7 +53,6 @@ public class Context {
private final ResourceManager resourceManager;
private final boolean isInlineCachingDisabled;
private final boolean isIrCachingDisabled;
private final boolean isIrCacheReadingDisabled;
private final boolean shouldWaitForPendingSerializationJobs;
private final Builtins builtins;
private final String home;
@ -91,8 +90,6 @@ public class Context {
this.isInlineCachingDisabled =
environment.getOptions().get(RuntimeOptions.DISABLE_INLINE_CACHES_KEY);
this.isIrCachingDisabled = environment.getOptions().get(RuntimeOptions.DISABLE_IR_CACHES_KEY);
this.isIrCacheReadingDisabled =
environment.getOptions().get(RuntimeOptions.NO_READ_IR_CACHES_KEY);
this.shouldWaitForPendingSerializationJobs =
environment.getOptions().get(RuntimeOptions.WAIT_FOR_PENDING_SERIALIZATION_JOBS_KEY);
this.compilerConfig = new CompilerConfig(false, true);
@ -409,11 +406,6 @@ public class Context {
return isIrCachingDisabled;
}
/** @return whether IR cache reading is disabled for this context */
public boolean isIrCacheReadingDisabled() {
return isIrCacheReadingDisabled;
}
/** @return the compiler configuration for this language */
public CompilerConfig getCompilerConfig() {
return compilerConfig;

View File

@ -105,7 +105,8 @@ public class TopLevelScope implements TruffleObject {
MethodNames.TopScope.GET_MODULE,
MethodNames.TopScope.CREATE_MODULE,
MethodNames.TopScope.REGISTER_MODULE,
MethodNames.TopScope.UNREGISTER_MODULE);
MethodNames.TopScope.UNREGISTER_MODULE,
MethodNames.TopScope.COMPILE);
}
/** Handles member invocation through the polyglot API. */
@ -154,6 +155,14 @@ public class TopLevelScope implements TruffleObject {
return context.getEnvironment().asGuestValue(context);
}
private static Object compile(Object[] arguments, Context context)
throws UnsupportedTypeException, ArityException {
boolean shouldCompileDependencies = Types.extractArguments(arguments, Boolean.class);
context.getCompiler().compile(shouldCompileDependencies);
return true;
}
@Specialization
static Object doInvoke(
TopLevelScope scope,
@ -172,6 +181,8 @@ public class TopLevelScope implements TruffleObject {
return unregisterModule(scope, arguments, contextRef.get());
case MethodNames.TopScope.LEAK_CONTEXT:
return leakContext(contextRef.get());
case MethodNames.TopScope.COMPILE:
return compile(arguments, contextRef.get());
default:
throw UnknownIdentifierException.create(member);
}
@ -189,7 +200,8 @@ public class TopLevelScope implements TruffleObject {
return member.equals(MethodNames.TopScope.GET_MODULE)
|| member.equals(MethodNames.TopScope.CREATE_MODULE)
|| member.equals(MethodNames.TopScope.REGISTER_MODULE)
|| member.equals(MethodNames.TopScope.UNREGISTER_MODULE);
|| member.equals(MethodNames.TopScope.UNREGISTER_MODULE)
|| member.equals(MethodNames.TopScope.COMPILE);
}
/**

View File

@ -3,6 +3,7 @@ package org.enso.interpreter.runtime.type;
import com.oracle.truffle.api.dsl.TypeSystem;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import org.enso.interpreter.runtime.Context;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.Thunk;
import org.enso.interpreter.runtime.callable.atom.Atom;
@ -164,6 +165,7 @@ public class Types {
if (arguments.length != 1) {
throw ArityException.create(1, arguments.length);
}
if (!(cls.isInstance(arguments[0]))) {
throw UnsupportedTypeException.create(
arguments, "The argument must be a " + cls.getSimpleName() + ".");

View File

@ -19,7 +19,7 @@ import org.enso.interpreter.node.{ExpressionNode => RuntimeExpression}
import org.enso.interpreter.runtime.builtin.Builtins
import org.enso.interpreter.runtime.scope.{LocalScope, ModuleScope}
import org.enso.interpreter.runtime.{Context, Module}
import org.enso.polyglot.LanguageInfo
import org.enso.polyglot.{LanguageInfo, RuntimeOptions}
import org.enso.syntax.text.Parser.IDMap
import org.enso.syntax.text.{AST, Parser}
@ -45,8 +45,10 @@ class Compiler(
private val importResolver: ImportResolver = new ImportResolver(this)
private val stubsGenerator: RuntimeStubsGenerator =
new RuntimeStubsGenerator()
private val irCachingEnabled = !context.isIrCachingDisabled
private val irCacheReadingEnabled = !context.isIrCacheReadingDisabled
private val irCachingEnabled = !context.isIrCachingDisabled
private val useGlobalCacheLocations = context.getEnvironment.getOptions.get(
RuntimeOptions.USE_GLOBAL_IR_CACHE_LOCATION_KEY
)
private val serializationManager: SerializationManager =
new SerializationManager(this)
private val logger: TruffleLogger = context.getLogger(getClass)
@ -62,7 +64,7 @@ class Compiler(
builtins.initializeBuiltinsSource()
if (irCachingEnabled && irCacheReadingEnabled) {
if (irCachingEnabled) {
serializationManager.deserialize(builtins.getModule) match {
case Some(true) =>
// Ensure that builtins doesn't try and have codegen run on it.
@ -80,7 +82,10 @@ class Compiler(
}
if (irCachingEnabled && !builtins.getModule.wasLoadedFromCache()) {
serializationManager.serialize(builtins.getModule)
serializationManager.serialize(
builtins.getModule,
useGlobalCacheLocations = true // Builtins can't have a local cache.
)
}
}
}
@ -103,13 +108,83 @@ class Compiler(
* executable functionality in the module corresponding to `source`.
*/
def run(module: Module): Unit = {
initializeBuiltinsIr()
parseModule(module)
runInternal(
List(module),
generateCode = true,
shouldCompileDependencies = true
)
}
var requiredModules = runImportsAndExportsResolution(module)
/** Compiles the requested packages, writing the compiled IR to the library
* cache directories.
*
* @param shouldCompileDependencies whether compilation should also compile
* the dependencies of the requested package
*/
def compile(shouldCompileDependencies: Boolean): Unit = {
val packageRepository = context.getPackageRepository
packageRepository.getMainProjectPackage match {
case None =>
logger.log(
Level.SEVERE,
s"No package found in the compiler environment. Aborting."
)
case Some(pkg) =>
val packageModule = packageRepository.getModuleMap.get(
s"${pkg.namespace}.${pkg.name}.Main"
)
packageModule match {
case None =>
logger.log(
Level.SEVERE,
s"Could not find entry point for compilation in package " +
s"[${pkg.namespace}.${pkg.name}]."
)
case Some(m) =>
logger.log(
Compiler.defaultLogLevel,
s"Compiling the package [${pkg.namespace}.${pkg.name}] " +
s"starting at the root [${m.getName}]."
)
val packageModules = packageRepository.freezeModuleMap.collect {
case (name, mod)
if name.startsWith(s"${pkg.namespace}.${pkg.name}") =>
mod
}.toList
runInternal(
packageModules,
generateCode = false,
shouldCompileDependencies
)
}
}
}
/** Runs part of the compiler to generate docs from Enso code.
*
* @param module the scope from which docs are generated
*/
def generateDocs(module: Module): Module = {
initializeBuiltinsIr()
parseModule(module, isGenDocs = true)
module
}
private def runInternal(
modules: List[Module],
generateCode: Boolean,
shouldCompileDependencies: Boolean
): Unit = {
initializeBuiltinsIr()
modules.foreach(m => parseModule(m))
var requiredModules = modules.flatMap(runImportsAndExportsResolution)
var hasInvalidModuleRelink = false
if (irCachingEnabled && irCacheReadingEnabled) {
if (irCachingEnabled) {
requiredModules.foreach { module =>
if (!module.hasCrossModuleLinks) {
val flags =
@ -140,7 +215,7 @@ class Compiler(
s"export resolution."
)
requiredModules = runImportsAndExportsResolution(module)
requiredModules = modules.flatMap(runImportsAndExportsResolution)
}
requiredModules.foreach { module =>
@ -183,30 +258,38 @@ class Compiler(
Module.CompilationStage.AFTER_CODEGEN
)
) {
logger.log(
Compiler.defaultLogLevel,
s"Generating code for module [${module.getName}]."
)
truffleCodegen(module.getIr, module.getSource, module.getScope)
if (generateCode) {
logger.log(
Compiler.defaultLogLevel,
s"Generating code for module [${module.getName}]."
)
truffleCodegen(module.getIr, module.getSource, module.getScope)
}
module.unsafeSetCompilationStage(Module.CompilationStage.AFTER_CODEGEN)
val shouldStoreCache = irCachingEnabled && !module.wasLoadedFromCache()
if (shouldStoreCache && !hasErrors(module) && !module.isInteractive) {
serializationManager.serialize(module)
if (shouldCompileDependencies || isModuleInRootPackage(module)) {
val shouldStoreCache =
irCachingEnabled && !module.wasLoadedFromCache()
if (shouldStoreCache && !hasErrors(module) && !module.isInteractive) {
serializationManager.serialize(module, useGlobalCacheLocations)
}
} else {
logger.log(
Compiler.defaultLogLevel,
s"Skipping serialization for [${module.getName}]."
)
}
}
}
}
/** Runs part of the compiler to generate docs from Enso code.
*
* @param module the scope from which docs are generated
*/
def generateDocs(module: Module): Module = {
initializeBuiltinsIr()
parseModule(module, isGenDocs = true)
module
private def isModuleInRootPackage(module: Module): Boolean = {
if (!module.isInteractive) {
val pkg = context.getPackageOf(module.getSourceFile).toScala
pkg.contains(context.getPackageRepository.getMainProjectPackage.get)
} else false
}
private def runImportsAndExportsResolution(module: Module): List[Module] = {
@ -230,7 +313,7 @@ class Compiler(
module.ensureScopeExists()
module.getScope.reset()
if (irCachingEnabled && irCacheReadingEnabled && !module.isInteractive) {
if (irCachingEnabled && !module.isInteractive) {
serializationManager.deserialize(module) match {
case Some(_) => return
case _ =>

View File

@ -8,7 +8,7 @@ import io.circe.parser._
import io.circe.syntax._
import org.bouncycastle.jcajce.provider.digest.SHA3
import org.bouncycastle.util.encoders.Hex
import org.enso.compiler.ModuleCache.ToMaskedPath
import org.enso.compiler.ModuleCache.{logLevel, ToMaskedPath}
import org.enso.compiler.core.IR
import org.enso.interpreter.runtime.builtin.Builtins
import org.enso.interpreter.runtime.{Context, Module}
@ -36,18 +36,28 @@ class ModuleCache(private val module: Module) {
*
* @param module the module representation to be saved
* @param context the language context in which saving is taking place
* @param useGlobalCacheLocations
* @return returns the location of the cache if successful, and [[None]] if
* it was unable to save
*/
def save(
module: ModuleCache.CachedModule,
context: Context
context: Context,
useGlobalCacheLocations: Boolean
): Option[TruffleFile] = this.synchronized {
implicit val logger: TruffleLogger = context.getLogger(this.getClass)
getIrCacheRoots(context) match {
case Some(roots) =>
if (saveCacheTo(roots.globalCacheRoot, module)) {
return Some(roots.globalCacheRoot)
if (useGlobalCacheLocations) {
if (saveCacheTo(roots.globalCacheRoot, module)) {
return Some(roots.globalCacheRoot)
}
} else {
logger.log(
logLevel,
s"Skipping use of global cache locations for module " +
s"${this.module.getName}."
)
}
if (saveCacheTo(roots.localCacheRoot, module)) {

View File

@ -60,6 +60,10 @@ trait PackageRepository {
pkg: Package[TruffleFile]
): Unit
/** @return the main project package, if it exists
*/
def getMainProjectPackage: Option[Package[TruffleFile]]
/** Register a single module, outside of any packages or part of an already
* loaded package, that has been created manually during runtime.
*/
@ -127,8 +131,9 @@ object PackageRepository {
private val logger = Logger[Default]
implicit private val fs: TruffleFileSystem = new TruffleFileSystem
private val packageManager = new PackageManager[TruffleFile]
implicit private val fs: TruffleFileSystem = new TruffleFileSystem
private val packageManager = new PackageManager[TruffleFile]
private var projectPackage: Option[Package[TruffleFile]] = None
/** The mapping containing all loaded packages.
*
@ -165,12 +170,20 @@ object PackageRepository {
override def registerMainProjectPackage(
libraryName: LibraryName,
pkg: Package[TruffleFile]
): Unit = registerPackageInternal(
libraryName = libraryName,
pkg = pkg,
libraryVersion = LibraryVersion.Local,
isLibrary = false
)
): Unit = {
projectPackage = Some(pkg)
registerPackageInternal(
libraryName = libraryName,
pkg = pkg,
libraryVersion = LibraryVersion.Local,
isLibrary = false
)
}
/** @inheritdoc */
override def getMainProjectPackage: Option[Package[TruffleFile]] = {
projectPackage
}
private def registerPackageInternal(
libraryName: LibraryName,

View File

@ -55,6 +55,12 @@ class SerializationManager(compiler: Compiler) {
}
)
// Make sure it is started to avoid races with language shutdown with low job
// count.
if (compiler.context.getEnvironment.isCreateThreadAllowed) {
pool.prestartAllCoreThreads()
}
// === Interface ============================================================
/** Requests that `module` be serialized.
@ -76,7 +82,7 @@ class SerializationManager(compiler: Compiler) {
* @return `true` if `module` has been scheduled for serialization, `false`
* otherwise
*/
def serialize(module: Module): Boolean = {
def serialize(module: Module, useGlobalCacheLocations: Boolean): Boolean = {
logger.log(
debugLogLevel,
s"Requesting serialization for module [${module.getName}]."
@ -92,7 +98,8 @@ class SerializationManager(compiler: Compiler) {
duplicatedIr,
module.getCompilationStage,
module.getName,
module.getSource
module.getSource,
useGlobalCacheLocations
)
if (compiler.context.getEnvironment.isCreateThreadAllowed) {
isWaitingForSerialization.put(module.getName, task)
@ -213,15 +220,23 @@ class SerializationManager(compiler: Compiler) {
s"Waiting for $jobCount serialization jobs to complete."
)
while (this.hasJobsRemaining) {
// Bound the waiting loop
val maxCount = 60
var counter = 0
while (this.hasJobsRemaining && counter < maxCount) {
counter += 1
Thread.sleep(1 * 1000)
}
}
pool.shutdown()
while (!pool.isTerminated) {
// Bound the waiting loop
val maxCount = 10
var counter = 0
while (!pool.isTerminated && counter < maxCount) {
pool.awaitTermination(500, TimeUnit.MILLISECONDS)
counter += 1
}
pool.shutdownNow()
@ -252,13 +267,14 @@ class SerializationManager(compiler: Compiler) {
ir: IR.Module,
stage: Module.CompilationStage,
name: QualifiedName,
source: Source
source: Source,
useGlobalCaches: Boolean
): Runnable = { () =>
startSerializing(name)
logger.log(
debugLogLevel,
s"Running serialization for module [$name]."
)
startSerializing(name)
try {
val fixedStage =
if (stage.isAtLeast(Module.CompilationStage.AFTER_STATIC_PASSES)) {
@ -266,7 +282,8 @@ class SerializationManager(compiler: Compiler) {
} else stage
cache.save(
ModuleCache.CachedModule(ir, fixedStage, source),
compiler.context
compiler.context,
useGlobalCaches
)
} catch {
case e: NotSerializableException =>

View File

@ -23,7 +23,7 @@ case class SourceFile[F](qualifiedName: QualifiedName, file: F)
*
* @param root the root directory of this package
* @param config the metadata contained in the package configuration
* @param fileSystem the file system access module
* @param fileSystem the file system access module
*/
case class Package[F](
root: F,

View File

@ -45,7 +45,7 @@ import project.System.Process_Spec
import project.Examples_Spec
Main = Test.Suite.run_main <|
main = Test.Suite.run_main <|
Any_Spec.spec
Array_Spec.spec
Case_Spec.spec