net.sandius.rembulan.compiler.CompilerSettings Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2016 Miroslav Janíček
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sandius.rembulan.compiler;
import java.util.Objects;
/**
* An immutable class encapsulating the settings of the compilation of Lua to Java bytecode
* by {@link LuaCompiler}.
*
* The settings are the following
*
* - CPU accounting ({@link CPUAccountingMode}): controls whether and how
* the functions generated by the compiler account for number of ticks spent in execution
* and pause when their time slice has expired;
* - const folding (boolean): when {@code true}, constants are folded at compile
* time (note that this does not have an influence on the number of ticks counted);
* - const caching (boolean): when {@code true}, boxed numeric constants are stored
* as static fields rather than being instantiated (and boxed) at execution time;
* - node size limit (int): when positive, long functions are split up into smaller
* Java methods (each containing at most the specified number of IR nodes); otherwise,
* a single method containing the entire function code is generated. Java class files
* impose a strict limit of 64 kB per method: this setting allows the compilation
* of arbitrarily-long Lua functions.
*
*
* To obtain the settings with sensible defaults, use {@link CompilerSettings#defaultSettings()}.
* To obtain the default settings with CPU accounting disabled,
* use {@link CompilerSettings#defaultNoAccountingSettings()}.
*
*/
public final class CompilerSettings {
/**
* CPU accounting mode.
*/
public enum CPUAccountingMode {
/**
* Do not do CPU accounting.
*/
NO_CPU_ACCOUNTING,
/**
* Check CPU time usage at the beginning of every basic block.
*
* At the beginning of every basic block, update the ticks by invoking
* {@link net.sandius.rembulan.runtime.ExecutionContext#registerTicks(int)}
* and potentially pause by invoking
* {@link net.sandius.rembulan.runtime.ExecutionContext#pauseIfRequested()}.
*/
IN_EVERY_BASIC_BLOCK
}
/**
* The default CPU accounting mode.
*/
public static final CPUAccountingMode DEFAULT_CPU_ACCOUNTING_MODE = CPUAccountingMode.IN_EVERY_BASIC_BLOCK;
/**
* The default const folding mode.
*/
public static final boolean DEFAULT_CONST_FOLDING_MODE = true;
/**
* The default const caching mode.
*/
public static final boolean DEFAULT_CONST_CACHING_MODE = true;
/**
* The default byte string mode.
*/
public static final boolean DEFAULT_BYTE_STRING_MODE = true;
/**
* The default method size limit.
*/
public static final int DEFAULT_NODE_SIZE_LIMIT = 2000;
private final CPUAccountingMode cpuAccountingMode;
private final boolean constFolding;
private final boolean constCaching;
private final boolean byteStrings;
private final int nodeSizeLimit;
CompilerSettings(
CPUAccountingMode cpuAccountingMode,
boolean constFolding,
boolean constCaching,
boolean byteStrings,
int nodeSizeLimit) {
this.cpuAccountingMode = Objects.requireNonNull(cpuAccountingMode);
this.constFolding = constFolding;
this.constCaching = constCaching;
this.byteStrings = byteStrings;
this.nodeSizeLimit = nodeSizeLimit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CompilerSettings that = (CompilerSettings) o;
return this.cpuAccountingMode == that.cpuAccountingMode
&& this.constFolding == that.constFolding
&& this.constCaching == that.constCaching
&& this.byteStrings == that.byteStrings
&& this.nodeSizeLimit == that.nodeSizeLimit;
}
@Override
public int hashCode() {
int result = cpuAccountingMode.hashCode();
result = 31 * result + (constFolding ? 1 : 0);
result = 31 * result + (constCaching ? 1 : 0);
result = 31 * result + (byteStrings ? 1 : 0);
result = 31 * result + nodeSizeLimit;
return result;
}
/**
* Returns the compiler settings with the given parameters.
*
* When {@code nodeSizeLimit} is non-positive, no chunking of the body method
* will be performed.
*
* @param cpuAccountingMode CPU accounting mode, must not be {@code null}
* @param constFolding const folding mode
* @param constCaching const caching mode
* @param byteStrings byte string mode
* @param nodeSizeLimit node size limit
* @return the corresponding compiler settings
*
* @throws NullPointerException if {@code cpuAccountingMode} is {@code null}
*/
public static CompilerSettings of(
CPUAccountingMode cpuAccountingMode,
boolean constFolding,
boolean constCaching,
boolean byteStrings,
int nodeSizeLimit) {
return new CompilerSettings(
cpuAccountingMode, constFolding, constCaching, byteStrings, nodeSizeLimit);
}
/**
* Returns the default compiler settings.
*
* @return the default compiler settings
*/
public static CompilerSettings defaultSettings() {
return CompilerSettings.of(
DEFAULT_CPU_ACCOUNTING_MODE,
DEFAULT_CONST_FOLDING_MODE,
DEFAULT_CONST_CACHING_MODE,
DEFAULT_BYTE_STRING_MODE,
DEFAULT_NODE_SIZE_LIMIT);
}
/**
* Returns the default compiler settings without CPU accounting.
*
* @return the default compiler settings without CPU accounting
*/
public static CompilerSettings defaultNoAccountingSettings() {
return defaultSettings().withCPUAccountingMode(CPUAccountingMode.NO_CPU_ACCOUNTING);
}
/**
* Returns the CPU accounting mode.
*
* @return the CPU accounting mode
*/
public CPUAccountingMode cpuAccountingMode() {
return cpuAccountingMode;
}
/**
* Returns the const folding mode.
*
* @return the const folding mode
*/
public boolean constFolding() {
return constFolding;
}
/**
* Returns the const caching mode.
*
* @return the const caching mode
*/
public boolean constCaching() {
return constCaching;
}
public boolean byteStrings() {
return byteStrings;
}
/**
* Returns the node size limit.
*
* @return the node size limit
*/
public int nodeSizeLimit() {
return nodeSizeLimit;
}
/**
* Returns compiler settings derived from this compiler settings by updating
* the CPU accounting mode to {@code mode}.
*
* @param mode new CPU accounting mode, must not be {@code null}
* @return settings derived from {@code this} by updating the CPU accounting mode
* to {@code mode}
*
* @throws NullPointerException if {@code mode} is {@code null}
*/
public CompilerSettings withCPUAccountingMode(CPUAccountingMode mode) {
return mode != this.cpuAccountingMode
? new CompilerSettings(mode, constFolding, constCaching, byteStrings, nodeSizeLimit)
: this;
}
/**
* Returns compiler settings derived from this compiler settings by updating
* the const folding mode to {@code mode}.
*
* @param mode new const folding mode
* @return settings derived from {@code this} by updating the const folding mode
* to {@code mode}
*/
public CompilerSettings withConstFolding(boolean mode) {
return mode != this.constFolding
? new CompilerSettings(cpuAccountingMode, mode, constCaching, byteStrings, nodeSizeLimit)
: this;
}
/**
* Returns compiler settings derived from this compiler settings by updating
* the const caching mode to {@code mode}.
*
* @param mode new const caching mode
* @return settings derived from {@code this} by updating the const caching mode
* to {@code mode}
*/
public CompilerSettings withConstCaching(boolean mode) {
return mode != this.constCaching
? new CompilerSettings(cpuAccountingMode, constFolding, mode, byteStrings, nodeSizeLimit)
: this;
}
/**
* Returns compiler settings derived from this compiler settings by updating
* the byte string mode to {@code mode}.
*
* @param mode new byte string mode
* @return settings derived from {@code this} by updating the byte string mode to {@code mode}
*/
public CompilerSettings withByteStrings(boolean mode) {
return mode != this.byteStrings
? new CompilerSettings(cpuAccountingMode, constFolding, constCaching, mode, nodeSizeLimit)
: this;
}
/**
* Returns compiler settings derived from this compiler settings by updating
* the node size limit to {@code limit}.
*
* @param limit new node size limit
* @return settings derived from {@code this} by updating the node size limit
* to {@code limit}
*/
public CompilerSettings withNodeSizeLimit(int limit) {
return limit != this.nodeSizeLimit
? new CompilerSettings(cpuAccountingMode, constFolding, constCaching, byteStrings, limit)
: this;
}
}