mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8041434: Add synchronization to the common global constants structure
Reviewed-by: attila, hannesw
This commit is contained in:
parent
7bb2546460
commit
e30eb1b6bb
35 changed files with 409 additions and 385 deletions
|
@ -25,6 +25,7 @@ $FLAGS \
|
|||
-cp $CLASSPATH:../build/test/classes/ \
|
||||
jdk.nashorn.tools.Shell ${@}
|
||||
|
||||
#-Djava.security.manager= -Djava.security.policy=$DIR/build/nashorn.policy \
|
||||
#-XX:+ShowHiddenFrames \
|
||||
#-XX:+PrintOptoAssembly \
|
||||
#-XX:-TieredCompilation \
|
||||
|
|
|
@ -48,6 +48,7 @@ import jdk.nashorn.internal.objects.Global;
|
|||
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.Context;
|
||||
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
|
||||
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
|
||||
* "arguments" doesn't escape.
|
||||
*
|
||||
* @param context context
|
||||
* @param data recompilable script function data, which contains e.g. needs callee information
|
||||
* @param functionNode functionNode
|
||||
* @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.functionNode = functionNode;
|
||||
this.actualCallSiteType = actualCallSiteType;
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -123,8 +125,8 @@ public final class ApplySpecialization implements Loggable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,7 +100,6 @@ import jdk.nashorn.internal.ir.WhileNode;
|
|||
import jdk.nashorn.internal.ir.WithNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.TokenType;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.Debug;
|
||||
|
@ -164,7 +163,7 @@ final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> implement
|
|||
this.temporarySymbols = temporarySymbols;
|
||||
this.localDefs = new ArrayDeque<>();
|
||||
this.localUses = new ArrayDeque<>();
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(env.getContext());
|
||||
this.debug = log.isEnabled();
|
||||
}
|
||||
|
||||
|
@ -174,8 +173,8 @@ final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> implement
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -70,7 +70,6 @@ import jdk.nashorn.internal.ir.debug.NashornTextifier;
|
|||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.RewriteException;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
|
||||
|
@ -128,7 +127,7 @@ public class ClassEmitter implements Emitter {
|
|||
protected final ClassWriter cw;
|
||||
|
||||
/** The script environment */
|
||||
protected final ScriptEnvironment env;
|
||||
protected final Context context;
|
||||
|
||||
/** Compile unit class name. */
|
||||
private String unitClassName;
|
||||
|
@ -143,10 +142,8 @@ public class ClassEmitter implements Emitter {
|
|||
* @param env script environment
|
||||
* @param cw ASM classwriter
|
||||
*/
|
||||
private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) {
|
||||
assert env != null;
|
||||
|
||||
this.env = env;
|
||||
private ClassEmitter(final Context context, final ClassWriter cw) {
|
||||
this.context = context;
|
||||
this.cw = cw;
|
||||
this.methodsStarted = new HashSet<>();
|
||||
}
|
||||
|
@ -159,8 +156,8 @@ public class ClassEmitter implements Emitter {
|
|||
* @param superClassName super class name for class
|
||||
* @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) {
|
||||
this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
|
||||
ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
|
||||
this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
|
||||
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 strictMode Should we generate this method in strict mode
|
||||
*/
|
||||
ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) {
|
||||
this(env,
|
||||
ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) {
|
||||
this(context,
|
||||
new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
|
||||
private static final String OBJECT_CLASS = "java/lang/Object";
|
||||
|
||||
|
@ -199,6 +196,10 @@ public class ClassEmitter implements Emitter {
|
|||
defineCommonStatics(strictMode);
|
||||
}
|
||||
|
||||
Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 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 env used for class emission
|
||||
*/
|
||||
ScriptEnvironment getEnv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call back from MethodEmitter for method start
|
||||
*
|
||||
|
|
|
@ -240,7 +240,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
|||
super(new CodeGeneratorLexicalContext());
|
||||
this.compiler = compiler;
|
||||
this.callSiteFlags = compiler.getEnv()._callsite_flags;
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(compiler.getCompilationEnvironment().getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -249,8 +249,8 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.AccessNode;
|
||||
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.Optimistic;
|
||||
import jdk.nashorn.internal.objects.NativeArray;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.FindProperty;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
|
@ -57,6 +59,8 @@ public final class CompilationEnvironment {
|
|||
private final CompilationPhases phases;
|
||||
private final boolean optimistic;
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final ParamTypeMap paramTypes;
|
||||
|
||||
private RecompilableScriptFunctionData compiledFunction;
|
||||
|
@ -176,17 +180,21 @@ public final class CompilationEnvironment {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context context
|
||||
* @param phases compilation phases
|
||||
* @param strict strict mode
|
||||
*/
|
||||
public CompilationEnvironment(
|
||||
final Context context,
|
||||
final CompilationPhases phases,
|
||||
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
|
||||
*
|
||||
* @param context context
|
||||
* @param phases compilation phases
|
||||
* @param strict strict mode
|
||||
* @param compiledFunction the function being compiled
|
||||
|
@ -200,6 +208,7 @@ public final class CompilationEnvironment {
|
|||
* @param onDemand is this an on demand compilation
|
||||
*/
|
||||
public CompilationEnvironment(
|
||||
final Context context,
|
||||
final CompilationPhases phases,
|
||||
final boolean strict,
|
||||
final RecompilableScriptFunctionData compiledFunction,
|
||||
|
@ -208,11 +217,13 @@ public final class CompilationEnvironment {
|
|||
final Map<Integer, Type> invalidatedProgramPoints,
|
||||
final int[] continuationEntryPoint,
|
||||
final boolean onDemand) {
|
||||
this(phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, continuationEntryPoint, strict, onDemand);
|
||||
this(context, phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, continuationEntryPoint, strict, onDemand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context context
|
||||
* @param phases compilation phases
|
||||
* @param strict strict mode
|
||||
* @param compiledFunction recompiled function
|
||||
|
@ -225,6 +236,7 @@ public final class CompilationEnvironment {
|
|||
* @param onDemand is this an on demand compilation
|
||||
*/
|
||||
public CompilationEnvironment(
|
||||
final Context context,
|
||||
final CompilationPhases phases,
|
||||
final boolean strict,
|
||||
final RecompilableScriptFunctionData compiledFunction,
|
||||
|
@ -232,10 +244,11 @@ public final class CompilationEnvironment {
|
|||
final ParamTypeMap paramTypeMap,
|
||||
final Map<Integer, Type> invalidatedProgramPoints,
|
||||
final boolean onDemand) {
|
||||
this(phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, null, strict, onDemand);
|
||||
this(context, phases, paramTypeMap, invalidatedProgramPoints, compiledFunction, runtimeScope, null, strict, onDemand);
|
||||
}
|
||||
|
||||
private CompilationEnvironment(
|
||||
final Context context,
|
||||
final CompilationPhases phases,
|
||||
final ParamTypeMap paramTypes,
|
||||
final Map<Integer, Type> invalidatedProgramPoints,
|
||||
|
@ -244,6 +257,7 @@ public final class CompilationEnvironment {
|
|||
final int[] continuationEntryPoints,
|
||||
final boolean strict,
|
||||
final boolean onDemand) {
|
||||
this.context = context;
|
||||
this.phases = phases;
|
||||
this.paramTypes = paramTypes;
|
||||
this.continuationEntryPoints = continuationEntryPoints;
|
||||
|
@ -261,6 +275,10 @@ public final class CompilationEnvironment {
|
|||
assert !isCompileRestOf() || invalidatedProgramPoints != null && containsAll(invalidatedProgramPoints.keySet(), continuationEntryPoints);
|
||||
}
|
||||
|
||||
Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
private static boolean containsAll(final Set<Integer> set, final int[] array) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (!set.contains(array[i])) {
|
||||
|
|
|
@ -53,7 +53,6 @@ import jdk.nashorn.internal.ir.TemporarySymbols;
|
|||
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
||||
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.Timing;
|
||||
|
||||
|
@ -69,7 +68,7 @@ enum CompilationPhase {
|
|||
CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
|
||||
@Override
|
||||
FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
|
||||
return (FunctionNode)fn.accept(new FoldConstants());
|
||||
return (FunctionNode)fn.accept(new FoldConstants(compiler.getCompilationEnvironment()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,7 +87,7 @@ enum CompilationPhase {
|
|||
LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) {
|
||||
@Override
|
||||
FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
|
||||
return (FunctionNode)fn.accept(new Lower(compiler.getCodeInstaller()));
|
||||
return (FunctionNode)fn.accept(new Lower(compiler));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,7 +190,7 @@ enum CompilationPhase {
|
|||
return fn;
|
||||
}
|
||||
|
||||
FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer());
|
||||
FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer(compiler.getCompilationEnvironment()));
|
||||
final List<ReturnNode> returns = new ArrayList<>();
|
||||
|
||||
newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
|
||||
|
@ -225,7 +224,7 @@ enum CompilationPhase {
|
|||
|
||||
@Override
|
||||
public Node leaveDefault(final Node node) {
|
||||
if(node instanceof Expression) {
|
||||
if (node instanceof Expression) {
|
||||
final Expression expr = (Expression)node;
|
||||
final Symbol symbol = expr.getSymbol();
|
||||
if (symbol != null) {
|
||||
|
@ -238,7 +237,7 @@ enum CompilationPhase {
|
|||
|
||||
final Type rangeType = range.getType();
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +283,7 @@ enum CompilationPhase {
|
|||
FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
|
||||
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) {
|
||||
env.getErr().println(new ASTWriter(newFunctionNode));
|
||||
|
|
|
@ -61,8 +61,8 @@ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
|
|||
import jdk.nashorn.internal.ir.TemporarySymbols;
|
||||
import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
|
||||
import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.CodeInstaller;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
|
@ -150,9 +150,8 @@ public final class Compiler implements Loggable {
|
|||
this.constantData = new ConstantData();
|
||||
this.compileUnits = new TreeSet<>();
|
||||
this.bytecode = new LinkedHashMap<>();
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(compilationEnv.getContext());
|
||||
|
||||
synchronized (Compiler.class) {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
if (!ScriptEnvironment.globalOptimistic()) {
|
||||
|
@ -160,7 +159,6 @@ public final class Compiler implements Loggable {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor - common entry point for generating code.
|
||||
|
@ -177,7 +175,7 @@ public final class Compiler implements Loggable {
|
|||
* @param scriptEnv script environment
|
||||
*/
|
||||
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
|
||||
|
@ -186,8 +184,8 @@ public final class Compiler implements Loggable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
classEmitter.begin();
|
||||
|
|
|
@ -42,9 +42,9 @@ import jdk.nashorn.internal.ir.RuntimeNode.Request;
|
|||
import jdk.nashorn.internal.ir.Symbol;
|
||||
import jdk.nashorn.internal.ir.UnaryNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.Token;
|
||||
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.Loggable;
|
||||
import jdk.nashorn.internal.runtime.logging.Logger;
|
||||
|
@ -66,9 +66,9 @@ final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> implements
|
|||
|
||||
private final DebugLogger log;
|
||||
|
||||
FinalizeTypes() {
|
||||
FinalizeTypes(final CompilationEnvironment env) {
|
||||
super(new LexicalContext());
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(env.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,8 +77,8 @@ final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ import jdk.nashorn.internal.ir.LexicalContext;
|
|||
import jdk.nashorn.internal.ir.Node;
|
||||
import jdk.nashorn.internal.ir.Symbol;
|
||||
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.RecompilableScriptFunctionData;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
|
@ -70,7 +70,7 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
|
|||
super(new LexicalContext());
|
||||
this.compiler = compiler;
|
||||
this.env = compiler.getCompilationEnvironment();
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(compiler.getCompilationEnvironment().getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,8 +79,8 @@ final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Logga
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
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 PropertyMap allocatorMap = PropertyMap.newMap(null, 0, fieldCount, 0);
|
||||
final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
|
||||
compiler.getCompilationEnvironment().getContext(),
|
||||
newFunctionNode,
|
||||
compiler.getCodeInstaller(),
|
||||
allocatorClassName,
|
||||
|
|
|
@ -45,7 +45,7 @@ import jdk.nashorn.internal.ir.TernaryNode;
|
|||
import jdk.nashorn.internal.ir.UnaryNode;
|
||||
import jdk.nashorn.internal.ir.VarNode;
|
||||
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.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
|
@ -60,9 +60,9 @@ final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggabl
|
|||
|
||||
private final DebugLogger log;
|
||||
|
||||
FoldConstants() {
|
||||
FoldConstants(final CompilationEnvironment env) {
|
||||
super(new LexicalContext());
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(env.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,8 +71,8 @@ final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -68,10 +68,10 @@ import jdk.nashorn.internal.ir.WhileNode;
|
|||
import jdk.nashorn.internal.ir.WithNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.Token;
|
||||
import jdk.nashorn.internal.parser.TokenType;
|
||||
import jdk.nashorn.internal.runtime.CodeInstaller;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
|
@ -98,7 +98,7 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
|||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
Lower(final CodeInstaller<?> installer) {
|
||||
Lower(final Compiler compiler) {
|
||||
super(new BlockLexicalContext() {
|
||||
|
||||
@Override
|
||||
|
@ -142,8 +142,8 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
|||
}
|
||||
});
|
||||
|
||||
this.installer = installer;
|
||||
this.log = initLogger(Global.instance());
|
||||
this.installer = compiler.getCodeInstaller();
|
||||
this.log = initLogger(compiler.getCompilationEnvironment().getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,8 +152,8 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -97,10 +97,10 @@ import jdk.nashorn.internal.ir.RuntimeNode;
|
|||
import jdk.nashorn.internal.ir.Symbol;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.ArgumentSetter;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.Debug;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.RewriteException;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
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 */
|
||||
private boolean hasReturn;
|
||||
|
||||
/** The script environment */
|
||||
private final ScriptEnvironment env;
|
||||
/** The context */
|
||||
private final Context context;
|
||||
|
||||
private final List<Type> localVariableTypes = new ArrayList<>();
|
||||
|
||||
|
@ -144,8 +144,8 @@ public class MethodEmitter implements Emitter {
|
|||
static final int LARGE_STRING_THRESHOLD = 32 * 1024;
|
||||
|
||||
/** Debug flag, should we dump all generated bytecode along with stacks? */
|
||||
private final DebugLogger log = Global.instance().getLogger(CodeGenerator.class);
|
||||
private final boolean debug = log.isEnabled();
|
||||
private final DebugLogger log;
|
||||
private final boolean debug;
|
||||
|
||||
/** dump stack on a particular line, or -1 if disabled */
|
||||
private static final int DEBUG_TRACE_LINE;
|
||||
|
@ -193,11 +193,13 @@ public class MethodEmitter implements Emitter {
|
|||
* @param functionNode a function node representing this method
|
||||
*/
|
||||
MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
|
||||
this.env = classEmitter.getEnv();
|
||||
this.context = classEmitter.getContext();
|
||||
this.classEmitter = classEmitter;
|
||||
this.method = method;
|
||||
this.functionNode = functionNode;
|
||||
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
|
||||
*/
|
||||
void lineNumber(final int line) {
|
||||
if (env._debug_lines) {
|
||||
if (context.getEnv()._debug_lines) {
|
||||
debug_label("[LINE]", line);
|
||||
final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label();
|
||||
method.visitLabel(l);
|
||||
|
@ -2385,7 +2387,7 @@ public class MethodEmitter implements Emitter {
|
|||
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);
|
||||
if (DEBUG_TRACE_LINE == linePrefix) {
|
||||
new Throwable().printStackTrace(log.getOutputStream());
|
||||
|
|
|
@ -55,7 +55,6 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.AccessorProperty;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.FunctionScope;
|
||||
|
@ -147,8 +146,7 @@ public final class ObjectClassGenerator implements Loggable {
|
|||
public ObjectClassGenerator(final Context context) {
|
||||
this.context = context;
|
||||
assert context != null;
|
||||
this.log = initLogger(Global.instance());
|
||||
synchronized (ObjectClassGenerator.class) {
|
||||
this.log = initLogger(context);
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
if (OBJECT_FIELDS_ONLY) {
|
||||
|
@ -156,7 +154,6 @@ public final class ObjectClassGenerator implements Loggable {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger getLogger() {
|
||||
|
@ -164,8 +161,8 @@ public final class ObjectClassGenerator implements Loggable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context ctxt) {
|
||||
return ctxt.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,7 +383,7 @@ public final class ObjectClassGenerator implements Loggable {
|
|||
* @return Open class emitter.
|
||||
*/
|
||||
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();
|
||||
|
||||
return classEmitter;
|
||||
|
|
|
@ -47,8 +47,8 @@ import jdk.nashorn.internal.ir.UnaryNode;
|
|||
import jdk.nashorn.internal.ir.VarNode;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
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.Loggable;
|
||||
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<>();
|
||||
|
||||
RangeAnalyzer() {
|
||||
RangeAnalyzer(final CompilationEnvironment env) {
|
||||
super(new LexicalContext());
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(env.getContext());
|
||||
this.func = new Range.Functionality(log);
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,8 @@ final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -70,7 +70,6 @@ import jdk.nashorn.internal.parser.Parser;
|
|||
import jdk.nashorn.internal.parser.TokenType;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ParserException;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
|
||||
/**
|
||||
|
@ -81,14 +80,14 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
|
|||
/**
|
||||
* Returns AST as JSON compatible string.
|
||||
*
|
||||
* @param env script environment to use
|
||||
* @param context context
|
||||
* @param code code to be parsed
|
||||
* @param name name of the code source (used for location)
|
||||
* @param includeLoc tells whether to include location information for nodes or not
|
||||
* @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) {
|
||||
final Parser parser = new Parser(env, new Source(name, code), new Context.ThrowErrorManager(), env._strict);
|
||||
public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
|
||||
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);
|
||||
try {
|
||||
final FunctionNode functionNode = parser.parse(CompilerConstants.PROGRAM.symbolName());
|
||||
|
@ -317,7 +316,7 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean enterBlockStatement(BlockStatement blockStatement) {
|
||||
public boolean enterBlockStatement(final BlockStatement blockStatement) {
|
||||
enterDefault(blockStatement);
|
||||
|
||||
type("BlockStatement");
|
||||
|
@ -337,13 +336,13 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
|
|||
type("ForInStatement");
|
||||
comma();
|
||||
|
||||
Node init = forNode.getInit();
|
||||
final Node init = forNode.getInit();
|
||||
assert init != null;
|
||||
property("left");
|
||||
init.accept(this);
|
||||
comma();
|
||||
|
||||
Node modify = forNode.getModify();
|
||||
final Node modify = forNode.getModify();
|
||||
assert modify != null;
|
||||
property("right");
|
||||
modify.accept(this);
|
||||
|
@ -760,8 +759,8 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
|
|||
final List<CatchNode> guarded = new ArrayList<>();
|
||||
CatchNode unguarded = null;
|
||||
if (catches != null) {
|
||||
for (Node n : catches) {
|
||||
CatchNode cn = (CatchNode)n;
|
||||
for (final Node n : catches) {
|
||||
final CatchNode cn = (CatchNode)n;
|
||||
if (cn.getExceptionCondition() != null) {
|
||||
guarded.add(cn);
|
||||
} else {
|
||||
|
@ -957,9 +956,13 @@ public final class JSONWriter extends NodeVisitor<LexicalContext> {
|
|||
buf.append(key);
|
||||
buf.append("\":");
|
||||
if (value != null) {
|
||||
if (escape) buf.append('"');
|
||||
if (escape) {
|
||||
buf.append('"');
|
||||
}
|
||||
buf.append(value);
|
||||
if (escape) buf.append('"');
|
||||
if (escape) {
|
||||
buf.append('"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.ConsString;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.Debug;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
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 a method handle functionality implementation
|
||||
*/
|
||||
public static synchronized MethodHandleFunctionality getFunctionality() {
|
||||
public static MethodHandleFunctionality getFunctionality() {
|
||||
return FUNC;
|
||||
}
|
||||
|
||||
|
@ -286,8 +286,8 @@ public final class MethodHandleFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return this.log = global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return this.log = context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,15 +44,13 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.internal.codegen.ApplySpecialization;
|
||||
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
||||
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.Property;
|
||||
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.linker.Bootstrap;
|
||||
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.logging.DebugLogger;
|
||||
import jdk.nashorn.internal.runtime.logging.Logger;
|
||||
import jdk.nashorn.internal.runtime.logging.Loggable;
|
||||
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
|
||||
private final Context context;
|
||||
|
||||
// logging
|
||||
private final Map<String, DebugLogger> loggers = new HashMap<>();
|
||||
|
||||
private void initLoggers() {
|
||||
((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
|
||||
}
|
||||
// global constants for this global - they can be replaced with MethodHandle.constant until invalidated
|
||||
private static AtomicReference<GlobalConstants> gcsInstance = new AtomicReference<>();
|
||||
|
||||
@Override
|
||||
protected Context getContext() {
|
||||
|
@ -479,8 +469,11 @@ public final class Global extends ScriptObject implements Scope {
|
|||
this.context = context;
|
||||
this.setIsScope();
|
||||
this.optimisticFunctionMap = new HashMap<>();
|
||||
final GlobalConstants gc = GlobalConstants.instance(this);
|
||||
gc.invalidateAll();
|
||||
//we can only share one instance of Global constants between globals, or we consume way too much
|
||||
//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 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
|
||||
* @return true if one exists
|
||||
|
@ -1714,8 +1716,6 @@ public final class Global extends ScriptObject implements Scope {
|
|||
// synonym for "arguments" in scripting mode
|
||||
addOwnProperty("$ARG", argumentsFlags, argumentsObject);
|
||||
}
|
||||
|
||||
initLoggers();
|
||||
}
|
||||
|
||||
private void initErrorObjects() {
|
||||
|
@ -2097,7 +2097,7 @@ public final class Global extends ScriptObject implements Scope {
|
|||
public void invalidateReservedName(final String name) {
|
||||
final SwitchPoint sp = getChangeCallback(name);
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
@ -2114,72 +2114,5 @@ public final class Global extends ScriptObject implements Scope {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ public final class NativeFunction {
|
|||
private static void checkFunctionParameters(final String params) {
|
||||
final Source src = new Source("<function>", params);
|
||||
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 {
|
||||
parser.parseFormalParameterList();
|
||||
} catch (final ParserException pe) {
|
||||
|
@ -300,7 +300,7 @@ public final class NativeFunction {
|
|||
private static void checkFunctionBody(final String funcBody) {
|
||||
final Source src = new Source("<function>", funcBody);
|
||||
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 {
|
||||
parser.parseFunctionBody();
|
||||
} catch (final ParserException pe) {
|
||||
|
|
|
@ -105,7 +105,7 @@ import jdk.nashorn.internal.ir.UnaryNode;
|
|||
import jdk.nashorn.internal.ir.VarNode;
|
||||
import jdk.nashorn.internal.ir.WhileNode;
|
||||
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.JSErrorType;
|
||||
import jdk.nashorn.internal.runtime.ParserException;
|
||||
|
@ -125,7 +125,7 @@ import jdk.nashorn.internal.runtime.logging.Logger;
|
|||
public class Parser extends AbstractParser implements Loggable {
|
||||
private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
|
||||
|
||||
/** Current script environment. */
|
||||
/** Current env. */
|
||||
private final ScriptEnvironment env;
|
||||
|
||||
/** Is scripting mode. */
|
||||
|
@ -154,7 +154,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
* @param errors error manager
|
||||
*/
|
||||
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 errors error manager
|
||||
* @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) {
|
||||
this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0);
|
||||
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, log);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,8 +179,9 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
* @param strict parser created with strict mode enabled.
|
||||
* @param nextFunctionId starting value for assigning new unique ids to function nodes
|
||||
* @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);
|
||||
this.env = env;
|
||||
this.namespace = new Namespace(env.getNamespace());
|
||||
|
@ -199,7 +201,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
this.lineInfoReceiver = null;
|
||||
}
|
||||
|
||||
this.log = !Global.hasInstance() ? DebugLogger.DISABLED_LOGGER : initLogger(Global.instance());
|
||||
this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -208,8 +210,8 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return context.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -691,8 +691,14 @@ public class AccessorProperty extends Property {
|
|||
|
||||
|
||||
private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
|
||||
if (Global.hasInstance()) {
|
||||
return Global.instance().addLoggingToHandle(
|
||||
if (!Global.hasInstance()) {
|
||||
return mh;
|
||||
}
|
||||
|
||||
final Context context = Context.getContextTrusted();
|
||||
assert context != null;
|
||||
|
||||
return context.addLoggingToHandle(
|
||||
ObjectClassGenerator.class,
|
||||
Level.INFO,
|
||||
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) {
|
||||
if (Global.hasInstance()) {
|
||||
final Global global = Global.instance();
|
||||
MethodHandle mh = global.addLoggingToHandle(
|
||||
final Context context = Context.getContextTrusted();
|
||||
assert context != null;
|
||||
|
||||
MethodHandle mh = context.addLoggingToHandle(
|
||||
ObjectClassGenerator.class,
|
||||
REPLACE_MAP,
|
||||
new Supplier<String>() {
|
||||
|
@ -722,7 +730,7 @@ public class AccessorProperty extends Property {
|
|||
}
|
||||
});
|
||||
|
||||
mh = global.addLoggingToHandle(
|
||||
mh = context.addLoggingToHandle(
|
||||
ObjectClassGenerator.class,
|
||||
Level.FINEST,
|
||||
mh,
|
||||
|
@ -737,12 +745,15 @@ public class AccessorProperty extends Property {
|
|||
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) {
|
||||
if (Global.hasInstance()) {
|
||||
return Global.instance().addLoggingToHandle(
|
||||
final Context context = Context.getContextTrusted();
|
||||
assert context != null;
|
||||
|
||||
return context.addLoggingToHandle(
|
||||
ObjectClassGenerator.class,
|
||||
INVALIDATE_SP,
|
||||
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) {
|
||||
return MH.findStatic(LOOKUP, AccessorProperty.class, name, MH.type(rtype, types));
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ import java.util.logging.Level;
|
|||
import jdk.nashorn.internal.codegen.types.ArrayType;
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.FunctionNode;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.events.RecompilationEvent;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
|
@ -72,22 +71,25 @@ final class CompiledFunction {
|
|||
private boolean applyToCall;
|
||||
|
||||
CompiledFunction(final MethodHandle invoker) {
|
||||
this.invoker = invoker;
|
||||
this.log = Global.instance().getLogger(RecompilableScriptFunctionData.class);
|
||||
this(invoker, null);
|
||||
}
|
||||
|
||||
static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
|
||||
return new CompiledFunction(MH.insertArguments(invoker, 0, false),
|
||||
createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
|
||||
return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
|
||||
}
|
||||
|
||||
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.log = log;
|
||||
}
|
||||
|
||||
CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) {
|
||||
this(invoker);
|
||||
this(invoker, null, functionData.getLogger());
|
||||
this.flags = flags;
|
||||
if ((flags & FunctionNode.IS_OPTIMISTIC) != 0) {
|
||||
optimismInfo = new OptimismInfo(functionData);
|
||||
|
@ -620,10 +622,11 @@ final class CompiledFunction {
|
|||
private final RecompilableScriptFunctionData data;
|
||||
private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>();
|
||||
private SwitchPoint optimisticAssumptions;
|
||||
private final DebugLogger log = Global.instance().getLogger(RecompilableScriptFunctionData.class);
|
||||
private final DebugLogger log;
|
||||
|
||||
OptimismInfo(final RecompilableScriptFunctionData data) {
|
||||
this.data = data;
|
||||
this.log = data.getLogger();
|
||||
newOptimisticAssumptions();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -46,9 +47,11 @@ import java.security.CodeSource;
|
|||
import java.security.Permissions;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
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.debug.ASTWriter;
|
||||
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.Parser;
|
||||
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
|
||||
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.LoggingOption.LoggerInfo;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
assert getGlobal() != global;
|
||||
//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);
|
||||
}
|
||||
|
||||
|
@ -383,6 +392,8 @@ public final class Context {
|
|||
if (env._fullversion) {
|
||||
getErr().println("nashorn full version " + Version.fullVersion());
|
||||
}
|
||||
|
||||
initLoggers();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -916,14 +927,14 @@ public final class Context {
|
|||
|
||||
Class<?> script = findCachedClass(source);
|
||||
if (script != null) {
|
||||
final DebugLogger log = Global.instance().getLogger(Compiler.class);
|
||||
final DebugLogger log = getLogger(Compiler.class);
|
||||
if (log.isEnabled()) {
|
||||
log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
|
||||
}
|
||||
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()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -948,6 +959,7 @@ public final class Context {
|
|||
final CompilationPhases phases = CompilationEnvironment.CompilationPhases.EAGER;
|
||||
final Compiler compiler = new Compiler(
|
||||
new CompilationEnvironment(
|
||||
this,
|
||||
phases.
|
||||
makeOptimistic(
|
||||
ScriptEnvironment.globalOptimistic()),
|
||||
|
@ -1032,4 +1044,79 @@ public final class Context {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ import jdk.internal.dynalink.linker.GuardedInvocation;
|
|||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.internal.lookup.Lookup;
|
||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||
import jdk.nashorn.internal.runtime.logging.DebugLogger;
|
||||
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
|
||||
* a receiver guard on the constant getter, but it currently leaks memory and its benefits
|
||||
* 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")
|
||||
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.
|
||||
|
@ -98,8 +98,12 @@ public final class GlobalConstants implements Loggable {
|
|||
*/
|
||||
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
|
||||
|
@ -108,20 +112,8 @@ public final class GlobalConstants implements Loggable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public DebugLogger initLogger(final Context context) {
|
||||
return DebugLogger.DISABLED_LOGGER;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,7 +216,7 @@ public final class GlobalConstants implements Loggable {
|
|||
* the same class for a new global, but the builtins and global scoped variables
|
||||
* will have changed.
|
||||
*/
|
||||
public void invalidateAll() {
|
||||
public synchronized void invalidateAll() {
|
||||
log.info("New global created - invalidating all constant callsites without increasing invocation count.");
|
||||
for (final Access acc : map.values()) {
|
||||
acc.invalidateUncounted();
|
||||
|
@ -241,7 +233,7 @@ public final class GlobalConstants implements Loggable {
|
|||
* @return receiver, so this can be used as param filter
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Object invalidateSwitchPoint(final Object obj, final Access acc) {
|
||||
private synchronized Object invalidateSwitchPoint(final Object obj, final Access acc) {
|
||||
if (log.isEnabled()) {
|
||||
log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc);
|
||||
}
|
||||
|
@ -259,7 +251,7 @@ public final class GlobalConstants implements Loggable {
|
|||
return obj;
|
||||
}
|
||||
|
||||
private Access getOrCreateSwitchPoint(final String name) {
|
||||
private synchronized Access getOrCreateSwitchPoint(final String name) {
|
||||
Access acc = map.get(name);
|
||||
if (acc != null) {
|
||||
return acc;
|
||||
|
@ -321,7 +313,7 @@ public final class GlobalConstants implements Loggable {
|
|||
*
|
||||
* @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)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -365,8 +357,12 @@ public final class GlobalConstants implements Loggable {
|
|||
* @param c constant value
|
||||
* @return method handle (with dummy receiver) that returns this constant
|
||||
*/
|
||||
private static MethodHandle constantGetter(final Object c) {
|
||||
return MH.dropArguments(JSType.unboxConstant(c), 0, Object.class);
|
||||
private MethodHandle constantGetter(final Object c) {
|
||||
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
|
||||
*/
|
||||
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()) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ import jdk.nashorn.internal.codegen.types.Type;
|
|||
import jdk.nashorn.internal.ir.FunctionNode;
|
||||
import jdk.nashorn.internal.ir.LexicalContext;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.parser.Parser;
|
||||
import jdk.nashorn.internal.parser.Token;
|
||||
import jdk.nashorn.internal.parser.TokenType;
|
||||
|
@ -123,11 +122,14 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
|
||||
private final Set<String> internalSymbols;
|
||||
|
||||
private final Context context;
|
||||
|
||||
private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
|
||||
|
||||
/**
|
||||
* Constructor - public as scripts use it
|
||||
*
|
||||
* @param context context
|
||||
* @param functionNode functionNode that represents this function code
|
||||
* @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
|
||||
|
@ -138,6 +140,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
* @param internalSymbols internal symbols to method, defined in its scope
|
||||
*/
|
||||
public RecompilableScriptFunctionData(
|
||||
final Context context,
|
||||
final FunctionNode functionNode,
|
||||
final CodeInstaller<ScriptEnvironment> installer,
|
||||
final String allocatorClassName,
|
||||
|
@ -151,6 +154,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
Math.min(functionNode.getParameters().size(), MAX_ARITY),
|
||||
getFlags(functionNode));
|
||||
|
||||
this.context = context;
|
||||
this.functionName = functionNode.getName();
|
||||
this.lineNumber = functionNode.getLineNumber();
|
||||
this.isDeclared = functionNode.isDeclared();
|
||||
|
@ -172,7 +176,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
nfn.setParent(this);
|
||||
}
|
||||
|
||||
this.log = initLogger(Global.instance());
|
||||
this.log = initLogger(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -181,8 +185,8 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebugLogger initLogger(final Global global) {
|
||||
return global.getLogger(this.getClass());
|
||||
public DebugLogger initLogger(final Context ctxt) {
|
||||
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
|
||||
final int descPosition = Token.descPosition(token);
|
||||
final Parser parser = new Parser(
|
||||
installer.getOwner(),
|
||||
context.getEnv(),
|
||||
source,
|
||||
new Context.ThrowErrorManager(),
|
||||
isStrict(),
|
||||
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) {
|
||||
parser.setFunctionName(functionName);
|
||||
|
@ -420,6 +425,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
|
||||
final Compiler compiler = new Compiler(
|
||||
new CompilationEnvironment(
|
||||
context,
|
||||
CompilationPhases.EAGER.makeOptimistic(),
|
||||
isStrict(),
|
||||
this,
|
||||
|
@ -454,6 +460,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
final CompilationPhases phases = CompilationPhases.EAGER;
|
||||
final Compiler compiler = new Compiler(
|
||||
new CompilationEnvironment(
|
||||
context,
|
||||
phases.makeOptimistic(ScriptEnvironment.globalOptimistic()),
|
||||
isStrict(),
|
||||
this,
|
||||
|
@ -744,7 +751,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||
public FunctionNode apply(final FunctionNode functionNode) {
|
||||
this.initialFunctionNode = functionNode;
|
||||
if (data.isVariableArity()) {
|
||||
final ApplySpecialization spec = new ApplySpecialization(data, functionNode, actualCallSiteType);
|
||||
final ApplySpecialization spec = new ApplySpecialization(data.context, data, functionNode, actualCallSiteType);
|
||||
if (spec.transform()) {
|
||||
setTransformedFunctionNode(spec.getFunctionNode());
|
||||
return transformedFunctionNode;
|
||||
|
|
|
@ -681,7 +681,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||
if (isApplyToCall) {
|
||||
if (isFailedApplyToCall) {
|
||||
//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);
|
||||
} else {
|
||||
appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint);
|
||||
|
|
|
@ -918,7 +918,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||
if (property instanceof UserAccessorProperty) {
|
||||
((UserAccessorProperty)property).setAccessors(this, getMap(), null);
|
||||
}
|
||||
GlobalConstants.instance(Global.instance()).delete(property.getKey());
|
||||
Global.getConstants().delete(property.getKey());
|
||||
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) {
|
||||
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) {
|
||||
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 guard = getScriptObjectGuard(desc.getMethodType(), true);
|
||||
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 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) {
|
||||
return cinv;
|
||||
}
|
||||
|
|
|
@ -451,7 +451,7 @@ public final class ScriptRuntime {
|
|||
* @return JSON string representation of AST of the supplied code
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,15 +37,11 @@ import java.lang.invoke.MethodType;
|
|||
import java.lang.invoke.SwitchPoint;
|
||||
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.DynamicLinker;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.internal.lookup.Lookup;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -53,10 +49,7 @@ import jdk.nashorn.internal.runtime.logging.Logger;
|
|||
* native arrays
|
||||
*/
|
||||
@Logger(name="arrays")
|
||||
public abstract class ContinuousArrayData extends ArrayData implements Loggable {
|
||||
|
||||
/** Logger for array accessor linkage */
|
||||
protected final DebugLogger log;
|
||||
public abstract class ContinuousArrayData extends ArrayData {
|
||||
|
||||
private SwitchPoint sp;
|
||||
|
||||
|
@ -66,17 +59,6 @@ public abstract class ContinuousArrayData extends ArrayData implements Loggable
|
|||
*/
|
||||
protected ContinuousArrayData(final long 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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.lang.invoke.MethodHandle;
|
|||
import java.nio.Buffer;
|
||||
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.DynamicLinker;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.internal.lookup.Lookup;
|
||||
|
@ -101,22 +100,22 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||
}
|
||||
|
||||
@Override
|
||||
public void shiftLeft(int by) {
|
||||
public void shiftLeft(final int by) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData shiftRight(int by) {
|
||||
public ArrayData shiftRight(final int by) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData ensure(long safeIndex) {
|
||||
public ArrayData ensure(final long safeIndex) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData shrink(long newLength) {
|
||||
public ArrayData shrink(final long newLength) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -126,17 +125,17 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||
}
|
||||
|
||||
@Override
|
||||
public ArrayData delete(int index) {
|
||||
public ArrayData delete(final int index) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData delete(long fromIndex, long toIndex) {
|
||||
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayData convert(Class<?> type) {
|
||||
protected ArrayData convert(final Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -146,7 +145,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||
}
|
||||
|
||||
@Override
|
||||
public ArrayData slice(long from, long to) {
|
||||
public ArrayData slice(final long from, final long to) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -190,10 +189,6 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||
return inv;
|
||||
}
|
||||
|
||||
if (log.isEnabled()) {
|
||||
log.info(clazz.getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -205,10 +200,6 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||
return inv;
|
||||
}
|
||||
|
||||
if (log.isEnabled()) {
|
||||
log.info(clazz.getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.events;
|
|||
|
||||
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.RewriteException;
|
||||
|
||||
|
@ -54,7 +54,7 @@ public final class RecompilationEvent extends RuntimeEvent<RewriteException> {
|
|||
@SuppressWarnings("javadoc")
|
||||
public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) {
|
||||
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";
|
||||
this.returnValue = returnValue;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,15 @@ public final class DebugLogger {
|
|||
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.
|
||||
* Positions start at 0 and are increased by one for a new "tab"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
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.
|
||||
|
@ -40,13 +40,13 @@ import jdk.nashorn.internal.objects.Global;
|
|||
*/
|
||||
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
|
||||
*
|
||||
* @param global global
|
||||
* @param context context
|
||||
* @return the initialized logger
|
||||
*/
|
||||
public DebugLogger initLogger(final Global global);
|
||||
public DebugLogger initLogger(final Context context);
|
||||
|
||||
/**
|
||||
* Return the logger in use
|
||||
|
|
|
@ -245,7 +245,7 @@ public class Shell {
|
|||
|
||||
// For each file on the command line.
|
||||
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) {
|
||||
return COMPILATION_ERROR;
|
||||
|
|
|
@ -154,7 +154,7 @@ public class ParserTest {
|
|||
};
|
||||
errors.setLimit(0);
|
||||
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) {
|
||||
log("Parse failed: " + file.getAbsolutePath());
|
||||
failed++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue