8041434: Add synchronization to the common global constants structure

Reviewed-by: attila, hannesw
This commit is contained in:
Marcus Lagergren 2014-04-23 17:37:41 +02:00
parent 7bb2546460
commit e30eb1b6bb
35 changed files with 409 additions and 385 deletions

View file

@ -25,6 +25,7 @@ $FLAGS \
-cp $CLASSPATH:../build/test/classes/ \ -cp $CLASSPATH:../build/test/classes/ \
jdk.nashorn.tools.Shell ${@} jdk.nashorn.tools.Shell ${@}
#-Djava.security.manager= -Djava.security.policy=$DIR/build/nashorn.policy \
#-XX:+ShowHiddenFrames \ #-XX:+ShowHiddenFrames \
#-XX:+PrintOptoAssembly \ #-XX:+PrintOptoAssembly \
#-XX:-TieredCompilation \ #-XX:-TieredCompilation \

View file

@ -48,6 +48,7 @@ import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable; import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger; import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.options.Options; import jdk.nashorn.internal.runtime.options.Options;
@ -106,15 +107,16 @@ public final class ApplySpecialization implements Loggable {
* applies as calls if they just pass on the "arguments" array and * applies as calls if they just pass on the "arguments" array and
* "arguments" doesn't escape. * "arguments" doesn't escape.
* *
* @param context context
* @param data recompilable script function data, which contains e.g. needs callee information * @param data recompilable script function data, which contains e.g. needs callee information
* @param functionNode functionNode * @param functionNode functionNode
* @param actualCallSiteType actual call site type that we use (not Object[] varargs) * @param actualCallSiteType actual call site type that we use (not Object[] varargs)
*/ */
public ApplySpecialization(final RecompilableScriptFunctionData data, final FunctionNode functionNode, final MethodType actualCallSiteType) { public ApplySpecialization(final Context context, final RecompilableScriptFunctionData data, final FunctionNode functionNode, final MethodType actualCallSiteType) {
this.data = data; this.data = data;
this.functionNode = functionNode; this.functionNode = functionNode;
this.actualCallSiteType = actualCallSiteType; this.actualCallSiteType = actualCallSiteType;
this.log = initLogger(Global.instance()); this.log = initLogger(context);
} }
@Override @Override
@ -123,8 +125,8 @@ public final class ApplySpecialization implements Loggable {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
/** /**

View file

@ -100,7 +100,6 @@ import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.WithNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.Debug;
@ -164,7 +163,7 @@ final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> implement
this.temporarySymbols = temporarySymbols; this.temporarySymbols = temporarySymbols;
this.localDefs = new ArrayDeque<>(); this.localDefs = new ArrayDeque<>();
this.localUses = new ArrayDeque<>(); this.localUses = new ArrayDeque<>();
this.log = initLogger(Global.instance()); this.log = initLogger(env.getContext());
this.debug = log.isEnabled(); this.debug = log.isEnabled();
} }
@ -174,8 +173,8 @@ final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> implement
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -70,7 +70,6 @@ import jdk.nashorn.internal.ir.debug.NashornTextifier;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.RewriteException; import jdk.nashorn.internal.runtime.RewriteException;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.Source;
@ -128,7 +127,7 @@ public class ClassEmitter implements Emitter {
protected final ClassWriter cw; protected final ClassWriter cw;
/** The script environment */ /** The script environment */
protected final ScriptEnvironment env; protected final Context context;
/** Compile unit class name. */ /** Compile unit class name. */
private String unitClassName; private String unitClassName;
@ -143,10 +142,8 @@ public class ClassEmitter implements Emitter {
* @param env script environment * @param env script environment
* @param cw ASM classwriter * @param cw ASM classwriter
*/ */
private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) { private ClassEmitter(final Context context, final ClassWriter cw) {
assert env != null; this.context = context;
this.env = env;
this.cw = cw; this.cw = cw;
this.methodsStarted = new HashSet<>(); this.methodsStarted = new HashSet<>();
} }
@ -159,8 +156,8 @@ public class ClassEmitter implements Emitter {
* @param superClassName super class name for class * @param superClassName super class name for class
* @param interfaceNames names of interfaces implemented by this class, or null if none * @param interfaceNames names of interfaces implemented by this class, or null if none
*/ */
ClassEmitter(final ScriptEnvironment env, final String className, final String superClassName, final String... interfaceNames) { ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS)); this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames); cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames);
} }
@ -172,8 +169,8 @@ public class ClassEmitter implements Emitter {
* @param unitClassName Compile unit class name. * @param unitClassName Compile unit class name.
* @param strictMode Should we generate this method in strict mode * @param strictMode Should we generate this method in strict mode
*/ */
ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) { ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) {
this(env, this(context,
new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
private static final String OBJECT_CLASS = "java/lang/Object"; private static final String OBJECT_CLASS = "java/lang/Object";
@ -199,6 +196,10 @@ public class ClassEmitter implements Emitter {
defineCommonStatics(strictMode); defineCommonStatics(strictMode);
} }
Context getContext() {
return context;
}
/** /**
* Returns the name of the compile unit class name. * Returns the name of the compile unit class name.
* @return the name of the compile unit class name. * @return the name of the compile unit class name.
@ -393,13 +394,6 @@ public class ClassEmitter implements Emitter {
return str; return str;
} }
/**
* @return env used for class emission
*/
ScriptEnvironment getEnv() {
return env;
}
/** /**
* Call back from MethodEmitter for method start * Call back from MethodEmitter for method start
* *

View file

@ -240,7 +240,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
super(new CodeGeneratorLexicalContext()); super(new CodeGeneratorLexicalContext());
this.compiler = compiler; this.compiler = compiler;
this.callSiteFlags = compiler.getEnv()._callsite_flags; this.callSiteFlags = compiler.getEnv()._callsite_flags;
this.log = initLogger(Global.instance()); this.log = initLogger(compiler.getCompilationEnvironment().getContext());
} }
@Override @Override
@ -249,8 +249,8 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
/** /**

View file

@ -34,6 +34,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.AccessNode;
import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.Expression;
@ -42,6 +43,7 @@ import jdk.nashorn.internal.ir.IdentNode;
import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.IndexNode;
import jdk.nashorn.internal.ir.Optimistic; import jdk.nashorn.internal.ir.Optimistic;
import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.objects.NativeArray;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.FindProperty; import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.Property;
@ -57,6 +59,8 @@ public final class CompilationEnvironment {
private final CompilationPhases phases; private final CompilationPhases phases;
private final boolean optimistic; private final boolean optimistic;
private final Context context;
private final ParamTypeMap paramTypes; private final ParamTypeMap paramTypes;
private RecompilableScriptFunctionData compiledFunction; private RecompilableScriptFunctionData compiledFunction;
@ -176,17 +180,21 @@ public final class CompilationEnvironment {
/** /**
* Constructor * Constructor
* @param context context
* @param phases compilation phases * @param phases compilation phases
* @param strict strict mode * @param strict strict mode
*/ */
public CompilationEnvironment( public CompilationEnvironment(
final Context context,
final CompilationPhases phases, final CompilationPhases phases,
final boolean strict) { final boolean strict) {
this(phases, null, null, null, null, null, strict, false); this(context, phases, null, null, null, null, null, strict, false);
} }
/** /**
* Constructor for compilation environment of the rest-of method * Constructor for compilation environment of the rest-of method
*
* @param context context
* @param phases compilation phases * @param phases compilation phases
* @param strict strict mode * @param strict strict mode
* @param compiledFunction the function being compiled * @param compiledFunction the function being compiled
@ -200,6 +208,7 @@ public final class CompilationEnvironment {
* @param onDemand is this an on demand compilation * @param onDemand is this an on demand compilation
*/ */
public CompilationEnvironment( public CompilationEnvironment(
final Context context,
final CompilationPhases phases, final CompilationPhases phases,
final boolean strict, final boolean strict,
final RecompilableScriptFunctionData compiledFunction, final RecompilableScriptFunctionData compiledFunction,
@ -208,11 +217,13 @@ public final class CompilationEnvironment {
final Map<Integer, Type> invalidatedProgramPoints, final Map<Integer, Type> invalidatedProgramPoints,
final int[] continuationEntryPoint, final int[] continuationEntryPoint,
final boolean onDemand) { final boolean onDemand) {
this(phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, continuationEntryPoint, strict, onDemand); this(context, phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, continuationEntryPoint, strict, onDemand);
} }
/** /**
* Constructor * Constructor
*
* @param context context
* @param phases compilation phases * @param phases compilation phases
* @param strict strict mode * @param strict strict mode
* @param compiledFunction recompiled function * @param compiledFunction recompiled function
@ -225,6 +236,7 @@ public final class CompilationEnvironment {
* @param onDemand is this an on demand compilation * @param onDemand is this an on demand compilation
*/ */
public CompilationEnvironment( public CompilationEnvironment(
final Context context,
final CompilationPhases phases, final CompilationPhases phases,
final boolean strict, final boolean strict,
final RecompilableScriptFunctionData compiledFunction, final RecompilableScriptFunctionData compiledFunction,
@ -232,10 +244,11 @@ public final class CompilationEnvironment {
final ParamTypeMap paramTypeMap, final ParamTypeMap paramTypeMap,
final Map<Integer, Type> invalidatedProgramPoints, final Map<Integer, Type> invalidatedProgramPoints,
final boolean onDemand) { final boolean onDemand) {
this(phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, null, strict, onDemand); this(context, phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, null, strict, onDemand);
} }
private CompilationEnvironment( private CompilationEnvironment(
final Context context,
final CompilationPhases phases, final CompilationPhases phases,
final ParamTypeMap paramTypes, final ParamTypeMap paramTypes,
final Map<Integer, Type> invalidatedProgramPoints, final Map<Integer, Type> invalidatedProgramPoints,
@ -244,6 +257,7 @@ public final class CompilationEnvironment {
final int[] continuationEntryPoints, final int[] continuationEntryPoints,
final boolean strict, final boolean strict,
final boolean onDemand) { final boolean onDemand) {
this.context = context;
this.phases = phases; this.phases = phases;
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
this.continuationEntryPoints = continuationEntryPoints; this.continuationEntryPoints = continuationEntryPoints;
@ -261,6 +275,10 @@ public final class CompilationEnvironment {
assert !isCompileRestOf() || invalidatedProgramPoints != null && containsAll(invalidatedProgramPoints.keySet(), continuationEntryPoints); assert !isCompileRestOf() || invalidatedProgramPoints != null && containsAll(invalidatedProgramPoints.keySet(), continuationEntryPoints);
} }
Context getContext() {
return context;
}
private static boolean containsAll(final Set<Integer> set, final int[] array) { private static boolean containsAll(final Set<Integer> set, final int[] array) {
for (int i = 0; i < array.length; ++i) { for (int i = 0; i < array.length; ++i) {
if (!set.contains(array[i])) { if (!set.contains(array[i])) {

View file

@ -53,7 +53,6 @@ import jdk.nashorn.internal.ir.TemporarySymbols;
import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.debug.ASTWriter;
import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.ir.debug.PrintVisitor;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.Timing; import jdk.nashorn.internal.runtime.Timing;
@ -69,7 +68,7 @@ enum CompilationPhase {
CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) { CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
@Override @Override
FunctionNode transform(final Compiler compiler, final FunctionNode fn) { FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
return (FunctionNode)fn.accept(new FoldConstants()); return (FunctionNode)fn.accept(new FoldConstants(compiler.getCompilationEnvironment()));
} }
@Override @Override
@ -88,7 +87,7 @@ enum CompilationPhase {
LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) { LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) {
@Override @Override
FunctionNode transform(final Compiler compiler, final FunctionNode fn) { FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
return (FunctionNode)fn.accept(new Lower(compiler.getCodeInstaller())); return (FunctionNode)fn.accept(new Lower(compiler));
} }
@Override @Override
@ -191,7 +190,7 @@ enum CompilationPhase {
return fn; return fn;
} }
FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer()); FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer(compiler.getCompilationEnvironment()));
final List<ReturnNode> returns = new ArrayList<>(); final List<ReturnNode> returns = new ArrayList<>();
newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
@ -225,7 +224,7 @@ enum CompilationPhase {
@Override @Override
public Node leaveDefault(final Node node) { public Node leaveDefault(final Node node) {
if(node instanceof Expression) { if (node instanceof Expression) {
final Expression expr = (Expression)node; final Expression expr = (Expression)node;
final Symbol symbol = expr.getSymbol(); final Symbol symbol = expr.getSymbol();
if (symbol != null) { if (symbol != null) {
@ -238,7 +237,7 @@ enum CompilationPhase {
final Type rangeType = range.getType(); final Type rangeType = range.getType();
if (!rangeType.isUnknown() && !Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range if (!rangeType.isUnknown() && !Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
Global.instance().getLogger(RangeAnalyzer.class).info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange()); compiler.getCompilationEnvironment().getContext().getLogger(RangeAnalyzer.class).info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
return expr.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols())); return expr.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
} }
} }
@ -284,7 +283,7 @@ enum CompilationPhase {
FunctionNode transform(final Compiler compiler, final FunctionNode fn) { FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
final ScriptEnvironment env = compiler.getEnv(); final ScriptEnvironment env = compiler.getEnv();
final FunctionNode newFunctionNode = (FunctionNode)fn.accept(new FinalizeTypes()); final FunctionNode newFunctionNode = (FunctionNode)fn.accept(new FinalizeTypes(compiler.getCompilationEnvironment()));
if (env._print_lower_ast) { if (env._print_lower_ast) {
env.getErr().println(new ASTWriter(newFunctionNode)); env.getErr().println(new ASTWriter(newFunctionNode));

View file

@ -61,8 +61,8 @@ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
import jdk.nashorn.internal.ir.TemporarySymbols; import jdk.nashorn.internal.ir.TemporarySymbols;
import jdk.nashorn.internal.ir.debug.ClassHistogramElement; import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator; import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.CodeInstaller; import jdk.nashorn.internal.runtime.CodeInstaller;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.Source;
@ -150,9 +150,8 @@ public final class Compiler implements Loggable {
this.constantData = new ConstantData(); this.constantData = new ConstantData();
this.compileUnits = new TreeSet<>(); this.compileUnits = new TreeSet<>();
this.bytecode = new LinkedHashMap<>(); this.bytecode = new LinkedHashMap<>();
this.log = initLogger(Global.instance()); this.log = initLogger(compilationEnv.getContext());
synchronized (Compiler.class) {
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
if (!ScriptEnvironment.globalOptimistic()) { if (!ScriptEnvironment.globalOptimistic()) {
@ -160,7 +159,6 @@ public final class Compiler implements Loggable {
} }
} }
} }
}
/** /**
* Constructor - common entry point for generating code. * Constructor - common entry point for generating code.
@ -177,7 +175,7 @@ public final class Compiler implements Loggable {
* @param scriptEnv script environment * @param scriptEnv script environment
*/ */
public Compiler(final ScriptEnvironment scriptEnv) { public Compiler(final ScriptEnvironment scriptEnv) {
this(new CompilationEnvironment(CompilationPhases.EAGER, scriptEnv._strict), scriptEnv, null); this(new CompilationEnvironment(Context.getContext(), CompilationPhases.EAGER, scriptEnv._strict), scriptEnv, null);
} }
@Override @Override
@ -186,8 +184,8 @@ public final class Compiler implements Loggable {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
private void printMemoryUsage(final String phaseName, final FunctionNode functionNode) { private void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
@ -500,7 +498,7 @@ public final class Compiler implements Loggable {
} }
private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) { private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
final ClassEmitter classEmitter = new ClassEmitter(scriptEnv, sourceName, unitClassName, compilationEnv.isStrict()); final ClassEmitter classEmitter = new ClassEmitter(compilationEnv.getContext(), sourceName, unitClassName, compilationEnv.isStrict());
final CompileUnit compileUnit = new CompileUnit(unitClassName, classEmitter, initialWeight); final CompileUnit compileUnit = new CompileUnit(unitClassName, classEmitter, initialWeight);
classEmitter.begin(); classEmitter.begin();

View file

@ -42,9 +42,9 @@ import jdk.nashorn.internal.ir.RuntimeNode.Request;
import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable; import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger; import jdk.nashorn.internal.runtime.logging.Logger;
@ -66,9 +66,9 @@ final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> implements
private final DebugLogger log; private final DebugLogger log;
FinalizeTypes() { FinalizeTypes(final CompilationEnvironment env) {
super(new LexicalContext()); super(new LexicalContext());
this.log = initLogger(Global.instance()); this.log = initLogger(env.getContext());
} }
@Override @Override
@ -77,8 +77,8 @@ final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> implements
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -42,7 +42,7 @@ import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
@ -70,7 +70,7 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
super(new LexicalContext()); super(new LexicalContext());
this.compiler = compiler; this.compiler = compiler;
this.env = compiler.getCompilationEnvironment(); this.env = compiler.getCompilationEnvironment();
this.log = initLogger(Global.instance()); this.log = initLogger(compiler.getCompilationEnvironment().getContext());
} }
@Override @Override
@ -79,8 +79,8 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
static int findScopesToStart(final LexicalContext lc, final FunctionNode fn, final Block block) { static int findScopesToStart(final LexicalContext lc, final FunctionNode fn, final Block block) {
@ -187,6 +187,7 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
final String allocatorClassName = Compiler.binaryName(getClassName(fieldCount)); final String allocatorClassName = Compiler.binaryName(getClassName(fieldCount));
final PropertyMap allocatorMap = PropertyMap.newMap(null, 0, fieldCount, 0); final PropertyMap allocatorMap = PropertyMap.newMap(null, 0, fieldCount, 0);
final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData( final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
compiler.getCompilationEnvironment().getContext(),
newFunctionNode, newFunctionNode,
compiler.getCodeInstaller(), compiler.getCodeInstaller(),
allocatorClassName, allocatorClassName,

View file

@ -45,7 +45,7 @@ import jdk.nashorn.internal.ir.TernaryNode;
import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
@ -60,9 +60,9 @@ final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggabl
private final DebugLogger log; private final DebugLogger log;
FoldConstants() { FoldConstants(final CompilationEnvironment env) {
super(new LexicalContext()); super(new LexicalContext());
this.log = initLogger(Global.instance()); this.log = initLogger(env.getContext());
} }
@Override @Override
@ -71,8 +71,8 @@ final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggabl
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -68,10 +68,10 @@ import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.WithNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.CodeInstaller; import jdk.nashorn.internal.runtime.CodeInstaller;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
@ -98,7 +98,7 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
/** /**
* Constructor. * Constructor.
*/ */
Lower(final CodeInstaller<?> installer) { Lower(final Compiler compiler) {
super(new BlockLexicalContext() { super(new BlockLexicalContext() {
@Override @Override
@ -142,8 +142,8 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
} }
}); });
this.installer = installer; this.installer = compiler.getCodeInstaller();
this.log = initLogger(Global.instance()); this.log = initLogger(compiler.getCompilationEnvironment().getContext());
} }
@Override @Override
@ -152,8 +152,8 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -97,10 +97,10 @@ import jdk.nashorn.internal.ir.RuntimeNode;
import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ArgumentSetter; import jdk.nashorn.internal.runtime.ArgumentSetter;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.Debug;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.RewriteException; import jdk.nashorn.internal.runtime.RewriteException;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
@ -135,8 +135,8 @@ public class MethodEmitter implements Emitter {
/** Check whether this emitter ever has a function return point */ /** Check whether this emitter ever has a function return point */
private boolean hasReturn; private boolean hasReturn;
/** The script environment */ /** The context */
private final ScriptEnvironment env; private final Context context;
private final List<Type> localVariableTypes = new ArrayList<>(); private final List<Type> localVariableTypes = new ArrayList<>();
@ -144,8 +144,8 @@ public class MethodEmitter implements Emitter {
static final int LARGE_STRING_THRESHOLD = 32 * 1024; static final int LARGE_STRING_THRESHOLD = 32 * 1024;
/** Debug flag, should we dump all generated bytecode along with stacks? */ /** Debug flag, should we dump all generated bytecode along with stacks? */
private final DebugLogger log = Global.instance().getLogger(CodeGenerator.class); private final DebugLogger log;
private final boolean debug = log.isEnabled(); private final boolean debug;
/** dump stack on a particular line, or -1 if disabled */ /** dump stack on a particular line, or -1 if disabled */
private static final int DEBUG_TRACE_LINE; private static final int DEBUG_TRACE_LINE;
@ -193,11 +193,13 @@ public class MethodEmitter implements Emitter {
* @param functionNode a function node representing this method * @param functionNode a function node representing this method
*/ */
MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) { MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
this.env = classEmitter.getEnv(); this.context = classEmitter.getContext();
this.classEmitter = classEmitter; this.classEmitter = classEmitter;
this.method = method; this.method = method;
this.functionNode = functionNode; this.functionNode = functionNode;
this.stack = null; this.stack = null;
this.log = context.getLogger(CodeGenerator.class);
this.debug = log.isEnabled();
} }
/** /**
@ -2226,7 +2228,7 @@ public class MethodEmitter implements Emitter {
* @param label label * @param label label
*/ */
void lineNumber(final int line) { void lineNumber(final int line) {
if (env._debug_lines) { if (context.getEnv()._debug_lines) {
debug_label("[LINE]", line); debug_label("[LINE]", line);
final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label(); final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label();
method.visitLabel(l); method.visitLabel(l);
@ -2385,7 +2387,7 @@ public class MethodEmitter implements Emitter {
sb.append(' '); sb.append(' ');
} }
if (env != null) { //early bootstrap code doesn't have inited context yet if (context.getEnv() != null) { //early bootstrap code doesn't have inited context yet
log.info(sb); log.info(sb);
if (DEBUG_TRACE_LINE == linePrefix) { if (DEBUG_TRACE_LINE == linePrefix) {
new Throwable().printStackTrace(log.getOutputStream()); new Throwable().printStackTrace(log.getOutputStream());

View file

@ -55,7 +55,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag; import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.FunctionScope; import jdk.nashorn.internal.runtime.FunctionScope;
@ -147,8 +146,7 @@ public final class ObjectClassGenerator implements Loggable {
public ObjectClassGenerator(final Context context) { public ObjectClassGenerator(final Context context) {
this.context = context; this.context = context;
assert context != null; assert context != null;
this.log = initLogger(Global.instance()); this.log = initLogger(context);
synchronized (ObjectClassGenerator.class) {
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
if (OBJECT_FIELDS_ONLY) { if (OBJECT_FIELDS_ONLY) {
@ -156,7 +154,6 @@ public final class ObjectClassGenerator implements Loggable {
} }
} }
} }
}
@Override @Override
public DebugLogger getLogger() { public DebugLogger getLogger() {
@ -164,8 +161,8 @@ public final class ObjectClassGenerator implements Loggable {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context ctxt) {
return global.getLogger(this.getClass()); return ctxt.getLogger(this.getClass());
} }
/** /**
@ -386,7 +383,7 @@ public final class ObjectClassGenerator implements Loggable {
* @return Open class emitter. * @return Open class emitter.
*/ */
private ClassEmitter newClassEmitter(final String className, final String superName) { private ClassEmitter newClassEmitter(final String className, final String superName) {
final ClassEmitter classEmitter = new ClassEmitter(context.getEnv(), className, superName); final ClassEmitter classEmitter = new ClassEmitter(context, className, superName);
classEmitter.begin(); classEmitter.begin();
return classEmitter; return classEmitter;

View file

@ -47,8 +47,8 @@ import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable; import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger; import jdk.nashorn.internal.runtime.logging.Logger;
@ -74,9 +74,9 @@ final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> implements
private final Map<LoopNode, Symbol> loopCounters = new HashMap<>(); private final Map<LoopNode, Symbol> loopCounters = new HashMap<>();
RangeAnalyzer() { RangeAnalyzer(final CompilationEnvironment env) {
super(new LexicalContext()); super(new LexicalContext());
this.log = initLogger(Global.instance()); this.log = initLogger(env.getContext());
this.func = new Range.Functionality(log); this.func = new Range.Functionality(log);
} }
@ -86,8 +86,8 @@ final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> implements
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -70,7 +70,6 @@ import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.Source;
/** /**
@ -81,14 +80,14 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
/** /**
* Returns AST as JSON compatible string. * Returns AST as JSON compatible string.
* *
* @param env script environment to use * @param context context
* @param code code to be parsed * @param code code to be parsed
* @param name name of the code source (used for location) * @param name name of the code source (used for location)
* @param includeLoc tells whether to include location information for nodes or not * @param includeLoc tells whether to include location information for nodes or not
* @return JSON string representation of AST of the supplied code * @return JSON string representation of AST of the supplied code
*/ */
public static String parse(final ScriptEnvironment env, final String code, final String name, final boolean includeLoc) { public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
final Parser parser = new Parser(env, new Source(name, code), new Context.ThrowErrorManager(), env._strict); final Parser parser = new Parser(context.getEnv(), new Source(name, code), new Context.ThrowErrorManager(), context.getEnv()._strict, context.getLogger(Parser.class));
final JSONWriter jsonWriter = new JSONWriter(includeLoc); final JSONWriter jsonWriter = new JSONWriter(includeLoc);
try { try {
final FunctionNode functionNode = parser.parse(CompilerConstants.PROGRAM.symbolName()); final FunctionNode functionNode = parser.parse(CompilerConstants.PROGRAM.symbolName());
@ -317,7 +316,7 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
} }
@Override @Override
public boolean enterBlockStatement(BlockStatement blockStatement) { public boolean enterBlockStatement(final BlockStatement blockStatement) {
enterDefault(blockStatement); enterDefault(blockStatement);
type("BlockStatement"); type("BlockStatement");
@ -337,13 +336,13 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
type("ForInStatement"); type("ForInStatement");
comma(); comma();
Node init = forNode.getInit(); final Node init = forNode.getInit();
assert init != null; assert init != null;
property("left"); property("left");
init.accept(this); init.accept(this);
comma(); comma();
Node modify = forNode.getModify(); final Node modify = forNode.getModify();
assert modify != null; assert modify != null;
property("right"); property("right");
modify.accept(this); modify.accept(this);
@ -760,8 +759,8 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
final List<CatchNode> guarded = new ArrayList<>(); final List<CatchNode> guarded = new ArrayList<>();
CatchNode unguarded = null; CatchNode unguarded = null;
if (catches != null) { if (catches != null) {
for (Node n : catches) { for (final Node n : catches) {
CatchNode cn = (CatchNode)n; final CatchNode cn = (CatchNode)n;
if (cn.getExceptionCondition() != null) { if (cn.getExceptionCondition() != null) {
guarded.add(cn); guarded.add(cn);
} else { } else {
@ -957,9 +956,13 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
buf.append(key); buf.append(key);
buf.append("\":"); buf.append("\":");
if (value != null) { if (value != null) {
if (escape) buf.append('"'); if (escape) {
buf.append('"');
}
buf.append(value); buf.append(value);
if (escape) buf.append('"'); if (escape) {
buf.append('"');
}
} }
} }

View file

@ -37,8 +37,8 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.Debug;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable; import jdk.nashorn.internal.runtime.logging.Loggable;
@ -107,7 +107,7 @@ public final class MethodHandleFactory {
* Return the method handle functionality used for all method handle operations * Return the method handle functionality used for all method handle operations
* @return a method handle functionality implementation * @return a method handle functionality implementation
*/ */
public static synchronized MethodHandleFunctionality getFunctionality() { public static MethodHandleFunctionality getFunctionality() {
return FUNC; return FUNC;
} }
@ -286,8 +286,8 @@ public final class MethodHandleFactory {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return this.log = global.getLogger(this.getClass()); return this.log = context.getLogger(this.getClass());
} }
@Override @Override

View file

@ -44,15 +44,13 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.codegen.ApplySpecialization; import jdk.nashorn.internal.codegen.ApplySpecialization;
import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Property; import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.ScriptClass;
@ -73,11 +71,7 @@ import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName; import jdk.nashorn.internal.runtime.linker.InvokeByName;
import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
import jdk.nashorn.internal.runtime.regexp.RegExpResult; import jdk.nashorn.internal.runtime.regexp.RegExpResult;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.scripts.JO; import jdk.nashorn.internal.scripts.JO;
/** /**
@ -437,12 +431,8 @@ public final class Global extends ScriptObject implements Scope {
// context to which this global belongs to // context to which this global belongs to
private final Context context; private final Context context;
// logging // global constants for this global - they can be replaced with MethodHandle.constant until invalidated
private final Map<String, DebugLogger> loggers = new HashMap<>(); private static AtomicReference<GlobalConstants> gcsInstance = new AtomicReference<>();
private void initLoggers() {
((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
}
@Override @Override
protected Context getContext() { protected Context getContext() {
@ -479,8 +469,11 @@ public final class Global extends ScriptObject implements Scope {
this.context = context; this.context = context;
this.setIsScope(); this.setIsScope();
this.optimisticFunctionMap = new HashMap<>(); this.optimisticFunctionMap = new HashMap<>();
final GlobalConstants gc = GlobalConstants.instance(this); //we can only share one instance of Global constants between globals, or we consume way too much
gc.invalidateAll(); //memory - this is good enough for most programs
while (gcsInstance.get() == null) {
gcsInstance.compareAndSet(null, new GlobalConstants(context.getLogger(GlobalConstants.class)));
}
} }
/** /**
@ -494,6 +487,15 @@ public final class Global extends ScriptObject implements Scope {
return global; return global;
} }
/**
* Return the global constants map for fields that
* can be accessed as MethodHandle.constant
* @return constant map
*/
public static GlobalConstants getConstants() {
return gcsInstance.get();
}
/** /**
* Check if we have a Global instance * Check if we have a Global instance
* @return true if one exists * @return true if one exists
@ -1714,8 +1716,6 @@ public final class Global extends ScriptObject implements Scope {
// synonym for "arguments" in scripting mode // synonym for "arguments" in scripting mode
addOwnProperty("$ARG", argumentsFlags, argumentsObject); addOwnProperty("$ARG", argumentsFlags, argumentsObject);
} }
initLoggers();
} }
private void initErrorObjects() { private void initErrorObjects() {
@ -2097,7 +2097,7 @@ public final class Global extends ScriptObject implements Scope {
public void invalidateReservedName(final String name) { public void invalidateReservedName(final String name) {
final SwitchPoint sp = getChangeCallback(name); final SwitchPoint sp = getChangeCallback(name);
if (sp != null) { if (sp != null) {
getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint"); getContext().getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
SwitchPoint.invalidateAll(new SwitchPoint[] { sp }); SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
} }
} }
@ -2114,72 +2114,5 @@ public final class Global extends ScriptObject implements Scope {
return new ConstantCallSite(target); return new ConstantCallSite(target);
} }
/**
* Get a logger, given a loggable class
* @param clazz a Loggable class
* @return debuglogger associated with that class
*/
public DebugLogger getLogger(final Class<? extends Loggable> clazz) {
final String name = getLoggerName(clazz);
DebugLogger logger = loggers.get(name);
if (logger == null) {
final ScriptEnvironment env = context.getEnv();
if (!env.hasLogger(name)) {
return DebugLogger.DISABLED_LOGGER;
}
final LoggerInfo info = env._loggers.get(name);
logger = new DebugLogger(name, info.getLevel(), info.isQuiet());
loggers.put(name, logger);
}
return logger;
}
/**
* Given a Loggable class, weave debug info info a method handle for that logger.
* Level.INFO is used
*
* @param clazz loggable
* @param mh method handle
* @param text debug printout to add
*
* @return instrumented method handle, or null if logger not enabled
*/
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final MethodHandle mh, final Supplier<String> text) {
return addLoggingToHandle(clazz, Level.INFO, mh, Integer.MAX_VALUE, false, text);
}
/**
* Given a Loggable class, weave debug info info a method handle for that logger.
*
* @param clazz loggable
* @param level log level
* @param mh method handle
* @param paramStart first parameter to print
* @param printReturnValue should we print the return vaulue?
* @param text debug printout to add
*
* @return instrumented method handle, or null if logger not enabled
*/
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Supplier<String> text) {
final DebugLogger log = getLogger(clazz);
if (log.isEnabled()) {
return MethodHandleFactory.addDebugPrintout(log, level, mh, paramStart, printReturnValue, text.get());
}
return mh;
}
private static String getLoggerName(final Class<?> clazz) {
Class<?> current = clazz;
while (current != null) {
final Logger log = current.getAnnotation(Logger.class);
if (log != null) {
assert !"".equals(log.name());
return log.name();
}
current = current.getSuperclass();
}
assert false;
return null;
}
} }

View file

@ -289,7 +289,7 @@ public final class NativeFunction {
private static void checkFunctionParameters(final String params) { private static void checkFunctionParameters(final String params) {
final Source src = new Source("<function>", params); final Source src = new Source("<function>", params);
final ScriptEnvironment env = Global.getEnv(); final ScriptEnvironment env = Global.getEnv();
final Parser parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict); final Parser parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict, null);
try { try {
parser.parseFormalParameterList(); parser.parseFormalParameterList();
} catch (final ParserException pe) { } catch (final ParserException pe) {
@ -300,7 +300,7 @@ public final class NativeFunction {
private static void checkFunctionBody(final String funcBody) { private static void checkFunctionBody(final String funcBody) {
final Source src = new Source("<function>", funcBody); final Source src = new Source("<function>", funcBody);
final ScriptEnvironment env = Global.getEnv(); final ScriptEnvironment env = Global.getEnv();
final Parser parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict); final Parser parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict, null);
try { try {
parser.parseFunctionBody(); parser.parseFunctionBody();
} catch (final ParserException pe) { } catch (final ParserException pe) {

View file

@ -105,7 +105,7 @@ import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.WhileNode; import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.WithNode;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSErrorType; import jdk.nashorn.internal.runtime.JSErrorType;
import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.ParserException;
@ -125,7 +125,7 @@ import jdk.nashorn.internal.runtime.logging.Logger;
public class Parser extends AbstractParser implements Loggable { public class Parser extends AbstractParser implements Loggable {
private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName(); private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
/** Current script environment. */ /** Current env. */
private final ScriptEnvironment env; private final ScriptEnvironment env;
/** Is scripting mode. */ /** Is scripting mode. */
@ -154,7 +154,7 @@ public class Parser extends AbstractParser implements Loggable {
* @param errors error manager * @param errors error manager
*/ */
public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) { public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
this(env, source, errors, env._strict); this(env, source, errors, env._strict, null);
} }
/** /**
@ -164,9 +164,10 @@ public class Parser extends AbstractParser implements Loggable {
* @param source source to parse * @param source source to parse
* @param errors error manager * @param errors error manager
* @param strict strict * @param strict strict
* @param log debug logger if one is needed
*/ */
public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict) { public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) {
this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0); this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0, log);
} }
/** /**
@ -178,8 +179,9 @@ public class Parser extends AbstractParser implements Loggable {
* @param strict parser created with strict mode enabled. * @param strict parser created with strict mode enabled.
* @param nextFunctionId starting value for assigning new unique ids to function nodes * @param nextFunctionId starting value for assigning new unique ids to function nodes
* @param lineOffset line offset to start counting lines from * @param lineOffset line offset to start counting lines from
* @param log debug logger if one is needed
*/ */
public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int nextFunctionId, final int lineOffset) { public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int nextFunctionId, final int lineOffset, final DebugLogger log) {
super(source, errors, strict, lineOffset); super(source, errors, strict, lineOffset);
this.env = env; this.env = env;
this.namespace = new Namespace(env.getNamespace()); this.namespace = new Namespace(env.getNamespace());
@ -199,7 +201,7 @@ public class Parser extends AbstractParser implements Loggable {
this.lineInfoReceiver = null; this.lineInfoReceiver = null;
} }
this.log = !Global.hasInstance() ? DebugLogger.DISABLED_LOGGER : initLogger(Global.instance()); this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
} }
@Override @Override
@ -208,8 +210,8 @@ public class Parser extends AbstractParser implements Loggable {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return context.getLogger(this.getClass());
} }
/** /**

View file

@ -691,8 +691,14 @@ public class AccessorProperty extends Property {
private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) { private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
if (Global.hasInstance()) { if (!Global.hasInstance()) {
return Global.instance().addLoggingToHandle( return mh;
}
final Context context = Context.getContextTrusted();
assert context != null;
return context.addLoggingToHandle(
ObjectClassGenerator.class, ObjectClassGenerator.class,
Level.INFO, Level.INFO,
mh, mh,
@ -706,13 +712,15 @@ public class AccessorProperty extends Property {
}); });
} }
return mh; private MethodHandle debugReplace(final Class<?> oldType, final Class<?> newType, final PropertyMap oldMap, final PropertyMap newMap) {
if (!Global.hasInstance()) {
return REPLACE_MAP;
} }
private MethodHandle debugReplace(final Class<?> oldType, final Class<?> newType, final PropertyMap oldMap, final PropertyMap newMap) { final Context context = Context.getContextTrusted();
if (Global.hasInstance()) { assert context != null;
final Global global = Global.instance();
MethodHandle mh = global.addLoggingToHandle( MethodHandle mh = context.addLoggingToHandle(
ObjectClassGenerator.class, ObjectClassGenerator.class,
REPLACE_MAP, REPLACE_MAP,
new Supplier<String>() { new Supplier<String>() {
@ -722,7 +730,7 @@ public class AccessorProperty extends Property {
} }
}); });
mh = global.addLoggingToHandle( mh = context.addLoggingToHandle(
ObjectClassGenerator.class, ObjectClassGenerator.class,
Level.FINEST, Level.FINEST,
mh, mh,
@ -737,12 +745,15 @@ public class AccessorProperty extends Property {
return mh; return mh;
} }
return REPLACE_MAP; private static MethodHandle debugInvalidate(final String key, final SwitchPoint sp) {
if (!Global.hasInstance()) {
return INVALIDATE_SP;
} }
private static MethodHandle debugInvalidate(final String key, final SwitchPoint sp) { final Context context = Context.getContextTrusted();
if (Global.hasInstance()) { assert context != null;
return Global.instance().addLoggingToHandle(
return context.addLoggingToHandle(
ObjectClassGenerator.class, ObjectClassGenerator.class,
INVALIDATE_SP, INVALIDATE_SP,
new Supplier<String>() { new Supplier<String>() {
@ -753,9 +764,6 @@ public class AccessorProperty extends Property {
}); });
} }
return INVALIDATE_SP;
}
private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) { private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
return MH.findStatic(LOOKUP, AccessorProperty.class, name, MH.type(rtype, types)); return MH.findStatic(LOOKUP, AccessorProperty.class, name, MH.type(rtype, types));
} }

View file

@ -41,7 +41,6 @@ import java.util.logging.Level;
import jdk.nashorn.internal.codegen.types.ArrayType; import jdk.nashorn.internal.codegen.types.ArrayType;
import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.events.RecompilationEvent; import jdk.nashorn.internal.runtime.events.RecompilationEvent;
import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
@ -72,22 +71,25 @@ final class CompiledFunction {
private boolean applyToCall; private boolean applyToCall;
CompiledFunction(final MethodHandle invoker) { CompiledFunction(final MethodHandle invoker) {
this.invoker = invoker; this(invoker, null);
this.log = Global.instance().getLogger(RecompilableScriptFunctionData.class);
} }
static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) { static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
return new CompiledFunction(MH.insertArguments(invoker, 0, false), return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
} }
CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) { CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
this(invoker); this(invoker, constructor, DebugLogger.DISABLED_LOGGER);
}
CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final DebugLogger log) {
this.invoker = invoker;
this.constructor = constructor; this.constructor = constructor;
this.log = log;
} }
CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) { CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) {
this(invoker); this(invoker, null, functionData.getLogger());
this.flags = flags; this.flags = flags;
if ((flags & FunctionNode.IS_OPTIMISTIC) != 0) { if ((flags & FunctionNode.IS_OPTIMISTIC) != 0) {
optimismInfo = new OptimismInfo(functionData); optimismInfo = new OptimismInfo(functionData);
@ -620,10 +622,11 @@ final class CompiledFunction {
private final RecompilableScriptFunctionData data; private final RecompilableScriptFunctionData data;
private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>(); private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>();
private SwitchPoint optimisticAssumptions; private SwitchPoint optimisticAssumptions;
private final DebugLogger log = Global.instance().getLogger(RecompilableScriptFunctionData.class); private final DebugLogger log;
OptimismInfo(final RecompilableScriptFunctionData data) { OptimismInfo(final RecompilableScriptFunctionData data) {
this.data = data; this.data = data;
this.log = data.getLogger();
newOptimisticAssumptions(); newOptimisticAssumptions();
} }

View file

@ -33,6 +33,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.invoke.MethodHandle;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -46,9 +47,11 @@ import java.security.CodeSource;
import java.security.Permissions; import java.security.Permissions;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import java.util.logging.Level; import java.util.logging.Level;
import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassReader;
@ -62,11 +65,15 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.debug.ASTWriter;
import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.ir.debug.PrintVisitor;
import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.events.RuntimeEvent; import jdk.nashorn.internal.runtime.events.RuntimeEvent;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.options.Options; import jdk.nashorn.internal.runtime.options.Options;
import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
/** /**
* This class manages the global state of execution. Context is immutable. * This class manages the global state of execution. Context is immutable.
@ -196,7 +203,9 @@ public final class Context {
// Trusted code only can call this method. // Trusted code only can call this method.
assert getGlobal() != global; assert getGlobal() != global;
//same code can be cached between globals, then we need to invalidate method handle constants //same code can be cached between globals, then we need to invalidate method handle constants
GlobalConstants.instance(global).invalidateAll(); if (global != null) {
Global.getConstants().invalidateAll();
}
currentGlobal.set(global); currentGlobal.set(global);
} }
@ -383,6 +392,8 @@ public final class Context {
if (env._fullversion) { if (env._fullversion) {
getErr().println("nashorn full version " + Version.fullVersion()); getErr().println("nashorn full version " + Version.fullVersion());
} }
initLoggers();
} }
/** /**
@ -916,14 +927,14 @@ public final class Context {
Class<?> script = findCachedClass(source); Class<?> script = findCachedClass(source);
if (script != null) { if (script != null) {
final DebugLogger log = Global.instance().getLogger(Compiler.class); final DebugLogger log = getLogger(Compiler.class);
if (log.isEnabled()) { if (log.isEnabled()) {
log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile."); log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
} }
return script; return script;
} }
final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse(); final FunctionNode functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
if (errors.hasErrors()) { if (errors.hasErrors()) {
return null; return null;
} }
@ -948,6 +959,7 @@ public final class Context {
final CompilationPhases phases = CompilationEnvironment.CompilationPhases.EAGER; final CompilationPhases phases = CompilationEnvironment.CompilationPhases.EAGER;
final Compiler compiler = new Compiler( final Compiler compiler = new Compiler(
new CompilationEnvironment( new CompilationEnvironment(
this,
phases. phases.
makeOptimistic( makeOptimistic(
ScriptEnvironment.globalOptimistic()), ScriptEnvironment.globalOptimistic()),
@ -1032,4 +1044,79 @@ public final class Context {
classCache.cache(source, clazz); classCache.cache(source, clazz);
} }
} }
// logging
private final Map<String, DebugLogger> loggers = new HashMap<>();
private void initLoggers() {
((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
}
/**
* Get a logger, given a loggable class
* @param clazz a Loggable class
* @return debuglogger associated with that class
*/
public DebugLogger getLogger(final Class<? extends Loggable> clazz) {
final String name = getLoggerName(clazz);
DebugLogger logger = loggers.get(name);
if (logger == null) {
if (!env.hasLogger(name)) {
return DebugLogger.DISABLED_LOGGER;
}
final LoggerInfo info = env._loggers.get(name);
logger = new DebugLogger(name, info.getLevel(), info.isQuiet());
loggers.put(name, logger);
}
return logger;
}
/**
* Given a Loggable class, weave debug info info a method handle for that logger.
* Level.INFO is used
*
* @param clazz loggable
* @param mh method handle
* @param text debug printout to add
*
* @return instrumented method handle, or null if logger not enabled
*/
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final MethodHandle mh, final Supplier<String> text) {
return addLoggingToHandle(clazz, Level.INFO, mh, Integer.MAX_VALUE, false, text);
}
/**
* Given a Loggable class, weave debug info info a method handle for that logger.
*
* @param clazz loggable
* @param level log level
* @param mh method handle
* @param paramStart first parameter to print
* @param printReturnValue should we print the return vaulue?
* @param text debug printout to add
*
* @return instrumented method handle, or null if logger not enabled
*/
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Supplier<String> text) {
final DebugLogger log = getLogger(clazz);
if (log.isEnabled()) {
return MethodHandleFactory.addDebugPrintout(log, level, mh, paramStart, printReturnValue, text.get());
}
return mh;
}
private static String getLoggerName(final Class<?> clazz) {
Class<?> current = clazz;
while (current != null) {
final Logger log = current.getAnnotation(Logger.class);
if (log != null) {
assert !"".equals(log.name());
return log.name();
}
current = current.getSuperclass();
}
assert false;
return null;
}
} }

View file

@ -44,7 +44,6 @@ import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.logging.DebugLogger; import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable; import jdk.nashorn.internal.runtime.logging.Loggable;
@ -71,11 +70,12 @@ import jdk.nashorn.internal.runtime.logging.Logger;
* We can extend this to ScriptObjects in general (GLOBAL_ONLY=false), which requires * We can extend this to ScriptObjects in general (GLOBAL_ONLY=false), which requires
* a receiver guard on the constant getter, but it currently leaks memory and its benefits * a receiver guard on the constant getter, but it currently leaks memory and its benefits
* have not yet been investigated property. * have not yet been investigated property.
*
* As long as all Globals share the same constant instance, we need synchronization
* whenever we access the instance.
*/ */
@Logger(name="const") @Logger(name="const")
public final class GlobalConstants implements Loggable { public final class GlobalConstants implements Loggable {
/** singleton per global */
private static GlobalConstants instance;
/** /**
* Should we only try to link globals as constants, and not generic script objects. * Should we only try to link globals as constants, and not generic script objects.
@ -98,8 +98,12 @@ public final class GlobalConstants implements Loggable {
*/ */
private final Map<String, Access> map = new HashMap<>(); private final Map<String, Access> map = new HashMap<>();
private GlobalConstants(final Global global) { /**
this.log = initLogger(global); * Constructor - used only by global
* @param log logger, or null if none
*/
public GlobalConstants(final DebugLogger log) {
this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
} }
@Override @Override
@ -108,20 +112,8 @@ public final class GlobalConstants implements Loggable {
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context context) {
return global.getLogger(this.getClass()); return DebugLogger.DISABLED_LOGGER;
}
/**
* Return the singleton global constant pool
* @param global global
* @return singleton global constant pool
*/
public static synchronized GlobalConstants instance(final Global global) {
if (instance == null) {
instance = new GlobalConstants(global);
}
return instance;
} }
/** /**
@ -224,7 +216,7 @@ public final class GlobalConstants implements Loggable {
* the same class for a new global, but the builtins and global scoped variables * the same class for a new global, but the builtins and global scoped variables
* will have changed. * will have changed.
*/ */
public void invalidateAll() { public synchronized void invalidateAll() {
log.info("New global created - invalidating all constant callsites without increasing invocation count."); log.info("New global created - invalidating all constant callsites without increasing invocation count.");
for (final Access acc : map.values()) { for (final Access acc : map.values()) {
acc.invalidateUncounted(); acc.invalidateUncounted();
@ -241,7 +233,7 @@ public final class GlobalConstants implements Loggable {
* @return receiver, so this can be used as param filter * @return receiver, so this can be used as param filter
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Object invalidateSwitchPoint(final Object obj, final Access acc) { private synchronized Object invalidateSwitchPoint(final Object obj, final Access acc) {
if (log.isEnabled()) { if (log.isEnabled()) {
log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc); log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc);
} }
@ -259,7 +251,7 @@ public final class GlobalConstants implements Loggable {
return obj; return obj;
} }
private Access getOrCreateSwitchPoint(final String name) { private synchronized Access getOrCreateSwitchPoint(final String name) {
Access acc = map.get(name); Access acc = map.get(name);
if (acc != null) { if (acc != null) {
return acc; return acc;
@ -321,7 +313,7 @@ public final class GlobalConstants implements Loggable {
* *
* @return null if failed to set up constant linkage * @return null if failed to set up constant linkage
*/ */
GuardedInvocation findSetMethod(final FindProperty find, final ScriptObject receiver, final GuardedInvocation inv, final CallSiteDescriptor desc, final LinkRequest request) { synchronized GuardedInvocation findSetMethod(final FindProperty find, final ScriptObject receiver, final GuardedInvocation inv, final CallSiteDescriptor desc, final LinkRequest request) {
if (GLOBAL_ONLY && !isGlobalSetter(receiver, find)) { if (GLOBAL_ONLY && !isGlobalSetter(receiver, find)) {
return null; return null;
} }
@ -365,8 +357,12 @@ public final class GlobalConstants implements Loggable {
* @param c constant value * @param c constant value
* @return method handle (with dummy receiver) that returns this constant * @return method handle (with dummy receiver) that returns this constant
*/ */
private static MethodHandle constantGetter(final Object c) { private MethodHandle constantGetter(final Object c) {
return MH.dropArguments(JSType.unboxConstant(c), 0, Object.class); final MethodHandle mh = MH.dropArguments(JSType.unboxConstant(c), 0, Object.class);
if (log.isEnabled()) {
return MethodHandleFactory.addDebugPrintout(log, Level.FINEST, mh, "getting as constant");
}
return mh;
} }
/** /**
@ -380,7 +376,7 @@ public final class GlobalConstants implements Loggable {
* *
* @return resulting getter, or null if failed to create constant * @return resulting getter, or null if failed to create constant
*/ */
GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc, final LinkRequest request, final String operator) { synchronized GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
if (GLOBAL_ONLY && !find.getOwner().isGlobal()) { if (GLOBAL_ONLY && !find.getOwner().isGlobal()) {
return null; return null;
} }

View file

@ -50,7 +50,6 @@ import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
@ -123,11 +122,14 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
private final Set<String> internalSymbols; private final Set<String> internalSymbols;
private final Context context;
private static final int GET_SET_PREFIX_LENGTH = "*et ".length(); private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
/** /**
* Constructor - public as scripts use it * Constructor - public as scripts use it
* *
* @param context context
* @param functionNode functionNode that represents this function code * @param functionNode functionNode that represents this function code
* @param installer installer for code regeneration versions of this function * @param installer installer for code regeneration versions of this function
* @param allocatorClassName name of our allocator class, will be looked up dynamically if used as a constructor * @param allocatorClassName name of our allocator class, will be looked up dynamically if used as a constructor
@ -138,6 +140,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
* @param internalSymbols internal symbols to method, defined in its scope * @param internalSymbols internal symbols to method, defined in its scope
*/ */
public RecompilableScriptFunctionData( public RecompilableScriptFunctionData(
final Context context,
final FunctionNode functionNode, final FunctionNode functionNode,
final CodeInstaller<ScriptEnvironment> installer, final CodeInstaller<ScriptEnvironment> installer,
final String allocatorClassName, final String allocatorClassName,
@ -151,6 +154,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
Math.min(functionNode.getParameters().size(), MAX_ARITY), Math.min(functionNode.getParameters().size(), MAX_ARITY),
getFlags(functionNode)); getFlags(functionNode));
this.context = context;
this.functionName = functionNode.getName(); this.functionName = functionNode.getName();
this.lineNumber = functionNode.getLineNumber(); this.lineNumber = functionNode.getLineNumber();
this.isDeclared = functionNode.isDeclared(); this.isDeclared = functionNode.isDeclared();
@ -172,7 +176,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
nfn.setParent(this); nfn.setParent(this);
} }
this.log = initLogger(Global.instance()); this.log = initLogger(context);
} }
@Override @Override
@ -181,8 +185,8 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
} }
@Override @Override
public DebugLogger initLogger(final Global global) { public DebugLogger initLogger(final Context ctxt) {
return global.getLogger(this.getClass()); return ctxt.getLogger(this.getClass());
} }
/** /**
@ -331,12 +335,13 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
// NOTE: If we aren't recompiling the top-level program, we decrease functionNodeId 'cause we'll have a synthetic program node // NOTE: If we aren't recompiling the top-level program, we decrease functionNodeId 'cause we'll have a synthetic program node
final int descPosition = Token.descPosition(token); final int descPosition = Token.descPosition(token);
final Parser parser = new Parser( final Parser parser = new Parser(
installer.getOwner(), context.getEnv(),
source, source,
new Context.ThrowErrorManager(), new Context.ThrowErrorManager(),
isStrict(), isStrict(),
functionNodeId - (isProgram ? 0 : 1), functionNodeId - (isProgram ? 0 : 1),
lineNumber - 1); // source starts at line 0, so even though lineNumber is the correct declaration line, back off one to make it exclusive lineNumber - 1,
context.getLogger(Parser.class)); // source starts at line 0, so even though lineNumber is the correct declaration line, back off one to make it exclusive
if (isAnonymous) { if (isAnonymous) {
parser.setFunctionName(functionName); parser.setFunctionName(functionName);
@ -420,6 +425,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
final Compiler compiler = new Compiler( final Compiler compiler = new Compiler(
new CompilationEnvironment( new CompilationEnvironment(
context,
CompilationPhases.EAGER.makeOptimistic(), CompilationPhases.EAGER.makeOptimistic(),
isStrict(), isStrict(),
this, this,
@ -454,6 +460,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
final CompilationPhases phases = CompilationPhases.EAGER; final CompilationPhases phases = CompilationPhases.EAGER;
final Compiler compiler = new Compiler( final Compiler compiler = new Compiler(
new CompilationEnvironment( new CompilationEnvironment(
context,
phases.makeOptimistic(ScriptEnvironment.globalOptimistic()), phases.makeOptimistic(ScriptEnvironment.globalOptimistic()),
isStrict(), isStrict(),
this, this,
@ -744,7 +751,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
public FunctionNode apply(final FunctionNode functionNode) { public FunctionNode apply(final FunctionNode functionNode) {
this.initialFunctionNode = functionNode; this.initialFunctionNode = functionNode;
if (data.isVariableArity()) { if (data.isVariableArity()) {
final ApplySpecialization spec = new ApplySpecialization(data, functionNode, actualCallSiteType); final ApplySpecialization spec = new ApplySpecialization(data.context, data, functionNode, actualCallSiteType);
if (spec.transform()) { if (spec.transform()) {
setTransformedFunctionNode(spec.getFunctionNode()); setTransformedFunctionNode(spec.getFunctionNode());
return transformedFunctionNode; return transformedFunctionNode;

View file

@ -681,7 +681,7 @@ public abstract class ScriptFunction extends ScriptObject {
if (isApplyToCall) { if (isApplyToCall) {
if (isFailedApplyToCall) { if (isFailedApplyToCall) {
//take the real arguments that were passed to a call and force them into the apply instead //take the real arguments that were passed to a call and force them into the apply instead
Global.instance().getLogger(ApplySpecialization.class).info("Collection arguments to revert call to apply in " + appliedFn); Context.getContextTrusted().getLogger(ApplySpecialization.class).info("Collection arguments to revert call to apply in " + appliedFn);
inv = MH.asCollector(inv, Object[].class, realArgCount); inv = MH.asCollector(inv, Object[].class, realArgCount);
} else { } else {
appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint); appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint);

View file

@ -918,7 +918,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (property instanceof UserAccessorProperty) { if (property instanceof UserAccessorProperty) {
((UserAccessorProperty)property).setAccessors(this, getMap(), null); ((UserAccessorProperty)property).setAccessors(this, getMap(), null);
} }
GlobalConstants.instance(Global.instance()).delete(property.getKey()); Global.getConstants().delete(property.getKey());
return true; return true;
} }
} }
@ -1930,7 +1930,7 @@ public abstract class ScriptObject implements PropertyAccess {
} }
} }
final GuardedInvocation cinv = GlobalConstants.instance(Global.instance()).findGetMethod(find, this, desc, request, operator); final GuardedInvocation cinv = Global.getConstants().findGetMethod(find, this, desc, request, operator);
if (cinv != null) { if (cinv != null) {
return cinv; return cinv;
} }
@ -1971,7 +1971,7 @@ public abstract class ScriptObject implements PropertyAccess {
} }
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod, final boolean isScope) { private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod, final boolean isScope) {
Global.instance().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod); Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope); final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true); final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true);
return new GuardedInvocation(invoker, guard); return new GuardedInvocation(invoker, guard);
@ -2121,7 +2121,7 @@ public abstract class ScriptObject implements PropertyAccess {
final GuardedInvocation inv = new SetMethodCreator(this, find, desc, explicitInstanceOfCheck).createGuardedInvocation(); final GuardedInvocation inv = new SetMethodCreator(this, find, desc, explicitInstanceOfCheck).createGuardedInvocation();
final GuardedInvocation cinv = GlobalConstants.instance(Global.instance()).findSetMethod(find, this, inv, desc, request); final GuardedInvocation cinv = Global.getConstants().findSetMethod(find, this, inv, desc, request);
if (cinv != null) { if (cinv != null) {
return cinv; return cinv;
} }

View file

@ -451,7 +451,7 @@ public final class ScriptRuntime {
* @return JSON string representation of AST of the supplied code * @return JSON string representation of AST of the supplied code
*/ */
public static String parse(final String code, final String name, final boolean includeLoc) { public static String parse(final String code, final String name, final boolean includeLoc) {
return JSONWriter.parse(Context.getContextTrusted().getEnv(), code, name, includeLoc); return JSONWriter.parse(Context.getContextTrusted(), code, name, includeLoc);
} }
/** /**

View file

@ -37,15 +37,11 @@ import java.lang.invoke.MethodType;
import java.lang.invoke.SwitchPoint; import java.lang.invoke.SwitchPoint;
import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.DynamicLinker;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger; import jdk.nashorn.internal.runtime.logging.Logger;
/** /**
@ -53,10 +49,7 @@ import jdk.nashorn.internal.runtime.logging.Logger;
* native arrays * native arrays
*/ */
@Logger(name="arrays") @Logger(name="arrays")
public abstract class ContinuousArrayData extends ArrayData implements Loggable { public abstract class ContinuousArrayData extends ArrayData {
/** Logger for array accessor linkage */
protected final DebugLogger log;
private SwitchPoint sp; private SwitchPoint sp;
@ -66,17 +59,6 @@ public abstract class ContinuousArrayData extends ArrayData implements Loggable
*/ */
protected ContinuousArrayData(final long length) { protected ContinuousArrayData(final long length) {
super(length); super(length);
this.log = initLogger(Global.instance());
}
@Override
public DebugLogger getLogger() {
return log;
}
@Override
public DebugLogger initLogger(final Global global) {
return global.getLogger(this.getClass());
} }
private SwitchPoint ensureSwitchPointExists() { private SwitchPoint ensureSwitchPointExists() {
@ -249,10 +231,6 @@ public abstract class ContinuousArrayData extends ArrayData implements Loggable
} }
} }
if (log.isEnabled()) {
log.info(getClass().getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null; return null;
} }
@ -290,10 +268,6 @@ public abstract class ContinuousArrayData extends ArrayData implements Loggable
} }
} }
if (log.isEnabled()) {
log.info(getClass().getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null; return null;
} }
} }

View file

@ -31,7 +31,6 @@ import java.lang.invoke.MethodHandle;
import java.nio.Buffer; import java.nio.Buffer;
import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.DynamicLinker;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.lookup.Lookup;
@ -101,22 +100,22 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
} }
@Override @Override
public void shiftLeft(int by) { public void shiftLeft(final int by) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public ArrayData shiftRight(int by) { public ArrayData shiftRight(final int by) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public ArrayData ensure(long safeIndex) { public ArrayData ensure(final long safeIndex) {
return this; return this;
} }
@Override @Override
public ArrayData shrink(long newLength) { public ArrayData shrink(final long newLength) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -126,17 +125,17 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
} }
@Override @Override
public ArrayData delete(int index) { public ArrayData delete(final int index) {
return this; return this;
} }
@Override @Override
public ArrayData delete(long fromIndex, long toIndex) { public ArrayData delete(final long fromIndex, final long toIndex) {
return this; return this;
} }
@Override @Override
protected ArrayData convert(Class<?> type) { protected ArrayData convert(final Class<?> type) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -146,7 +145,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
} }
@Override @Override
public ArrayData slice(long from, long to) { public ArrayData slice(final long from, final long to) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -190,10 +189,6 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
return inv; return inv;
} }
if (log.isEnabled()) {
log.info(clazz.getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null; return null;
} }
@ -205,10 +200,6 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
return inv; return inv;
} }
if (log.isEnabled()) {
log.info(clazz.getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null; return null;
} }

View file

@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.events;
import java.util.logging.Level; import java.util.logging.Level;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.RewriteException; import jdk.nashorn.internal.runtime.RewriteException;
@ -54,7 +54,7 @@ public final class RecompilationEvent extends RuntimeEvent<RewriteException> {
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) { public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) {
super(level, rewriteException); super(level, rewriteException);
assert Global.instance().getLogger(RecompilableScriptFunctionData.class).isEnabled() : assert Context.getContext().getLogger(RecompilableScriptFunctionData.class).isEnabled() :
"Unit test/instrumentation purpose only: RecompilationEvent instances should not be created without '--log=recompile', or we will leak memory in the general case"; "Unit test/instrumentation purpose only: RecompilationEvent instances should not be created without '--log=recompile', or we will leak memory in the general case";
this.returnValue = returnValue; this.returnValue = returnValue;
} }

View file

@ -178,6 +178,15 @@ public final class DebugLogger {
return isEnabled; return isEnabled;
} }
/**
* Check if the logger is enabled
* @param logger logger to check, null will return false
* @return true if enabled
*/
public static boolean isEnabled(final DebugLogger logger) {
return logger != null && logger.isEnabled();
}
/** /**
* If you want to change the indent level of your logger, call indent with a new position. * If you want to change the indent level of your logger, call indent with a new position.
* Positions start at 0 and are increased by one for a new "tab" * Positions start at 0 and are increased by one for a new "tab"

View file

@ -24,7 +24,7 @@
*/ */
package jdk.nashorn.internal.runtime.logging; package jdk.nashorn.internal.runtime.logging;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context;
/** /**
* Interface implemented by classes that are loggable. * Interface implemented by classes that are loggable.
@ -40,13 +40,13 @@ import jdk.nashorn.internal.objects.Global;
*/ */
public interface Loggable { public interface Loggable {
/** /**
* Initialize a logger, by asking Global to get or create it * Initialize a logger, by asking Context to get or create it
* and then keep it in a table by name * and then keep it in a table by name
* *
* @param global global * @param context context
* @return the initialized logger * @return the initialized logger
*/ */
public DebugLogger initLogger(final Global global); public DebugLogger initLogger(final Context context);
/** /**
* Return the logger in use * Return the logger in use

View file

@ -245,7 +245,7 @@ public class Shell {
// For each file on the command line. // For each file on the command line.
for (final String fileName : files) { for (final String fileName : files) {
final FunctionNode functionNode = new Parser(env, new Source(fileName, new File(fileName)), errors, env._strict).parse(); final FunctionNode functionNode = new Parser(env, new Source(fileName, new File(fileName)), errors, env._strict, FunctionNode.FIRST_FUNCTION_ID, 0, context.getLogger(Parser.class)).parse();
if (errors.getNumberOfErrors() != 0) { if (errors.getNumberOfErrors() != 0) {
return COMPILATION_ERROR; return COMPILATION_ERROR;

View file

@ -154,7 +154,7 @@ public class ParserTest {
}; };
errors.setLimit(0); errors.setLimit(0);
final Source source = new Source(file.getAbsolutePath(), buffer); final Source source = new Source(file.getAbsolutePath(), buffer);
new Parser(context.getEnv(), source, errors, context.getEnv()._strict).parse(); new Parser(context.getEnv(), source, errors, context.getEnv()._strict, null).parse();
if (errors.getNumberOfErrors() > 0) { if (errors.getNumberOfErrors() > 0) {
log("Parse failed: " + file.getAbsolutePath()); log("Parse failed: " + file.getAbsolutePath());
failed++; failed++;