8038426: Move all loggers from process wide scope into Global scope
Reviewed-by: attila, hannesw
--- a/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java Wed Apr 23 16:13:47 2014 +0200
@@ -45,7 +45,9 @@
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global;
-import jdk.nashorn.internal.runtime.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.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.options.Options;
@@ -80,7 +82,8 @@
* </pre>
*/
-public final class ApplySpecialization {
+@Logger(name="apply2call")
+public final class ApplySpecialization implements Loggable {
private static final boolean USE_APPLY2CALL = Options.getBooleanProperty("nashorn.apply2call", true);
@@ -90,7 +93,7 @@
private final MethodType actualCallSiteType;
- private static final DebugLogger LOG = new DebugLogger("apply2call");
+ private final DebugLogger log;
private static final String ARGUMENTS = ARGUMENTS_VAR.symbolName();
@@ -99,14 +102,6 @@
private boolean finished;
/**
- * Return the apply to call specialization logger g
- * @return the logger
- */
- public static DebugLogger getLogger() {
- return LOG;
- }
-
- /**
* Apply specialization optimization. Try to explode arguments and call
* applies as calls if they just pass on the "arguments" array and
* "arguments" doesn't escape.
@@ -116,9 +111,20 @@
* @param actualCallSiteType actual call site type that we use (not Object[] varargs)
*/
public ApplySpecialization(final RecompilableScriptFunctionData data, final FunctionNode functionNode, final MethodType actualCallSiteType) {
- this.data = data;
- this.functionNode = functionNode;
+ this.data = data;
+ this.functionNode = functionNode;
this.actualCallSiteType = actualCallSiteType;
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
/**
@@ -176,7 +182,7 @@
}
});
} catch (final UnsupportedOperationException e) {
- LOG.fine("'arguments' escapes, is not used in standard call dispatch, or is reassigned in '" + functionNode.getName() + "'. Aborting");
+ log.fine("'arguments' escapes, is not used in standard call dispatch, or is reassigned in '" + functionNode.getName() + "'. Aborting");
return true; //bad
}
@@ -204,7 +210,7 @@
changed = false;
if (!Global.instance().isSpecialNameValid("apply")) {
- LOG.fine("Apply transform disabled: apply/call overridden");
+ log.fine("Apply transform disabled: apply/call overridden");
assert !Global.instance().isSpecialNameValid("call") : "call and apply should have the same SwitchPoint";
return finish();
}
@@ -251,7 +257,7 @@
changed = true;
final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall();
- LOG.fine("Transformed " + callNode + " from apply to call => " + newCallNode + " in '" + functionNode.getName() + "'");
+ log.fine("Transformed " + callNode + " from apply to call => " + newCallNode + " in '" + functionNode.getName() + "'");
return newCallNode;
}
@@ -265,7 +271,7 @@
setParameters(null, newParams);
}
- LOG.info("Successfully specialized apply to call in '" + functionNode.getName() + "' id=" + functionNode.getId() + " signature=" + actualCallSiteType);
+ log.info("Successfully specialized apply to call in '" + functionNode.getName() + "' id=" + functionNode.getId() + " signature=" + actualCallSiteType);
return finish();
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Wed Apr 23 16:13:47 2014 +0200
@@ -59,6 +59,7 @@
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.BinaryNode;
@@ -99,13 +100,16 @@
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;
-import jdk.nashorn.internal.runtime.DebugLogger;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* This is the attribution pass of the code generator. Attr takes Lowered IR,
@@ -121,8 +125,8 @@
* but in general, this is where the main symbol type information is
* computed.
*/
-
-final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> {
+@Logger(name="Attr")
+final class Attr extends NodeOperatorVisitor<OptimisticLexicalContext> implements Loggable {
private final CompilationEnvironment env;
@@ -146,8 +150,8 @@
private int catchNestingLevel;
- private static final DebugLogger LOG = new DebugLogger("attr");
- private static final boolean DEBUG = LOG.isEnabled();
+ private final DebugLogger log;
+ private final boolean debug;
private final TemporarySymbols temporarySymbols;
@@ -160,6 +164,18 @@
this.temporarySymbols = temporarySymbols;
this.localDefs = new ArrayDeque<>();
this.localUses = new ArrayDeque<>();
+ this.log = initLogger(Global.instance());
+ this.debug = log.isEnabled();
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
@Override
@@ -564,7 +580,7 @@
if (newFunctionNode.usesSelfSymbol()) {
syntheticInitializers = new ArrayList<>(2);
- LOG.info("Accepting self symbol init for ", newFunctionNode.getName());
+ log.info("Accepting self symbol init for ", newFunctionNode.getName());
// "var fn = :callee"
syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode));
}
@@ -628,8 +644,8 @@
if (identNode.isPropertyName()) {
// assign a pseudo symbol to property name
final Symbol pseudoSymbol = pseudoSymbol(name);
- LOG.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol);
- LOG.unindent();
+ log.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol);
+ log.unindent();
return end(identNode.setSymbol(lc, pseudoSymbol));
}
@@ -639,7 +655,7 @@
//If an existing symbol with the name is found, use that otherwise, declare a new one
if (symbol != null) {
- LOG.info("Existing symbol = ", symbol);
+ log.info("Existing symbol = ", symbol);
if (symbol.isFunctionSelf()) {
final FunctionNode functionNode = lc.getDefiningFunction(symbol);
assert functionNode != null;
@@ -667,7 +683,7 @@
// if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
maybeForceScope(symbol);
} else {
- LOG.info("No symbol exists. Declare undefined: ", symbol);
+ log.info("No symbol exists. Declare undefined: ", symbol);
symbol = defineGlobalSymbol(block, name);
// we have never seen this before, it can be undefined
newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway?
@@ -1686,7 +1702,7 @@
final Type callSiteParamType = env.getParamType(functionNode, pos);
if (callSiteParamType != null) {
- LOG.info("Callsite type override for parameter " + pos + " " + paramSymbol + " => " + callSiteParamType);
+ log.info("Callsite type override for parameter " + pos + " " + paramSymbol + " => " + callSiteParamType);
newType(paramSymbol, callSiteParamType);
} else {
// When we're using optimistic compilation, we'll generate specialized versions of the functions anyway
@@ -1699,7 +1715,7 @@
// with Type.UNKNOWN.
newType(paramSymbol, isOptimistic ? Type.OBJECT : Type.UNKNOWN);
}
- LOG.info("Initialized param ", pos, "=", paramSymbol);
+ log.info("Initialized param ", pos, "=", paramSymbol);
pos++;
}
@@ -1771,7 +1787,7 @@
final String key = property.getKey();
final Symbol symbol = defineGlobalSymbol(block, key);
newType(symbol, Type.OBJECT);
- LOG.info("Added global symbol from property map ", symbol);
+ log.info("Added global symbol from property map ", symbol);
}
}
@@ -1811,8 +1827,8 @@
}
final Type from = node.getType();
if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) {
- if (LOG.isEnabled()) {
- LOG.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to);
+ if (log.isEnabled()) {
+ log.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to);
}
Symbol symbol = node.getSymbol();
if (symbol.isShared() && symbol.wouldChangeType(to)) {
@@ -1983,7 +1999,7 @@
}
private Expression ensureSymbol(final Expression expr, final Type type) {
- LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type);
+ log.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type);
return temporarySymbols.ensureSymbol(lc, type, expr);
}
@@ -2030,14 +2046,14 @@
*/
private void tagNeverOptimistic(final Expression expr) {
if (expr instanceof Optimistic) {
- LOG.info("Tagging TypeOverride node '" + expr + "' never optimistic");
+ log.info("Tagging TypeOverride node '" + expr + "' never optimistic");
neverOptimistic.add(tag((Optimistic)expr));
}
}
private void tagOptimistic(final Expression expr) {
if (expr instanceof Optimistic) {
- LOG.info("Tagging TypeOverride node '" + expr + "' as optimistic");
+ log.info("Tagging TypeOverride node '" + expr + "' as optimistic");
optimistic.add(tag((Optimistic)expr));
}
}
@@ -2106,7 +2122,7 @@
expr = (T)expr.setSymbol(lc, symbol.createUnshared(symbol.getName()));
}
}
- LOG.fine(expr, " turned optimistic with type=", optimisticType);
+ log.fine(expr, " turned optimistic with type=", optimisticType);
assert ((Optimistic)expr).isOptimistic();
}
}
@@ -2118,17 +2134,17 @@
return defineSymbol(lc.getCurrentBlock(), name, IS_VAR | IS_INTERNAL).setType(type); //NASHORN-73
}
- private static void newType(final Symbol symbol, final Type type) {
+ private void newType(final Symbol symbol, final Type type) {
final Type oldType = symbol.getSymbolType();
symbol.setType(type);
if (symbol.getSymbolType() != oldType) {
- LOG.info("New TYPE ", type, " for ", symbol," (was ", oldType, ")");
+ log.info("New TYPE ", type, " for ", symbol," (was ", oldType, ")");
}
if (symbol.isParam()) {
symbol.setType(type);
- LOG.info("Param type change ", symbol);
+ log.info("Param type change ", symbol);
}
}
@@ -2156,12 +2172,12 @@
}
private void addLocalDef(final String name) {
- LOG.info("Adding local def of symbol: '", name, "'");
+ log.info("Adding local def of symbol: '", name, "'");
localDefs.peek().add(name);
}
private void removeLocalDef(final String name) {
- LOG.info("Removing local def of symbol: '", name, "'");
+ log.info("Removing local def of symbol: '", name, "'");
localDefs.peek().remove(name);
}
@@ -2170,7 +2186,7 @@
}
private void addLocalUse(final String name) {
- LOG.info("Adding local use of symbol: '", name, "'");
+ log.info("Adding local use of symbol: '", name, "'");
localUses.peek().add(name);
}
@@ -2183,7 +2199,7 @@
return;
}
if (symbolType != type) {
- LOG.info("Infer parameter type " + symbol + " ==> " + type + " " + lc.getCurrentFunction().getSource().getName() + " " + lc.getCurrentFunction().getName());
+ log.info("Infer parameter type " + symbol + " ==> " + type + " " + lc.getCurrentFunction().getSource().getName() + " " + lc.getCurrentFunction().getName());
}
symbol.setType(type); //will be overwritten by object later if pessimistic anyway
lc.logOptimisticAssumption(symbol, type);
@@ -2230,7 +2246,7 @@
}
private boolean start(final Node node, final boolean printNode) {
- if (DEBUG) {
+ if (debug) {
final StringBuilder sb = new StringBuilder();
sb.append("[ENTER ").
@@ -2240,8 +2256,8 @@
append(" in '").
append(lc.getCurrentFunction().getName()).
append("'");
- LOG.info(sb);
- LOG.indent();
+ log.info(sb);
+ log.indent();
}
return true;
@@ -2256,7 +2272,7 @@
// If we're done with a statement, all temporaries can be reused.
temporarySymbols.reuse();
}
- if (DEBUG) {
+ if (debug) {
final StringBuilder sb = new StringBuilder();
sb.append("[LEAVE ").
@@ -2276,8 +2292,8 @@
}
}
- LOG.unindent();
- LOG.info(sb);
+ log.unindent();
+ log.info(sb);
}
return node;
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Apr 23 16:13:47 2014 +0200
@@ -133,7 +133,6 @@
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug;
-import jdk.nashorn.internal.runtime.DebugLogger;
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
@@ -149,6 +148,9 @@
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+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;
/**
@@ -170,7 +172,8 @@
* The CodeGenerator visits nodes only once, tags them as resolved and emits
* bytecode for them.
*/
-final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> {
+@Logger(name="codegen")
+final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> implements Loggable {
private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class);
@@ -214,7 +217,7 @@
/** Current compile unit */
private CompileUnit unit;
- private static final DebugLogger LOG = new DebugLogger("codegen", "nashorn.codegen.debug");
+ private final DebugLogger log;
/** From what size should we use spill instead of fields for JavaScript objects? */
private static final int OBJECT_SPILL_THRESHOLD = Options.getIntProperty("nashorn.spill.threshold", 256);
@@ -237,6 +240,17 @@
super(new CodeGeneratorLexicalContext());
this.compiler = compiler;
this.callSiteFlags = compiler.getEnv()._callsite_flags;
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
/**
@@ -1511,7 +1525,7 @@
// exact type closure and deduplicate based on that, or just decide that functions in finally blocks aren't
// worth it, and generate one method with most generic type closure.
if (!emittedMethods.contains(fnName)) {
- LOG.info("=== BEGIN ", fnName);
+ log.info("=== BEGIN ", fnName);
assert functionNode.getCompileUnit() != null : "no compile unit for " + fnName + " " + Debug.id(functionNode);
unit = lc.pushCompileUnit(functionNode.getCompileUnit());
@@ -1550,7 +1564,7 @@
method.end(); // wrap up this method
unit = lc.popCompileUnit(functionNode.getCompileUnit());
method = lc.popMethodEmitter(method);
- LOG.info("=== END ", functionNode.getName());
+ log.info("=== END ", functionNode.getName());
} else {
markOptimistic = false;
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed Apr 23 16:13:47 2014 +0200
@@ -1,6 +1,30 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
package jdk.nashorn.internal.codegen;
-import static jdk.nashorn.internal.codegen.Compiler.info;
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.ATTR;
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED;
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED;
@@ -29,6 +53,7 @@
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;
@@ -128,7 +153,7 @@
accept(new Attr(compiler.getCompilationEnvironment(), ts));
if (compiler.getEnv()._print_mem_usage) {
- info("Attr temporary symbol count:", ts.getTotalSymbolCount());
+ compiler.getLogger().info("Attr temporary symbol count:", ts.getTotalSymbolCount());
}
return newFunctionNode;
@@ -213,7 +238,7 @@
final Type rangeType = range.getType();
if (!rangeType.isUnknown() && !Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
- RangeAnalyzer.LOG.info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
+ Global.instance().getLogger(RangeAnalyzer.class).info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
return expr.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
}
}
@@ -332,7 +357,7 @@
compiler.getCodeInstaller().verify(bytecode);
}
- DumpBytecode.dumpBytecode(env, bytecode, className);
+ DumpBytecode.dumpBytecode(env, compiler, bytecode, className);
}
return newFunctionNode;
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Wed Apr 23 16:13:47 2014 +0200
@@ -51,6 +51,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
+
import jdk.internal.dynalink.support.NameCodec;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
import jdk.nashorn.internal.codegen.CompilationEnvironment.CompilationPhases;
@@ -60,12 +61,15 @@
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.DebugLogger;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.Timing;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Responsible for converting JavaScripts to java byte code. Main entry
@@ -73,7 +77,8 @@
* predefined Code installation policy, given to it at construction time.
* @see CodeInstaller
*/
-public final class Compiler {
+@Logger(name="compiler")
+public final class Compiler implements Loggable {
/** Name of the scripts package */
public static final String SCRIPTS_PACKAGE = "jdk/nashorn/internal/scripts";
@@ -104,21 +109,9 @@
/** logger for compiler, trampolines, splits and related code generation events
* that affect classes */
- private static final DebugLogger LOG = new DebugLogger("compiler");
+ private final DebugLogger log;
- /**
- * Get the logger used for this compiler
- * @return logger
- */
- public static DebugLogger getLogger() {
- return LOG;
- }
-
- static {
- if (!ScriptEnvironment.globalOptimistic()) {
- LOG.warning("Running without optimistic types. This is a configuration that may be deprecated.");
- }
- }
+ private static boolean initialized = false;
/**
* This array contains names that need to be reserved at the start
@@ -157,6 +150,16 @@
this.constantData = new ConstantData();
this.compileUnits = new TreeSet<>();
this.bytecode = new LinkedHashMap<>();
+ this.log = initLogger(Global.instance());
+
+ synchronized (Compiler.class) {
+ if (!initialized) {
+ initialized = true;
+ if (!ScriptEnvironment.globalOptimistic()) {
+ log.warning("Running without optimistic types. This is a configuration that may be deprecated.");
+ }
+ }
+ }
}
/**
@@ -177,12 +180,22 @@
this(new CompilationEnvironment(CompilationPhases.EAGER, scriptEnv._strict), scriptEnv, null);
}
- private static void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
- if (!LOG.isEnabled()) {
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
+ }
+
+ private void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
+ if (!log.isEnabled()) {
return;
}
- info(phaseName, "finished. Doing IR size calculation...");
+ log.info(phaseName, "finished. Doing IR size calculation...");
final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification());
osc.calculateObjectSize(functionNode);
@@ -195,7 +208,7 @@
append(" Total size = ").
append(totalSize / 1024 / 1024).
append("MB");
- LOG.info(sb);
+ log.info(sb);
Collections.sort(list, new Comparator<ClassHistogramElement>() {
@Override
@@ -212,9 +225,9 @@
});
for (final ClassHistogramElement e : list) {
final String line = String.format(" %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances());
- info(line);
+ log.info(line);
if (e.getBytes() < totalSize / 200) {
- info(" ...");
+ log.info(" ...");
break; // never mind, so little memory anyway
}
}
@@ -258,8 +271,8 @@
newFunctionNode.uniqueName(reservedName);
}
- final boolean fine = LOG.levelFinerThanOrEqual(Level.FINE);
- final boolean info = LOG.levelFinerThanOrEqual(Level.INFO);
+ final boolean fine = log.levelFinerThanOrEqual(Level.FINE);
+ final boolean info = log.levelFinerThanOrEqual(Level.INFO);
long time = 0L;
@@ -287,7 +300,7 @@
append(" ms ");
}
- LOG.fine(sb);
+ log.fine(sb);
}
}
@@ -305,14 +318,14 @@
append(" ms");
}
- LOG.info(sb);
+ log.info(sb);
}
return newFunctionNode;
}
private Class<?> install(final String className, final byte[] code) {
- LOG.fine("Installing class ", className);
+ log.fine("Installing class ", className);
final Class<?> clazz = installer.install(Compiler.binaryName(className), code);
@@ -384,7 +397,7 @@
}
final StringBuilder sb;
- if (LOG.isEnabled()) {
+ if (log.isEnabled()) {
sb = new StringBuilder();
sb.append("Installed class '").
append(rootClass.getSimpleName()).
@@ -408,7 +421,7 @@
}
if (sb != null) {
- LOG.fine(sb);
+ log.fine(sb);
}
return rootClass;
@@ -482,7 +495,7 @@
private CompileUnit addCompileUnit(final String unitClassName, final long initialWeight) {
final CompileUnit compileUnit = initCompileUnit(unitClassName, initialWeight);
compileUnits.add(compileUnit);
- LOG.fine("Added compile unit ", compileUnit);
+ log.fine("Added compile unit ", compileUnit);
return compileUnit;
}
@@ -523,35 +536,4 @@
return name.replace('/', '.');
}
- /**
- * Log hook; level finest
- * @param args args
- */
- public static void finest(final Object... args) {
- LOG.finest(args);
- }
-
- /**
- * Log hook; level fine
- * @param args args
- */
- public static void fine(final Object... args) {
- LOG.fine(args);
- }
-
- /**
- * Log hook; level info
- * @param args args
- */
- public static void info(final Object... args) {
- LOG.info(args);
- }
-
- /**
- * Log hook; level warning
- * @param args args
- */
- public static void warning(final Object... args) {
- LOG.warning(args);
- }
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/DumpBytecode.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/DumpBytecode.java Wed Apr 23 16:13:47 2014 +0200
@@ -25,9 +25,6 @@
package jdk.nashorn.internal.codegen;
-import static jdk.nashorn.internal.codegen.Compiler.info;
-import static jdk.nashorn.internal.codegen.Compiler.warning;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -39,7 +36,7 @@
* Class that facilitates dumping bytecode to disk
*/
final class DumpBytecode {
- static void dumpBytecode(final ScriptEnvironment env, final byte[] bytecode, final String className) {
+ static void dumpBytecode(final ScriptEnvironment env, final Compiler compiler, final byte[] bytecode, final String className) {
File dir = null;
try {
// should could be printed to stderr for generate class?
@@ -54,7 +51,7 @@
if (env._print_code_dir != null) {
String name = className;
- int dollar = name.lastIndexOf('$');
+ final int dollar = name.lastIndexOf('$');
if (dollar != -1) {
name = name.substring(dollar + 1);
}
@@ -101,10 +98,10 @@
try (final FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytecode);
}
- info("Wrote class to '" + file.getAbsolutePath() + '\'');
+ compiler.getLogger().info("Wrote class to '" + file.getAbsolutePath() + '\'');
}
} catch (final IOException e) {
- warning("Skipping class dump for ",
+ compiler.getLogger().warning("Skipping class dump for ",
className,
": ",
ECMAErrors.getMessage(
--- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java Wed Apr 23 16:13:47 2014 +0200
@@ -42,9 +42,12 @@
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.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Lower to more primitive operations. After lowering, an AST has symbols and
@@ -58,13 +61,24 @@
* that scope and slot information is correct. This enables e.g. AccessSpecialization
* and frame optimizations
*/
+@Logger(name="finalize")
+final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> implements Loggable {
-final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> {
-
- private static final DebugLogger LOG = new DebugLogger("finalize");
+ private final DebugLogger log;
FinalizeTypes() {
super(new LexicalContext());
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
@Override
@@ -176,13 +190,13 @@
return functionNode.setState(lc, CompilationState.FINALIZED);
}
- private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
- if (LOG.isEnabled()) {
+ private void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
+ if (log.isEnabled()) {
if (!symbol.isScope()) {
- LOG.finest("updateSymbols: ", symbol, " => scope, because all vars in ", functionNode.getName(), " are in scope");
+ log.finest("updateSymbols: ", symbol, " => scope, because all vars in ", functionNode.getName(), " are in scope");
}
if (loseSlot && symbol.hasSlot()) {
- LOG.finest("updateSymbols: ", symbol, " => no slot, because all vars in ", functionNode.getName(), " are in scope");
+ log.finest("updateSymbols: ", symbol, " => no slot, because all vars in ", functionNode.getName(), " are in scope");
}
}
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/FindScopeDepths.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FindScopeDepths.java Wed Apr 23 16:13:47 2014 +0200
@@ -42,9 +42,12 @@
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Establishes depth of scope for non local symbols at the start of method.
@@ -52,8 +55,8 @@
* stored in the RecompilableScriptFunctionData and is transferred to the
* FunctionNode being compiled
*/
-
-final class FindScopeDepths extends NodeVisitor<LexicalContext> {
+@Logger(name="scopedepths")
+final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Loggable {
private final Compiler compiler;
private final CompilationEnvironment env;
@@ -61,12 +64,23 @@
private final Map<Integer, Map<String, Integer>> externalSymbolDepths = new HashMap<>();
private final Map<Integer, Set<String>> internalSymbols = new HashMap<>();
- private final static DebugLogger LOG = new DebugLogger("scopedepths");
+ private final DebugLogger log;
FindScopeDepths(final Compiler compiler) {
super(new LexicalContext());
this.compiler = compiler;
- this.env = compiler.getCompilationEnvironment();
+ this.env = compiler.getCompilationEnvironment();
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
static int findScopesToStart(final LexicalContext lc, final FunctionNode fn, final Block block) {
@@ -266,8 +280,8 @@
addInternalSymbols(fn, internals.keySet());
- if (LOG.isEnabled()) {
- LOG.info(fn.getName() + " internals=" + internals + " externals=" + externalSymbolDepths.get(fn.getId()));
+ if (log.isEnabled()) {
+ log.info(fn.getName() + " internals=" + internals + " externals=" + externalSymbolDepths.get(fn.getId()));
}
return true;
--- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java Wed Apr 23 16:13:47 2014 +0200
@@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.List;
+
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
@@ -44,26 +45,41 @@
import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
-import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Simple constant folding pass, executed before IR is starting to be lowered.
*/
-final class FoldConstants extends NodeVisitor<LexicalContext> {
+@Logger(name="fold")
+final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggable {
- private static final DebugLogger LOG = new DebugLogger("fold");
+ private final DebugLogger log;
FoldConstants() {
super(new LexicalContext());
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
@Override
public Node leaveUnaryNode(final UnaryNode unaryNode) {
final LiteralNode<?> literalNode = new UnaryNodeConstantEvaluator(unaryNode).eval();
if (literalNode != null) {
- LOG.info("Unary constant folded ", unaryNode, " to ", literalNode);
+ log.info("Unary constant folded ", unaryNode, " to ", literalNode);
return literalNode;
}
return unaryNode;
@@ -73,7 +89,7 @@
public Node leaveBinaryNode(final BinaryNode binaryNode) {
final LiteralNode<?> literalNode = new BinaryNodeConstantEvaluator(binaryNode).eval();
if (literalNode != null) {
- LOG.info("Binary constant folded ", binaryNode, " to ", literalNode);
+ log.info("Binary constant folded ", binaryNode, " to ", literalNode);
return literalNode;
}
return binaryNode;
@@ -144,7 +160,7 @@
final LexicalContext lc = new LexicalContext();
block.accept(lc, new NodeVisitor<LexicalContext>(lc) {
@Override
- public boolean enterVarNode(VarNode varNode) {
+ public boolean enterVarNode(final VarNode varNode) {
statements.add(varNode.setInit(null));
return false;
}
@@ -256,7 +272,7 @@
break;
case ADD:
if ((lhs.isString() || rhs.isNumeric()) && (rhs.isString() || rhs.isNumeric())) {
- Object res = ScriptRuntime.ADD(lhs.getObject(), rhs.getObject());
+ final Object res = ScriptRuntime.ADD(lhs.getObject(), rhs.getObject());
if (res instanceof Number) {
value = ((Number)res).doubleValue();
break;
--- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java Wed Apr 23 16:13:47 2014 +0200
@@ -34,6 +34,7 @@
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
+
import jdk.nashorn.internal.ir.BaseNode;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;
@@ -67,12 +68,15 @@
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.DebugLogger;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Lower to more primitive operations. After lowering, an AST still has no symbols
@@ -83,10 +87,10 @@
* harder and context dependent to do any code copying after symbols have been
* finalized.
*/
+@Logger(name="lower")
+final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
-final class Lower extends NodeOperatorVisitor<BlockLexicalContext> {
-
- private static final DebugLogger LOG = new DebugLogger("lower");
+ private final DebugLogger log;
// needed only to get unique eval id
private final CodeInstaller<?> installer;
@@ -137,7 +141,19 @@
return block.setIsTerminal(this, false);
}
});
+
this.installer = installer;
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
@Override
@@ -223,7 +239,7 @@
}
@Override
- public Node leaveBlockStatement(BlockStatement blockStatement) {
+ public Node leaveBlockStatement(final BlockStatement blockStatement) {
return addStatement(blockStatement);
}
@@ -252,7 +268,7 @@
@Override
public Node leaveFunctionNode(final FunctionNode functionNode) {
- LOG.info("END FunctionNode: ", functionNode.getName());
+ log.info("END FunctionNode: ", functionNode.getName());
return functionNode.setState(lc, CompilationState.LOWERED);
}
@@ -478,7 +494,7 @@
if (tryNode.getCatchBlocks().isEmpty()) {
newTryNode = tryNode.setFinallyBody(null);
} else {
- Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), tryNode.setFinallyBody(null));
+ final Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), tryNode.setFinallyBody(null));
newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null);
}
@@ -667,7 +683,7 @@
* @return true if an assignment to eval result, false otherwise
*/
private static boolean isEvalResultAssignment(final Node expression) {
- Node e = expression;
+ final Node e = expression;
assert e.tokenType() != TokenType.DISCARD; //there are no discards this early anymore
if (e instanceof BinaryNode) {
final Node lhs = ((BinaryNode)e).lhs();
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Wed Apr 23 16:13:47 2014 +0200
@@ -98,12 +98,12 @@
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ArgumentSetter;
import jdk.nashorn.internal.runtime.Debug;
-import jdk.nashorn.internal.runtime.DebugLogger;
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;
import jdk.nashorn.internal.runtime.options.Options;
/**
@@ -144,8 +144,8 @@
static final int LARGE_STRING_THRESHOLD = 32 * 1024;
/** Debug flag, should we dump all generated bytecode along with stacks? */
- private static final DebugLogger LOG = new DebugLogger("codegen", "nashorn.codegen.debug");
- private static final boolean DEBUG = LOG.isEnabled();
+ private final DebugLogger log = Global.instance().getLogger(CodeGenerator.class);
+ private final boolean debug = log.isEnabled();
/** dump stack on a particular line, or -1 if disabled */
private static final int DEBUG_TRACE_LINE;
@@ -2301,7 +2301,7 @@
* @param args debug information to print
*/
private void debug(final Object... args) {
- if (DEBUG) {
+ if (debug) {
debug(30, args);
}
}
@@ -2313,13 +2313,13 @@
* @param args debug information to print
*/
private void debug_label(final Object... args) {
- if (DEBUG) {
+ if (debug) {
debug(22, args);
}
}
private void debug(final int padConstant, final Object... args) {
- if (DEBUG) {
+ if (debug) {
final StringBuilder sb = new StringBuilder();
int pad;
@@ -2386,9 +2386,9 @@
}
if (env != null) { //early bootstrap code doesn't have inited context yet
- LOG.info(sb);
+ log.info(sb);
if (DEBUG_TRACE_LINE == linePrefix) {
- new Throwable().printStackTrace(LOG.getOutputStream());
+ new Throwable().printStackTrace(log.getOutputStream());
}
}
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Wed Apr 23 16:13:47 2014 +0200
@@ -50,30 +50,30 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.EnumSet;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-
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.DebugLogger;
import jdk.nashorn.internal.runtime.FunctionScope;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Undefined;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+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;
/**
* Generates the ScriptObject subclass structure with fields for a user objects.
*/
-public final class ObjectClassGenerator {
+@Logger(name="fields")
+public final class ObjectClassGenerator implements Loggable {
/**
* Type guard to make sure we don't unnecessarily explode field storages. Rather unbox e.g.
@@ -96,44 +96,12 @@
* Debug field logger
* Should we print debugging information for fields when they are generated and getters/setters are called?
*/
- private static final DebugLogger LOG = new DebugLogger("fields", "nashorn.fields.debug");
-
- /**
- * Get the field logger
- * @return logger
- */
- public static DebugLogger getLogger() {
- return LOG;
- }
+ private final DebugLogger log;
- private static final Set<String> FIELDS_TO_INSTRUMENT;
- static {
- final String fields = Options.getStringProperty("nashorn.fields", null);
- final Set<String> fti = new HashSet<>();
- if (fields != null) {
- final StringTokenizer st = new StringTokenizer(fields, ",");
- while (st.hasMoreTokens()) {
- fti.add(st.nextToken());
- }
- }
- FIELDS_TO_INSTRUMENT = fti.isEmpty() ? null : fti;
- }
-
- /**
- * Should this particular field be instrumented with --log=fields
- * Internal use only
- * @param field field name
- * @return true if it should be instrumented
- */
- public static boolean shouldInstrument(final String field) {
- //if no explicit fields to imstrument are given, instrument all fields
- return FIELDS_TO_INSTRUMENT == null || FIELDS_TO_INSTRUMENT.contains(field);
- }
/**
* is field debugging enabled. Several modules in codegen and properties use this, hence
* public access.
*/
- public static final boolean DEBUG_FIELDS = LOG.isEnabled();
private static final boolean EXPLICIT_OBJECT = Options.getBooleanProperty("nashorn.fields.objects");
@@ -163,11 +131,10 @@
static {
if (!OBJECT_FIELDS_ONLY) {
FIELD_TYPES.add(PRIMITIVE_FIELD_TYPE);
- } else {
- LOG.warning("Running with object fields only - this is a deprecated configuration.");
}
FIELD_TYPES.add(Type.OBJECT);
}
+ private static boolean initialized = false;
/** The context */
private final Context context;
@@ -180,6 +147,25 @@
public ObjectClassGenerator(final Context context) {
this.context = context;
assert context != null;
+ this.log = initLogger(Global.instance());
+ synchronized (ObjectClassGenerator.class) {
+ if (!initialized) {
+ initialized = true;
+ if (OBJECT_FIELDS_ONLY) {
+ log.warning("Running with object fields only - this is a deprecated configuration.");
+ }
+ }
+ }
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
/**
--- a/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java Wed Apr 23 16:13:47 2014 +0200
@@ -47,8 +47,11 @@
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.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Range analysis and narrowing of type where it can be proven
@@ -63,15 +66,28 @@
*
* Proves that the multiplication never exceeds 24 bits and can thus be an int
*/
-final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> {
- static final DebugLogger LOG = new DebugLogger("ranges");
+@Logger(name="ranges")
+final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> implements Loggable {
+ private final DebugLogger log;
- private static final Range.Functionality RANGE = new Range.Functionality(LOG);
+ private final Range.Functionality func;
private final Map<LoopNode, Symbol> loopCounters = new HashMap<>();
RangeAnalyzer() {
super(new LexicalContext());
+ this.log = initLogger(Global.instance());
+ this.func = new Range.Functionality(log);
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
@Override
@@ -80,7 +96,7 @@
//properly identified and that no optimizations can be made with it - its range is
//simply unknown in that case, if it is assigned in the loop
final Symbol counter = findLoopCounter(forNode);
- LOG.fine("Entering forNode " + forNode + " counter = " + counter);
+ log.fine("Entering forNode " + forNode + " counter = " + counter);
if (counter != null && !assignedInLoop(forNode, counter)) {
loopCounters.put(forNode, counter);
}
@@ -96,7 +112,7 @@
final Symbol symbol = dest.getSymbol();
assert symbol != null : dest + " " + dest.getClass() + " has no symbol";
assert symbol.getRange() != null : symbol + " has no range";
- final Range symRange = RANGE.join(symbol.getRange(), range);
+ final Range symRange = func.join(symbol.getRange(), range);
//anything assigned in the loop, not being the safe loop counter(s) invalidates its entire range
if (lc.inLoop() && !isLoopCounter(lc.getCurrentLoop(), symbol)) {
@@ -105,7 +121,7 @@
}
if (!symRange.equals(symbol.getRange())) {
- LOG.fine("Modify range for " + dest + " " + symbol + " from " + symbol.getRange() + " to " + symRange + " (in node = " + dest + ")" );
+ log.fine("Modify range for " + dest + " " + symbol + " from " + symbol.getRange() + " to " + symRange + " (in node = " + dest + ")" );
symbol.setRange(symRange);
}
@@ -114,67 +130,67 @@
@Override
public Node leaveADD(final BinaryNode node) {
- setRange(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveSUB(final BinaryNode node) {
- setRange(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveMUL(final BinaryNode node) {
- setRange(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveDIV(final BinaryNode node) {
- setRange(node, RANGE.div(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.div(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveMOD(final BinaryNode node) {
- setRange(node, RANGE.mod(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.mod(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveBIT_AND(final BinaryNode node) {
- setRange(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveBIT_OR(final BinaryNode node) {
- setRange(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveBIT_XOR(final BinaryNode node) {
- setRange(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveSAR(final BinaryNode node) {
- setRange(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveSHL(final BinaryNode node) {
- setRange(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@Override
public Node leaveSHR(final BinaryNode node) {
- setRange(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ setRange(node, func.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
return node;
}
@@ -250,17 +266,17 @@
@Override
public Node leaveASSIGN_ADD(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_SUB(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_MUL(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
@@ -275,32 +291,32 @@
@Override
public Node leaveASSIGN_BIT_AND(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_BIT_OR(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_BIT_XOR(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_SAR(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_SHR(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
public Node leaveASSIGN_SHL(final BinaryNode node) {
- return leaveSelfModifyingAssign(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return leaveSelfModifyingAssign(node, func.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
}
@Override
@@ -308,10 +324,10 @@
switch (node.tokenType()) {
case DECPREFIX:
case DECPOSTFIX:
- return leaveSelfModifyingAssign(node, RANGE.sub(node.getExpression().getSymbol().getRange(), Range.createRange(1)));
+ return leaveSelfModifyingAssign(node, func.sub(node.getExpression().getSymbol().getRange(), Range.createRange(1)));
case INCPREFIX:
case INCPOSTFIX:
- return leaveSelfModifyingAssign(node, RANGE.add(node.getExpression().getSymbol().getRange(), Range.createRange(1)));
+ return leaveSelfModifyingAssign(node, func.add(node.getExpression().getSymbol().getRange(), Range.createRange(1)));
default:
throw new UnsupportedOperationException("" + node.tokenType());
}
@@ -341,7 +357,7 @@
@Override
public Node leaveSUB(final UnaryNode node) {
- setRange(node, RANGE.neg(node.getExpression().getSymbol().getRange()));
+ setRange(node, func.neg(node.getExpression().getSymbol().getRange()));
return node;
}
@@ -436,7 +452,7 @@
* @param node loop node to check
* @return
*/
- private static Symbol findLoopCounter(final LoopNode node) {
+ private Symbol findLoopCounter(final LoopNode node) {
final Expression test = node.getTest();
if (test != null && test.isComparison()) {
@@ -453,7 +469,7 @@
switch (op) {
case LT:
case LE:
- symbol.setRange(RANGE.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
+ symbol.setRange(func.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
return symbol;
case GT:
case GE:
--- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Wed Apr 23 16:13:47 2014 +0200
@@ -26,12 +26,12 @@
package jdk.nashorn.internal.codegen;
import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
-import static jdk.nashorn.internal.codegen.Compiler.finest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
@@ -43,6 +43,7 @@
import jdk.nashorn.internal.ir.SplitNode;
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.options.Options;
/**
@@ -64,6 +65,8 @@
/** Weight threshold for when to start a split. */
public static final long SPLIT_THRESHOLD = Options.getIntProperty("nashorn.compiler.splitter.threshold", 32 * 1024);
+ private final DebugLogger log;
+
/**
* Constructor.
*
@@ -76,6 +79,7 @@
this.compiler = compiler;
this.outermost = functionNode;
this.outermostCompileUnit = outermostCompileUnit;
+ this.log = compiler.getLogger();
}
/**
@@ -86,7 +90,7 @@
FunctionNode split(final FunctionNode fn, final boolean top) {
FunctionNode functionNode = fn;
- finest("Initiating split of '", functionNode.getName(), "'");
+ log.finest("Initiating split of '", functionNode.getName(), "'");
long weight = WeighNodes.weigh(functionNode);
@@ -95,7 +99,7 @@
assert lc.isEmpty() : "LexicalContext not empty";
if (weight >= SPLIT_THRESHOLD) {
- finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
+ log.finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
functionNode = (FunctionNode)functionNode.accept(this);
if (functionNode.isSplit()) {
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/Range.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Range.java Wed Apr 23 16:13:47 2014 +0200
@@ -29,7 +29,7 @@
import java.util.Collections;
import java.util.List;
-import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.JSType;
/**
@@ -544,8 +544,8 @@
final long shift = ((IntegerRange) b).getMin() & 0x1f;
final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
if (left.getMin() >= 0) {
- long min = left.getMin() >>> shift;
- long max = left.getMax() >>> shift;
+ final long min = left.getMin() >>> shift;
+ final long max = left.getMax() >>> shift;
return createIntegerRange(min, max);
} else if (shift >= 1) {
return createIntegerRange(0, JSType.MAX_UINT >>> shift);
--- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Wed Apr 23 16:13:47 2014 +0200
@@ -28,9 +28,6 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.__DIR__;
import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
-
-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
@@ -219,9 +216,6 @@
if (this.optimisticType == callSiteType) {
return this;
}
- if (DEBUG_FIELDS && ObjectClassGenerator.shouldInstrument(getName()) && getSymbol() != null && !Type.areEquivalent(getSymbol().getSymbolType(), callSiteType)) {
- ObjectClassGenerator.getLogger().info(getClass().getName(), " ", this, " => ", callSiteType, " instead of ", getType());
- }
return new IdentNode(this, name, callSiteType, flags, programPoint);
}
--- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Wed Apr 23 16:13:47 2014 +0200
@@ -37,9 +37,12 @@
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.Debug;
-import jdk.nashorn.internal.runtime.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.ScriptObject;
import jdk.nashorn.internal.runtime.options.Options;
@@ -97,38 +100,20 @@
return obj.toString();
}
- private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
- private static final MethodHandleFunctionality FUNC;
-
- private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
- private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
-
- static {
- if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
- if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
- FUNC = new TraceCreateMethodHandleFunctionality();
- } else {
- FUNC = new TraceMethodHandleFunctionality();
- }
- } else {
- FUNC = STANDARD;
- }
- }
-
+ private static final MethodHandleFunctionality FUNC = new StandardMethodHandleFunctionality();
private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
-
/**
* Return the method handle functionality used for all method handle operations
* @return a method handle functionality implementation
*/
- public static MethodHandleFunctionality getFunctionality() {
+ public static synchronized MethodHandleFunctionality getFunctionality() {
return FUNC;
}
- private static final MethodHandle TRACE = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
- private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
- private static final MethodHandle TRACE_RETURN_VOID = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturnVoid", MethodType.methodType(void.class, DebugLogger.class));
+ private static final MethodHandle TRACE = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
+ private static final MethodHandle TRACE_RETURN = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
+ private static final MethodHandle TRACE_RETURN_VOID = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturnVoid", MethodType.methodType(void.class, DebugLogger.class));
private static final String VOID_TAG = "[VOID]";
@@ -234,7 +219,6 @@
return addDebugPrintout(logger, level, mh, 0, true, tag);
}
-
/**
* Add a debug printout to a method handle, tracing parameters and return values
*
@@ -283,194 +267,34 @@
}
/**
- * The standard class that marshalls all method handle operations to the java.lang.invoke
+ * Class that marshalls all method handle operations to the java.lang.invoke
* package. This exists only so that it can be subclassed and method handles created from
* Nashorn made possible to instrument.
*
* All Nashorn classes should use the MethodHandleFactory for their method handle operations
*/
- private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
-
- @Override
- public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
- return MethodHandles.filterArguments(target, pos, filters);
- }
-
- @Override
- public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
- return MethodHandles.filterReturnValue(target, filter);
- }
-
- @Override
- public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
- return MethodHandles.guardWithTest(test, target, fallback);
- }
-
- @Override
- public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
- return MethodHandles.insertArguments(target, pos, values);
- }
-
- @Override
- public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
- return MethodHandles.dropArguments(target, pos, valueTypes);
- }
-
- @Override
- public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
- return MethodHandles.dropArguments(target, pos, valueTypes);
- }
-
- @Override
- public MethodHandle asType(final MethodHandle handle, final MethodType type) {
- return handle.asType(type);
- }
-
- @Override
- public MethodHandle bindTo(final MethodHandle handle, final Object x) {
- return handle.bindTo(x);
- }
+ @Logger(name="methodhandles")
+ private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality, Loggable {
- @Override
- public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
- return MethodHandles.foldArguments(target, combiner);
- }
-
- @Override
- public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
- return MethodHandles.explicitCastArguments(target, type);
- }
-
- @Override
- public MethodHandle arrayElementGetter(final Class<?> type) {
- return MethodHandles.arrayElementGetter(type);
- }
-
- @Override
- public MethodHandle arrayElementSetter(final Class<?> type) {
- return MethodHandles.arrayElementSetter(type);
- }
+ // for bootstrapping reasons, because a lot of static fields use MH for lookups, we
+ // need to set the logger when the Global object is finished. This means that we don't
+ // get instrumentation for public static final MethodHandle SOMETHING = MH... in the builtin
+ // classes, but that doesn't matter, because this is usually not where we want it
+ private DebugLogger log = DebugLogger.DISABLED_LOGGER;
- @Override
- public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
- return MethodHandles.throwException(returnType, exType);
- }
-
- @Override
- public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler) {
- return MethodHandles.catchException(target, exType, handler);
- }
-
- @Override
- public MethodHandle constant(final Class<?> type, final Object value) {
- return MethodHandles.constant(type, value);
- }
-
- @Override
- public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- return handle.asCollector(arrayType, arrayLength);
- }
-
- @Override
- public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- return handle.asSpreader(arrayType, arrayLength);
+ public StandardMethodHandleFunctionality() {
}
@Override
- public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findGetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findStaticGetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
-
- @Override
- public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findSetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findStaticSetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle find(final Method method) {
- try {
- return PUBLIC_LOOKUP.unreflect(method);
- } catch (final IllegalAccessException e) {
- throw new LookupException(e);
- }
+ public DebugLogger initLogger(final Global global) {
+ return this.log = global.getLogger(this.getClass());
}
@Override
- public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- try {
- return explicitLookup.findStatic(clazz, name, type);
- } catch (final NoSuchMethodException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle findSpecial(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type, final Class<?> thisClass) {
- try {
- return explicitLookup.findSpecial(clazz, name, type, thisClass);
- } catch (final NoSuchMethodException | IllegalAccessException e) {
- throw new LookupException(e);
- }
+ public DebugLogger getLogger() {
+ return log;
}
- @Override
- public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- try {
- return explicitLookup.findVirtual(clazz, name, type);
- } catch (final NoSuchMethodException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public SwitchPoint createSwitchPoint() {
- return new SwitchPoint();
- }
-
- @Override
- public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
- return sp.guardWithTest(before, after);
- }
-
- @Override
- public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
- return MethodType.methodType(returnType, paramTypes);
- }
-
- }
-
- /**
- * Class used for instrumenting and debugging Nashorn generated method handles
- */
- private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
-
protected static String describe(final Object... data) {
final StringBuilder sb = new StringBuilder();
@@ -503,183 +327,215 @@
}
public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
- return addDebugPrintout(LOG, Level.INFO, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
+ if (log.isEnabled()) {
+ if (PRINT_STACKTRACE) {
+ stacktrace(log);
+ }
+ return addDebugPrintout(log, Level.INFO, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
+ }
+ return master;
}
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
- final MethodHandle mh = super.filterArguments(target, pos, filters);
+ final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
return debug(mh, "filterArguments", target, pos, filters);
}
@Override
public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
- final MethodHandle mh = super.filterReturnValue(target, filter);
+ final MethodHandle mh = MethodHandles.filterReturnValue(target, filter);
return debug(mh, "filterReturnValue", target, filter);
}
@Override
public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
- final MethodHandle mh = super.guardWithTest(test, target, fallback);
+ final MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
return debug(mh, "guardWithTest", test, target, fallback);
}
@Override
public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
- final MethodHandle mh = super.insertArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.insertArguments(target, pos, values);
return debug(mh, "insertArguments", target, pos, values);
}
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
- final MethodHandle mh = super.dropArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
return debug(mh, "dropArguments", target, pos, values);
}
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
- final MethodHandle mh = super.dropArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
return debug(mh, "dropArguments", target, pos, values);
}
@Override
public MethodHandle asType(final MethodHandle handle, final MethodType type) {
- final MethodHandle mh = super.asType(handle, type);
+ final MethodHandle mh = handle.asType(type);
return debug(mh, "asType", handle, type);
}
@Override
public MethodHandle bindTo(final MethodHandle handle, final Object x) {
- final MethodHandle mh = super.bindTo(handle, x);
+ final MethodHandle mh = handle.bindTo(x);
return debug(mh, "bindTo", handle, x);
}
@Override
public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
- final MethodHandle mh = super.foldArguments(target, combiner);
+ final MethodHandle mh = MethodHandles.foldArguments(target, combiner);
return debug(mh, "foldArguments", target, combiner);
}
@Override
public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
- final MethodHandle mh = super.explicitCastArguments(target, type);
+ final MethodHandle mh = MethodHandles.explicitCastArguments(target, type);
return debug(mh, "explicitCastArguments", target, type);
}
@Override
public MethodHandle arrayElementGetter(final Class<?> type) {
- final MethodHandle mh = super.arrayElementGetter(type);
+ final MethodHandle mh = MethodHandles.arrayElementGetter(type);
return debug(mh, "arrayElementGetter", type);
}
@Override
public MethodHandle arrayElementSetter(final Class<?> type) {
- final MethodHandle mh = super.arrayElementSetter(type);
+ final MethodHandle mh = MethodHandles.arrayElementSetter(type);
return debug(mh, "arrayElementSetter", type);
}
@Override
public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
- final MethodHandle mh = super.throwException(returnType, exType);
+ final MethodHandle mh = MethodHandles.throwException(returnType, exType);
return debug(mh, "throwException", returnType, exType);
}
@Override
public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler) {
- final MethodHandle mh = super.catchException(target, exType, handler);
+ final MethodHandle mh = MethodHandles.catchException(target, exType, handler);
return debug(mh, "catchException", exType);
}
@Override
public MethodHandle constant(final Class<?> type, final Object value) {
- final MethodHandle mh = super.constant(type, value);
+ final MethodHandle mh = MethodHandles.constant(type, value);
return debug(mh, "constant", type, value);
}
@Override
public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
+ final MethodHandle mh = handle.asCollector(arrayType, arrayLength);
return debug(mh, "asCollector", handle, arrayType, arrayLength);
}
@Override
public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength);
+ final MethodHandle mh = handle.asSpreader(arrayType, arrayLength);
return debug(mh, "asSpreader", handle, arrayType, arrayLength);
}
@Override
public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
- return debug(mh, "getter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findGetter(clazz, name, type);
+ return debug(mh, "getter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
- return debug(mh, "static getter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStaticGetter(clazz, name, type);
+ return debug(mh, "static getter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
- return debug(mh, "setter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findSetter(clazz, name, type);
+ return debug(mh, "setter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
- return debug(mh, "static setter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStaticSetter(clazz, name, type);
+ return debug(mh, "static setter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle find(final Method method) {
- final MethodHandle mh = super.find(method);
- return debug(mh, "find", method);
+ try {
+ final MethodHandle mh = PUBLIC_LOOKUP.unreflect(method);
+ return debug(mh, "find", method);
+ } catch (final IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
- return debug(mh, "findStatic", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStatic(clazz, name, type);
+ return debug(mh, "findStatic", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
+ }
+
+ @Override
+ public MethodHandle findSpecial(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type, final Class<?> thisClass) {
+ try {
+ final MethodHandle mh = explicitLookup.findSpecial(clazz, name, type, thisClass);
+ return debug(mh, "findSpecial", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
- return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findVirtual(clazz, name, type);
+ return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public SwitchPoint createSwitchPoint() {
- final SwitchPoint sp = super.createSwitchPoint();
- LOG.log(TRACE_LEVEL, "createSwitchPoint ", sp);
+ final SwitchPoint sp = new SwitchPoint();
+ log.log(TRACE_LEVEL, "createSwitchPoint ", sp);
return sp;
}
@Override
public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
- final MethodHandle mh = super.guardWithTest(sp, before, after);
+ final MethodHandle mh = sp.guardWithTest(before, after);
return debug(mh, "guardWithTest", sp, before, after);
}
@Override
public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
- final MethodType mt = super.type(returnType, paramTypes);
- LOG.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
+ final MethodType mt = MethodType.methodType(returnType, paramTypes);
+ log.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
return mt;
}
}
-
- /**
- * Class used for debugging Nashorn generated method handles
- */
- private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
- @Override
- public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
- LOG.log(TRACE_LEVEL, str, " ", describe(args));
- stacktrace(LOG);
- return master;
- }
- }
}
--- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java Wed Apr 23 16:13:47 2014 +0200
@@ -337,5 +337,6 @@
* @return the method type
*/
public MethodType type(Class<?> returnType, Class<?>... paramTypes);
+
}
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Wed Apr 23 16:13:47 2014 +0200
@@ -44,12 +44,15 @@
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 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;
@@ -70,7 +73,11 @@
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;
/**
@@ -430,6 +437,13 @@
// 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);
+ }
+
@Override
protected Context getContext() {
return context;
@@ -465,7 +479,8 @@
this.context = context;
this.setIsScope();
this.optimisticFunctionMap = new HashMap<>();
- GlobalConstants.instance().invalidateAll();
+ final GlobalConstants gc = GlobalConstants.instance(this);
+ gc.invalidateAll();
}
/**
@@ -480,6 +495,14 @@
}
/**
+ * Check if we have a Global instance
+ * @return true if one exists
+ */
+ public static boolean hasInstance() {
+ return Context.getGlobal() != null;
+ }
+
+ /**
* Script access to {@link ScriptEnvironment}
*
* @return the script environment
@@ -1691,6 +1714,8 @@
// synonym for "arguments" in scripting mode
addOwnProperty("$ARG", argumentsFlags, argumentsObject);
}
+
+ initLoggers();
}
private void initErrorObjects() {
@@ -2072,7 +2097,7 @@
public void invalidateReservedName(final String name) {
final SwitchPoint sp = getChangeCallback(name);
if (sp != null) {
- ApplySpecialization.getLogger().info("Overwrote special name '" + name +"' - invalidating switchpoint");
+ getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
}
}
@@ -2088,4 +2113,73 @@
final MethodHandle target = MH.insertArguments(Global.instance().INVALIDATE_RESERVED_NAME, 0, name);
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;
+ }
+
}
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java Wed Apr 23 16:13:47 2014 +0200
@@ -105,7 +105,7 @@
import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode;
-import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSErrorType;
import jdk.nashorn.internal.runtime.ParserException;
@@ -114,11 +114,15 @@
import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.Timing;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Builds the IR.
*/
-public class Parser extends AbstractParser {
+@Logger(name="parser")
+public class Parser extends AbstractParser implements Loggable {
private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
/** Current script environment. */
@@ -135,7 +139,7 @@
/** Namespace for function names where not explicitly given */
private final Namespace namespace;
- private static final DebugLogger LOG = new DebugLogger("parser");
+ private final DebugLogger log;
/** to receive line information from Lexer when scanning multine literals. */
protected final Lexer.LineInfoReceiver lineInfoReceiver;
@@ -194,6 +198,18 @@
// non-scripting mode script can't have multi-line literals
this.lineInfoReceiver = null;
}
+
+ this.log = !Global.hasInstance() ? DebugLogger.DISABLED_LOGGER : initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
/**
@@ -250,7 +266,7 @@
*/
public FunctionNode parse(final String scriptName, final int startPos, final int len, final boolean allowPropertyFunction) {
final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
- LOG.info(this, " begin for '", scriptName, "'");
+ log.info(this, " begin for '", scriptName, "'");
try {
stream = new TokenStream();
@@ -271,9 +287,9 @@
final String end = this + " end '" + scriptName + "'";
if (Timing.isEnabled()) {
Timing.accumulateTime(toString(), System.currentTimeMillis() - t0);
- LOG.info(end, "' in ", System.currentTimeMillis() - t0, " ms");
+ log.info(end, "' in ", System.currentTimeMillis() - t0, " ms");
} else {
- LOG.info(end);
+ log.info(end);
}
}
}
@@ -2538,7 +2554,7 @@
return nodeList;
}
- private static <T> List<T> optimizeList(ArrayList<T> list) {
+ private static <T> List<T> optimizeList(final ArrayList<T> list) {
switch(list.size()) {
case 0: {
return Collections.emptyList();
@@ -2668,7 +2684,7 @@
return isValidIdentifier(defaultFunctionName) ? defaultFunctionName : ANON_FUNCTION_PREFIX.symbolName() + functionLine;
}
- private static boolean isValidIdentifier(String name) {
+ private static boolean isValidIdentifier(final String name) {
if(name == null || name.isEmpty()) {
return false;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Wed Apr 23 16:13:47 2014 +0200
@@ -25,14 +25,12 @@
package jdk.nashorn.internal.runtime;
-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldCount;
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldName;
-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.shouldInstrument;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.lookup.MethodHandleFactory.stripName;
import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
@@ -42,12 +40,12 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.SwitchPoint;
+import java.util.function.Supplier;
import java.util.logging.Level;
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.Global;
/**
@@ -56,14 +54,14 @@
*/
public class AccessorProperty extends Property {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
- private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
+
+ private static final MethodHandle REPLACE_MAP = findOwnMH_S("replaceMap", Object.class, Object.class, PropertyMap.class);
+ private static final MethodHandle INVALIDATE_SP = findOwnMH_S("invalidateSwitchPoint", Object.class, Object.class, SwitchPoint.class);
+
+ private static final SwitchPoint NO_CHANGE_CALLBACK = new SwitchPoint();
private static final int NOOF_TYPES = getNumberOfAccessorTypes();
- private static final DebugLogger LOG = ObjectClassGenerator.getLogger();
-
- private static final MethodHandle INVALIDATE_SP = findOwnMH("invalidateSwitchPoint", Object.class, Object.class, SwitchPoint.class, String.class);
-
/**
* Properties in different maps for the same structure class will share their field getters and setters. This could
* be further extended to other method handles that are looked up in the AccessorProperty constructor, but right now
@@ -376,9 +374,6 @@
if (!canBeUndefined()) { //todo if !canBeUndefined it means that we have an exact initialType
initialType = int.class;
}
- if (shouldInstrument(getKey())) {
- info(getKey(), canBeUndefined() ? " can be undefined" : " is always defined");
- }
}
setCurrentType(initialType);
}
@@ -594,27 +589,19 @@
// the final three arguments are for debug printout purposes only
@SuppressWarnings("unused")
- private static Object replaceMap(final Object sobj, final PropertyMap newMap, final String key, final Class<?> oldType, final Class<?> newType) {
- if (DEBUG_FIELDS && shouldInstrument(key)) {
- final PropertyMap oldMap = ((ScriptObject)sobj).getMap();
- info("Type change for '" + key + "' " + oldType + "=>" + newType);
- finest("setting map " + key+ " => " + sobj + " from " + Debug.id(oldMap) + " to " + Debug.id(newMap) + " " + oldMap + " => " + newMap);
- }
+ private static Object replaceMap(final Object sobj, final PropertyMap newMap) {
((ScriptObject)sobj).setMap(newMap);
return sobj;
}
@SuppressWarnings("unused")
- private static Object invalidateSwitchPoint(final Object obj, final SwitchPoint sp, final String key) {
- LOG.info("Field change callback for " + key + " triggered: " + sp);
+ private static Object invalidateSwitchPoint(final Object obj, final SwitchPoint sp) {
SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
return obj;
}
private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
- MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
- mh = debug(mh, getCurrentType(), type, "set");
- return mh;
+ return debug(createSetter(forType, type, primitiveSetter, objectSetter), getCurrentType(), type, "set");
}
/**
@@ -638,8 +625,8 @@
final PropertyMap newMap = getWiderMap(currentMap, newProperty);
final MethodHandle widerSetter = newProperty.getSetter(type, newMap);
- final Class<?> ct = getCurrentType();
- mh = MH.filterArguments(widerSetter, 0, MH.insertArguments(REPLACE_MAP, 1, newMap, getKey(), ct, type));
+ final Class<?> ct = getCurrentType();
+ mh = MH.filterArguments(widerSetter, 0, MH.insertArguments(debugReplace(ct, type, currentMap, newMap) , 1, newMap));
if (ct != null && ct.isPrimitive() && !type.isPrimitive()) {
mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh);
}
@@ -652,16 +639,14 @@
*/
final SwitchPoint ccb = getChangeCallback();
if (ccb != null && ccb != NO_CHANGE_CALLBACK) {
- mh = MH.filterArguments(mh, 0, MH.insertArguments(INVALIDATE_SP, 1, changeCallback, getKey()));
+ mh = MH.filterArguments(mh, 0, MH.insertArguments(debugInvalidate(getKey(), ccb), 1, changeCallback));
}
- assert mh.type().returnType() == void.class;
+ assert mh.type().returnType() == void.class : mh.type();
return mh;
}
- private static final SwitchPoint NO_CHANGE_CALLBACK = new SwitchPoint();
-
/**
* Get the change callback for this property
* @return switchpoint that is invalidated when property changes
@@ -693,32 +678,6 @@
return canChangeType() && ti > fti;
}
- // for loggers below, don't bother generating potentially expensive string concat
- // operations that will be thrown away anyway, if the level isn't finer than ior
- // equal to info
- private static void finest(final String... strs) {
- if (DEBUG_FIELDS && LOG.levelFinerThanOrEqual(Level.INFO)) {
- LOG.finest((Object[])strs);
- }
- }
-
- private static void info(final String... strs) {
- if (DEBUG_FIELDS && LOG.levelFinerThanOrEqual(Level.INFO)) {
- LOG.info((Object[])strs);
- }
- }
-
- private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
- if (DEBUG_FIELDS && LOG.levelFinerThanOrEqual(Level.INFO) && shouldInstrument(getKey())) {
- return MethodHandleFactory.addDebugPrintout(
- LOG,
- Level.INFO,
- mh,
- tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", slot=" + getSlot() + " " + getClass().getSimpleName() + " forType=" + stripName(forType) + ", type=" + stripName(type) + ')');
- }
- return mh;
- }
-
@Override
public final void setCurrentType(final Class<?> currentType) {
assert currentType != boolean.class : "no boolean storage support yet - fix this";
@@ -730,8 +689,74 @@
return currentType;
}
- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+
+ private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
+ if (Global.hasInstance()) {
+ return Global.instance().addLoggingToHandle(
+ ObjectClassGenerator.class,
+ Level.INFO,
+ mh,
+ 0,
+ true,
+ new Supplier<String>() {
+ @Override
+ public String get() {
+ return tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", slot=" + getSlot() + " " + getClass().getSimpleName() + " forType=" + stripName(forType) + ", type=" + stripName(type) + ')';
+ }
+ });
+ }
+
+ return mh;
+ }
+
+ 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(
+ ObjectClassGenerator.class,
+ REPLACE_MAP,
+ new Supplier<String>() {
+ @Override
+ public String get() {
+ return "Type change for '" + getKey() + "' " + oldType + "=>" + newType;
+ }
+ });
+
+ mh = global.addLoggingToHandle(
+ ObjectClassGenerator.class,
+ Level.FINEST,
+ mh,
+ Integer.MAX_VALUE,
+ false,
+ new Supplier<String>() {
+ @Override
+ public String get() {
+ return "Setting map " + Debug.id(oldMap) + " => " + Debug.id(newMap) + " " + oldMap + " => " + newMap;
+ }
+ });
+ return mh;
+ }
+
+ return REPLACE_MAP;
+ }
+
+ private static MethodHandle debugInvalidate(final String key, final SwitchPoint sp) {
+ if (Global.hasInstance()) {
+ return Global.instance().addLoggingToHandle(
+ ObjectClassGenerator.class,
+ INVALIDATE_SP,
+ new Supplier<String>() {
+ @Override
+ public String get() {
+ return "Field change callback for " + key + " triggered: " + sp;
+ }
+ });
+ }
+
+ 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));
}
-
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java Wed Apr 23 16:13:47 2014 +0200
@@ -41,8 +41,10 @@
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;
/**
* An version of a JavaScript function, native or JavaScript.
@@ -55,7 +57,7 @@
private static final MethodHandle HANDLE_REWRITE_EXCEPTION = findOwnMH("handleRewriteException", MethodHandle.class, CompiledFunction.class, OptimismInfo.class, RewriteException.class);
private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class));
- private static final DebugLogger LOG = RecompilableScriptFunctionData.getLogger();
+ private final DebugLogger log;
/**
* The method type may be more specific than the invoker, if. e.g.
@@ -71,6 +73,7 @@
CompiledFunction(final MethodHandle invoker) {
this.invoker = invoker;
+ this.log = Global.instance().getLogger(RecompilableScriptFunctionData.class);
}
static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
@@ -576,8 +579,8 @@
final MethodType callSiteType = type.parameterType(0) == ScriptFunction.class ? type : type.insertParameterTypes(0, ScriptFunction.class);
final FunctionNode fn = oldOptimismInfo.recompile(callSiteType, re);
- if (LOG.isEnabled()) {
- LOG.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "\tRewriteException ", re.getMessageShort());
+ if (log.isEnabled()) {
+ log.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "\tRewriteException ", re.getMessageShort());
}
// It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already
@@ -588,8 +591,8 @@
//is recompiled
assert optimismInfo == oldOptimismInfo;
isOptimistic = fn.isOptimistic();
- if (LOG.isEnabled()) {
- LOG.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ")", isOptimistic ? " remains optimistic." : " is no longer optimistic.");
+ if (log.isEnabled()) {
+ log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ")", isOptimistic ? " remains optimistic." : " is no longer optimistic.");
}
final MethodHandle newInvoker = oldOptimismInfo.data.lookup(fn);
invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
@@ -617,6 +620,7 @@
private final RecompilableScriptFunctionData data;
private final Map<Integer, Type> invalidatedProgramPoints = new TreeMap<>();
private SwitchPoint optimisticAssumptions;
+ private final DebugLogger log = Global.instance().getLogger(RecompilableScriptFunctionData.class);
OptimismInfo(final RecompilableScriptFunctionData data) {
this.data = data;
@@ -633,7 +637,7 @@
if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
final StackTraceElement[] stack = e.getStackTrace();
final String functionId = stack.length == 0 ? data.getName() : stack[0].getClassName() + "." + stack[0].getMethodName();
- LOG.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
+ log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
return null;
}
SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Wed Apr 23 16:13:47 2014 +0200
@@ -65,6 +65,7 @@
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.options.Options;
/**
@@ -195,7 +196,7 @@
// 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().invalidateAll();
+ GlobalConstants.instance(global).invalidateAll();
currentGlobal.set(global);
}
@@ -915,9 +916,9 @@
Class<?> script = findCachedClass(source);
if (script != null) {
- final DebugLogger LOG = Compiler.getLogger();
- if (LOG.isEnabled()) {
- LOG.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
+ final DebugLogger log = Global.instance().getLogger(Compiler.class);
+ if (log.isEnabled()) {
+ log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
}
return script;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java Tue Apr 22 14:09:46 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.runtime;
-
-import java.io.PrintWriter;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jdk.nashorn.internal.objects.Global;
-import jdk.nashorn.internal.runtime.events.RuntimeEvent;
-import jdk.nashorn.internal.runtime.options.Options;
-
-/**
- * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
- */
-
-public final class DebugLogger {
- private final Logger logger;
- private final boolean isEnabled;
-
- private int indent;
-
- private static final int INDENT_SPACE = 4;
-
- /** A quiet logger only logs {@link RuntimeEvent}s and does't output any text, regardless of level */
- private final boolean isQuiet;
-
- /**
- * Constructor
- *
- * @param loggerName name of logger - this is the unique key with which it can be identified
- */
- public DebugLogger(final String loggerName) {
- this(loggerName, null);
- }
-
- /**
- * Constructor
- *
- * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
- *
- * @param loggerName name of logger - this is the unique key with which it can be identified
- * @param property system property activating the logger on {@code info} level
- */
- public DebugLogger(final String loggerName, final String property) {
- if (property != null && Options.getBooleanProperty(property)) {
- this.logger = Logging.getOrCreateLogger(loggerName, Level.INFO);
- } else {
- this.logger = Logging.getLogger(loggerName);
- }
- this.isQuiet = Logging.loggerIsQuiet(loggerName);
- assert logger != null;
- this.isEnabled = getLevel() != Level.OFF;
- }
-
- /**
- * Do not currently support chaining this with parent logger. Logger level null
- * means disabled
- * @return level
- */
- private Level getLevel() {
- return logger.getLevel() == null ? Level.OFF : logger.getLevel();
- }
-
- /**
- * Get the output writer for the logger. Loggers always default to
- * stderr for output as they are used mainly to output debug info
- *
- * Can be inherited so this should not be static.
- *
- * @return print writer for log output.
- */
- @SuppressWarnings("static-method")
- public PrintWriter getOutputStream() {
- return Context.getCurrentErr();
- }
-
- /**
- * Add quotes around a string
- * @param str string
- * @return quoted string
- */
- public static String quote(final String str) {
- if (str.isEmpty()) {
- return "''";
- }
-
- char startQuote = '\0';
- char endQuote = '\0';
- char quote = '\0';
-
- if (str.startsWith("\\") || str.startsWith("\"")) {
- startQuote = str.charAt(0);
- }
- if (str.endsWith("\\") || str.endsWith("\"")) {
- endQuote = str.charAt(str.length() - 1);
- }
-
- if (startQuote == '\0' || endQuote == '\0') {
- quote = startQuote == '\0' ? endQuote : startQuote;
- }
- if (quote == '\0') {
- quote = '\'';
- }
-
- return (startQuote == '\0' ? quote : startQuote) + str + (endQuote == '\0' ? quote : endQuote);
- }
-
- /**
- * Check if the logger is enabled
- * @return true if enabled
- */
- public boolean isEnabled() {
- return 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"
- *
- * @param pos indent position
- */
- public void indent(final int pos) {
- if (isEnabled) {
- indent += pos * INDENT_SPACE;
- }
- }
-
- /**
- * Add an indent position
- */
- public void indent() {
- indent += INDENT_SPACE;
- }
-
- /**
- * Unindent a position
- */
- public void unindent() {
- indent -= INDENT_SPACE;
- if (indent < 0) {
- indent = 0;
- }
- }
-
- private static void logEvent(final RuntimeEvent<?> event) {
- if (event != null) {
- final Global global = Context.getGlobal();
- if (global.has("Debug")) {
- final ScriptObject debug = (ScriptObject)global.get("Debug");
- final ScriptFunction addRuntimeEvent = (ScriptFunction)debug.get("addRuntimeEvent");
- ScriptRuntime.apply(addRuntimeEvent, debug, event);
- }
- }
- }
-
- /**
- * Check if the logger is above the level of detail given
- * @see java.util.logging.Level
- *
- * The higher the level, the more severe the warning
- *
- * @param level logging level
- * @return true if level is above the given one
- */
- public boolean levelCoarserThan(final Level level) {
- return getLevel().intValue() > level.intValue();
- }
-
- /**
- * Check if the logger is above or equal to the level
- * of detail given
- * @see java.util.logging.Level
- *
- * The higher the level, the more severe the warning
- *
- * @param level logging level
- * @return true if level is above the given one
- */
- public boolean levelCoarserThanOrEqual(final Level level) {
- return getLevel().intValue() >= level.intValue();
- }
-
- /**
- * Check if the logger is below the level of detail given
- * @see java.util.logging.Level
- *
- * The higher the level, the more severe the warning
- *
- * @param level logging level
- * @return true if level is above the given one
- */
- public boolean levelFinerThan(final Level level) {
- return getLevel().intValue() < level.intValue();
- }
-
- /**
- * Check if the logger is below or equal to the level
- * of detail given
- * @see java.util.logging.Level
- *
- * The higher the level, the more severe the warning
- *
- * @param level logging level
- * @return true if level is above the given one
- */
- public boolean levelFinerThanOrEqual(final Level level) {
- return getLevel().intValue() <= level.intValue();
- }
-
- /**
- * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
- * @param str the string to log
- */
- public void finest(final String str) {
- log(Level.FINEST, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void finest(final RuntimeEvent<?> event, final String str) {
- finest(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINEST} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void finest(final Object... objs) {
- log(Level.FINEST, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINEST} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void finest(final RuntimeEvent<?> event, final Object... objs) {
- finest(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINER} on this logger
- * @param str the string to log
- */
- public void finer(final String str) {
- log(Level.FINER, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINER} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void finer(final RuntimeEvent<?> event, final String str) {
- finer(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINER} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void finer(final Object... objs) {
- log(Level.FINER, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINER} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void finer(final RuntimeEvent<?> event, final Object... objs) {
- finer(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param str the string to log
- */
- public void fine(final String str) {
- log(Level.FINE, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void fine(final RuntimeEvent<?> event, final String str) {
- fine(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void fine(final Object... objs) {
- log(Level.FINE, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void fine(final RuntimeEvent<?> event, final Object... objs) {
- fine(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#CONFIG} on this logger
- * @param str the string to log
- */
- public void config(final String str) {
- log(Level.CONFIG, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#CONFIG} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void config(final RuntimeEvent<?> event, final String str) {
- config(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#CONFIG} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void config(final Object... objs) {
- log(Level.CONFIG, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#CONFIG} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void config(final RuntimeEvent<?> event, final Object... objs) {
- config(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#INFO} on this logger
- * @param str the string to log
- */
- public void info(final String str) {
- log(Level.INFO, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#INFO} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void info(final RuntimeEvent<?> event, final String str) {
- info(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void info(final Object... objs) {
- log(Level.INFO, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void info(final RuntimeEvent<?> event, final Object... objs) {
- info(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#WARNING} on this logger
- * @param str the string to log
- */
- public void warning(final String str) {
- log(Level.WARNING, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#WARNING} on this logger
- * @param event optional runtime event to log
- * @param str the string to log
- */
- public void warning(final RuntimeEvent<?> event, final String str) {
- warning(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void warning(final Object... objs) {
- log(Level.WARNING, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- * @param event optional runtime event to log
- */
- public void warning(final RuntimeEvent<?> event, final Object... objs) {
- warning(objs);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#SEVERE} on this logger
- * @param str the string to log
- */
- public void severe(final String str) {
- log(Level.SEVERE, str);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#SEVERE} on this logger
- * @param str the string to log
- * @param event optional runtime event to log
- */
- public void severe(final RuntimeEvent<?> event, final String str) {
- severe(str);
- logEvent(event);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void severe(final Object... objs) {
- log(Level.SEVERE, objs);
- }
-
- /**
- * Shorthand for outputting a log string as log level
- * {@link java.util.logging.Level#FINE} on this logger
- * @param event optional runtime event to log
- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
- */
- public void severe(final RuntimeEvent<?> event, final Object... objs) {
- severe(objs);
- logEvent(event);
- }
-
- /**
- * Output log line on this logger at a given level of verbosity
- * @see java.util.logging.Level
- *
- * @param level minimum log level required for logging to take place
- * @param str string to log
- */
- public void log(final Level level, final String str) {
- if (isEnabled && !isQuiet) {
- final StringBuilder sb = new StringBuilder();
- for (int i = 0 ; i < indent ; i++) {
- sb.append(' ');
- }
- sb.append(str);
- logger.log(level, sb.toString());
- }
- }
-
- /**
- * Output log line on this logger at a given level of verbosity
- * @see java.util.logging.Level
- *
- * @param level minimum log level required for logging to take place
- * @param objs objects for which to invoke toString and concatenate to log
- */
- public void log(final Level level, final Object... objs) {
- if (isEnabled && !isQuiet) {
- final StringBuilder sb = new StringBuilder();
- for (final Object obj : objs) {
- sb.append(obj);
- }
- log(level, sb.toString());
- }
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java Wed Apr 23 16:13:47 2014 +0200
@@ -26,7 +26,8 @@
package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
-import static jdk.nashorn.internal.runtime.DebugLogger.quote;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
+import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
@@ -43,7 +44,11 @@
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;
+import jdk.nashorn.internal.runtime.logging.Logger;
/**
* Each global owns one of these. This is basically table of accessors
@@ -67,21 +72,10 @@
* a receiver guard on the constant getter, but it currently leaks memory and its benefits
* have not yet been investigated property.
*/
-public final class GlobalConstants {
-
- private GlobalConstants() {
- //singleton
- }
-
- /**
- * Return the singleton global constant pool
- * @return singleton global constant pool
- */
- public static GlobalConstants instance() {
- return instance;
- }
-
- private static final GlobalConstants instance = new GlobalConstants();
+@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.
@@ -92,11 +86,11 @@
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
- private static final MethodHandle INVALIDATE_SP = staticCall(LOOKUP, GlobalConstants.class, "invalidateSwitchPoint", Object.class, Object.class, Access.class).methodHandle();
+ private static final MethodHandle INVALIDATE_SP = virtualCall(LOOKUP, GlobalConstants.class, "invalidateSwitchPoint", Object.class, Object.class, Access.class).methodHandle();
private static final MethodHandle RECEIVER_GUARD = staticCall(LOOKUP, GlobalConstants.class, "receiverGuard", boolean.class, Access.class, Object.class, Object.class).methodHandle();
/** Logger for constant getters */
- private static final DebugLogger LOG = new DebugLogger("const");
+ private final DebugLogger log;
/**
* Access map for this global - associates a symbol name with an Access object, with getter
@@ -104,6 +98,32 @@
*/
private final Map<String, Access> map = new HashMap<>();
+ private GlobalConstants(final Global global) {
+ this.log = initLogger(global);
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @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;
+ }
+
/**
* Information about a constant access and its potential invalidations
*/
@@ -205,7 +225,7 @@
* will have changed.
*/
public 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()) {
acc.invalidateUncounted();
}
@@ -221,19 +241,19 @@
* @return receiver, so this can be used as param filter
*/
@SuppressWarnings("unused")
- private static Object invalidateSwitchPoint(final Object obj, final Access acc) {
- if (LOG.isEnabled()) {
- LOG.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc);
+ private Object invalidateSwitchPoint(final Object obj, final Access acc) {
+ if (log.isEnabled()) {
+ log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc);
}
acc.invalidateOnce();
if (acc.mayRetry()) {
- if (LOG.isEnabled()) {
- LOG.info("Retry is allowed for " + acc + "... Creating a new switchpoint.");
+ if (log.isEnabled()) {
+ log.info("Retry is allowed for " + acc + "... Creating a new switchpoint.");
}
acc.newSwitchPoint();
} else {
- if (LOG.isEnabled()) {
- LOG.info("This was the last time I allowed " + quote(acc.getName()) + " to relink as constant.");
+ if (log.isEnabled()) {
+ log.info("This was the last time I allowed " + quote(acc.getName()) + " to relink as constant.");
}
}
return obj;
@@ -310,32 +330,33 @@
final Access acc = getOrCreateSwitchPoint(name);
- if (LOG.isEnabled()) {
- LOG.fine("Trying to link constant SETTER ", acc);
+ if (log.isEnabled()) {
+ log.fine("Trying to link constant SETTER ", acc);
}
if (!acc.mayRetry()) {
- LOG.info("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation());
+ log.info("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation());
return null;
}
assert acc.mayRetry();
if (acc.hasBeenInvalidated()) {
- LOG.info("New chance for " + acc);
+ log.info("New chance for " + acc);
acc.newSwitchPoint();
}
assert !acc.hasBeenInvalidated();
// if we haven't given up on this symbol, add a switchpoint invalidation filter to the receiver parameter
- final MethodHandle target = inv.getInvocation();
- final Class<?> receiverType = target.type().parameterType(0);
- final MethodHandle invalidator = MH.asType(INVALIDATE_SP, INVALIDATE_SP.type().changeParameterType(0, receiverType).changeReturnType(receiverType));
- final MethodHandle mh = MH.filterArguments(inv.getInvocation(), 0, MH.insertArguments(invalidator, 1, acc));
+ final MethodHandle target = inv.getInvocation();
+ final Class<?> receiverType = target.type().parameterType(0);
+ final MethodHandle boundInvalidator = MH.bindTo(INVALIDATE_SP, this);
+ final MethodHandle invalidator = MH.asType(boundInvalidator, boundInvalidator.type().changeParameterType(0, receiverType).changeReturnType(receiverType));
+ final MethodHandle mh = MH.filterArguments(inv.getInvocation(), 0, MH.insertArguments(invalidator, 1, acc));
assert inv.getSwitchPoints() == null : Arrays.asList(inv.getSwitchPoints());
- LOG.info("Linked setter " + quote(name) + " " + acc.getSwitchPoint());
+ log.info("Linked setter " + quote(name) + " " + acc.getSwitchPoint());
return new GuardedInvocation(mh, inv.getGuard(), acc.getSwitchPoint(), inv.getException());
}
@@ -373,15 +394,15 @@
final Access acc = getOrCreateSwitchPoint(name);
- LOG.fine("Starting to look up object value " + name);
+ log.fine("Starting to look up object value " + name);
final Object c = find.getObjectValue();
- if (LOG.isEnabled()) {
- LOG.fine("Trying to link constant GETTER " + acc + " value = " + c);
+ if (log.isEnabled()) {
+ log.fine("Trying to link constant GETTER " + acc + " value = " + c);
}
if (acc.hasBeenInvalidated() || acc.guardFailed()) {
- LOG.fine("*** GET: Giving up on " + quote(name) + " - retry count has exceeded");
+ log.fine("*** GET: Giving up on " + quote(name) + " - retry count has exceeded");
return null;
}
@@ -409,9 +430,9 @@
guard = MH.insertArguments(RECEIVER_GUARD, 0, acc, receiver);
}
- if (LOG.isEnabled()) {
- LOG.info("Linked getter " + quote(name) + " as MethodHandle.constant() -> " + c + " " + acc.getSwitchPoint());
- mh = MethodHandleFactory.addDebugPrintout(LOG, Level.FINE, mh, "get const " + acc);
+ if (log.isEnabled()) {
+ log.info("Linked getter " + quote(name) + " as MethodHandle.constant() -> " + c + " " + acc.getSwitchPoint());
+ mh = MethodHandleFactory.addDebugPrintout(log, Level.FINE, mh, "get const " + acc);
}
return new GuardedInvocation(mh, guard, acc.getSwitchPoint(), null);
--- a/nashorn/src/jdk/nashorn/internal/runtime/Logging.java Tue Apr 22 14:09:46 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.runtime;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Permissions;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-import java.util.logging.LoggingPermission;
-
-/**
- * Logging system for getting loggers for arbitrary subsystems as
- * specified on the command line. Supports all standard log levels
- *
- */
-public final class Logging {
-
- private Logging() {
- }
-
- /** Loggers */
-
- private static final Logger disabledLogger = Logger.getLogger("disabled");
-
- private static AccessControlContext createLoggerControlAccCtxt() {
- final Permissions perms = new Permissions();
- perms.add(new LoggingPermission("control", null));
- return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
- }
-
- static {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- @Override
- public Void run() {
- Logging.disabledLogger.setLevel(Level.OFF);
- return null;
- }
- }, createLoggerControlAccCtxt());
- }
-
- /** Maps logger name to loggers. Names are typically per package */
- private static final Map<String, Logger> loggers = new HashMap<>();
-
- private static final Set<String> quietLoggers = new HashSet<>();
-
- private static String lastPart(final String packageName) {
- final String[] parts = packageName.split("\\.");
- if (parts.length == 0) {
- return packageName;
- }
- return parts[parts.length - 1];
- }
-
- /**
- * Get a logger for a given class, generating a logger name based on the
- * class name
- *
- * @param name the name to use as key for the logger
- * @return the logger
- */
- public static Logger getLogger(final String name) {
- final Logger logger = Logging.loggers.get(name);
- if (logger != null) {
- return logger;
- }
- return Logging.disabledLogger;
- }
-
- /**
- * Get a logger for a given name or create it if not already there, typically
- * used for mapping system properties to loggers
- *
- * @param name the name to use as key
- * @param level log lever to reset existing logger with, or create new logger with
- * @return the logger
- */
- public static Logger getOrCreateLogger(final String name, final Level level) {
- final Logger logger = Logging.loggers.get(name);
- if (logger == null) {
- return instantiateLogger(name, level);
- }
- logger.setLevel(level);
- return logger;
- }
-
- /**
- * Is this logger "quiet", i.e. does it put events in the debug event
- * queue, but refrains from printing anything?
- * @param name logger name
- * @return true if quiet
- */
- public static boolean loggerIsQuiet(final String name) {
- return quietLoggers.contains(name);
- }
-
- /**
- * Initialization function that is called to instantiate the logging system. It takes
- * logger names (keys) and logging labels respectively
- *
- * @param map a map where the key is a logger name and the value a logging level
- * @throws IllegalArgumentException if level or names cannot be parsed
- */
- public static void initialize(final Map<String, String> map) throws IllegalArgumentException {
- try {
- for (final Entry<String, String> entry : map.entrySet()) {
- Level level;
- final String key = entry.getKey();
- final String value = entry.getValue();
- final String name = Logging.lastPart(key);
-
- if ("".equals(value)) {
- level = Level.INFO;
- } else if ("quiet".equals(value)) {
- level = Level.INFO;
- quietLoggers.add(name);
- } else {
- level = Level.parse(value.toUpperCase(Locale.ENGLISH));
- }
-
- final Logger logger = instantiateLogger(name, level);
- Logging.loggers.put(name, logger);
- }
- } catch (final IllegalArgumentException | SecurityException e) {
- throw e;
- }
- }
-
- private static Logger instantiateLogger(final String name, final Level level) {
- final Logger logger = java.util.logging.Logger.getLogger(name);
- for (final Handler h : logger.getHandlers()) {
- logger.removeHandler(h);
- }
-
- logger.setLevel(level);
- logger.setUseParentHandlers(false);
- final Handler c = new ConsoleHandler();
-
- c.setFormatter(new Formatter() {
- @Override
- public String format(final LogRecord record) {
- final StringBuilder sb = new StringBuilder();
-
- sb.append('[')
- .append(record.getLoggerName())
- .append("] ")
- .append(record.getMessage())
- .append('\n');
-
- return sb.toString();
- }
- });
- logger.addHandler(c);
- c.setLevel(level);
-
- return logger;
- }
-
-}
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java Wed Apr 23 16:13:47 2014 +0200
@@ -172,7 +172,6 @@
*/
public PropertyHashMap immutableReplace(final Property property, final Property newProperty) {
assert property.getKey().equals(newProperty.getKey()) : "replacing properties with different keys: '" + property.getKey() + "' != '" + newProperty.getKey() + "'";
- assert property.hashCode() != newProperty.hashCode() : "replacing identical properties: '" + property + "'";
assert findElement(property.getKey()) != null : "replacing property that doesn't exist in map: '" + property.getKey() + "'";
return cloneMap().replaceNoClone(property.getKey(), newProperty);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Apr 23 16:13:47 2014 +0200
@@ -50,9 +50,13 @@
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;
+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;
/**
@@ -61,7 +65,8 @@
* The common denominator is that it can get new invokers during its lifespan,
* unlike {@code FinalScriptFunctionData}
*/
-public final class RecompilableScriptFunctionData extends ScriptFunctionData {
+@Logger(name="recompile")
+public final class RecompilableScriptFunctionData extends ScriptFunctionData implements Loggable {
/** Is lazy compilation enabled? TODO: this should be the default */
public static final boolean LAZY_COMPILATION = Options.getBooleanProperty("nashorn.lazy");
@@ -112,15 +117,7 @@
/** Unique id for classes needed to wrap recompiled script functions */
private static final AtomicInteger RECOMPILE_ID = new AtomicInteger(0);
- private static final DebugLogger LOG = new DebugLogger("recompile");
-
- /**
- * Get the recompilation logger
- * @return the logger
- */
- public static DebugLogger getLogger() {
- return LOG;
- }
+ private final DebugLogger log;
private final Map<String, Integer> externalScopeDepths;
@@ -174,6 +171,18 @@
assert nfn.getParent() == null;
nfn.setParent(this);
}
+
+ this.log = initLogger(Global.instance());
+ }
+
+ @Override
+ public DebugLogger getLogger() {
+ return log;
+ }
+
+ @Override
+ public DebugLogger initLogger(final Global global) {
+ return global.getLogger(this.getClass());
}
/**
@@ -400,8 +409,8 @@
}
MethodHandle compileRestOfMethod(final MethodType fnCallSiteType, final Map<Integer, Type> invalidatedProgramPoints, final int[] continuationEntryPoints, final ScriptObject runtimeScope, final FunctionNodeTransform tr) {
- if (LOG.isEnabled()) {
- LOG.info("Rest-of compilation of '", functionName, "' signature: ", fnCallSiteType, " ", stringifyInvalidations(invalidatedProgramPoints));
+ if (log.isEnabled()) {
+ log.info("Rest-of compilation of '", functionName, "' signature: ", fnCallSiteType, " ", stringifyInvalidations(invalidatedProgramPoints));
}
final String scriptName = RECOMPILATION_PREFIX + RECOMPILE_ID.incrementAndGet() + "$restOf";
@@ -434,8 +443,8 @@
final String scriptName = RECOMPILATION_PREFIX + RECOMPILE_ID.incrementAndGet();
final MethodType fnCallSiteType = actualCallSiteType == null ? null : actualCallSiteType.changeParameterType(0, ScriptFunction.class);
- if (LOG.isEnabled()) {
- LOG.info(reason, " of '", functionName, "' signature: ", fnCallSiteType, " ", stringifyInvalidations(invalidatedProgramPoints));
+ if (log.isEnabled()) {
+ log.info(reason, " of '", functionName, "' signature: ", fnCallSiteType, " ", stringifyInvalidations(invalidatedProgramPoints));
}
FunctionNode fn = tr.apply(reparse(scriptName));
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed Apr 23 16:13:47 2014 +0200
@@ -26,15 +26,20 @@
package jdk.nashorn.internal.runtime;
import java.io.PrintWriter;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimeZone;
+
import jdk.nashorn.internal.codegen.Namespace;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.options.KeyValueOption;
+import jdk.nashorn.internal.runtime.options.LoggingOption;
+import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
import jdk.nashorn.internal.runtime.options.Option;
import jdk.nashorn.internal.runtime.options.Options;
@@ -197,6 +202,9 @@
/** Local for error messages */
public final Locale _locale;
+ /** Logging */
+ public final Map<String, LoggerInfo> _loggers;
+
/**
* Constructor
*
@@ -310,6 +318,9 @@
} else {
this._locale = Locale.getDefault();
}
+
+ final LoggingOption lo = (LoggingOption)options.get("log");
+ this._loggers = lo == null ? new HashMap<String, LoggerInfo>() : lo.getLoggers();
}
/**
@@ -367,4 +378,15 @@
return options.getArguments();
}
+ /**
+ * Check if there is a logger registered for a particular name: typically
+ * the "name" attribute of a Loggable annotation on a class
+ *
+ * @param name logger name
+ * @return true, if a logger exists for that name, false otherwise
+ */
+ public boolean hasLogger(final String name) {
+ return _loggers.get(name) != null;
+ }
+
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Wed Apr 23 16:13:47 2014 +0200
@@ -681,7 +681,7 @@
if (isApplyToCall) {
if (isFailedApplyToCall) {
//take the real arguments that were passed to a call and force them into the apply instead
- ApplySpecialization.getLogger().info("Collection arguments to revert call to apply in " + appliedFn);
+ Global.instance().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);
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Apr 23 16:13:47 2014 +0200
@@ -918,7 +918,7 @@
if (property instanceof UserAccessorProperty) {
((UserAccessorProperty)property).setAccessors(this, getMap(), null);
}
- GlobalConstants.instance().delete(property.getKey());
+ GlobalConstants.instance(Global.instance()).delete(property.getKey());
return true;
}
}
@@ -1930,7 +1930,7 @@
}
}
- final GuardedInvocation cinv = GlobalConstants.instance().findGetMethod(find, this, desc, request, operator);
+ final GuardedInvocation cinv = GlobalConstants.instance(Global.instance()).findGetMethod(find, this, desc, request, operator);
if (cinv != null) {
return cinv;
}
@@ -1971,7 +1971,7 @@
}
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod, final boolean isScope) {
- ObjectClassGenerator.getLogger().warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
+ Global.instance().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 @@
final GuardedInvocation inv = new SetMethodCreator(this, find, desc, explicitInstanceOfCheck).createGuardedInvocation();
- final GuardedInvocation cinv = GlobalConstants.instance().findSetMethod(find, this, inv, desc, request);
+ final GuardedInvocation cinv = GlobalConstants.instance(Global.instance()).findSetMethod(find, this, inv, desc, request);
if (cinv != null) {
return cinv;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Wed Apr 23 16:13:47 2014 +0200
@@ -41,18 +41,22 @@
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.runtime.DebugLogger;
+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;
/**
* Interface implemented by all arrays that are directly accessible as underlying
* native arrays
*/
-public abstract class ContinuousArrayData extends ArrayData {
+@Logger(name="arrays")
+public abstract class ContinuousArrayData extends ArrayData implements Loggable {
/** Logger for array accessor linkage */
- protected static DebugLogger LOG = new DebugLogger("arrays");
+ protected final DebugLogger log;
private SwitchPoint sp;
@@ -62,6 +66,17 @@
*/
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() {
@@ -234,8 +249,8 @@
}
}
- if (LOG.isEnabled()) {
- LOG.info(getClass().getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
+ if (log.isEnabled()) {
+ log.info(getClass().getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null;
@@ -275,8 +290,8 @@
}
}
- if (LOG.isEnabled()) {
- LOG.info(getClass().getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
+ if (log.isEnabled()) {
+ log.info(getClass().getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null;
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java Wed Apr 23 16:13:47 2014 +0200
@@ -190,8 +190,8 @@
return inv;
}
- if (LOG.isEnabled()) {
- LOG.info(clazz.getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
+ if (log.isEnabled()) {
+ log.info(clazz.getSimpleName() + ": Missed fast GETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null;
@@ -205,8 +205,8 @@
return inv;
}
- if (LOG.isEnabled()) {
- LOG.info(clazz.getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
+ if (log.isEnabled()) {
+ log.info(clazz.getSimpleName() + ": Missed fast SETTER " + clazz.getSimpleName() + " " + desc + " " + " line:" + DynamicLinker.getLinkedCallSiteLocation().getLineNumber());
}
return null;
--- a/nashorn/src/jdk/nashorn/internal/runtime/events/RecompilationEvent.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/events/RecompilationEvent.java Wed Apr 23 16:13:47 2014 +0200
@@ -27,6 +27,7 @@
import java.util.logging.Level;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.RewriteException;
@@ -50,9 +51,10 @@
* {@link RewriteException#getReturnValueNonDestructive()} public, we pass it as
* an extra parameter, rather than querying the getter from another package.
*/
+ @SuppressWarnings("javadoc")
public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) {
super(level, rewriteException);
- assert RecompilableScriptFunctionData.getLogger().isEnabled() :
+ assert Global.instance().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;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/logging/DebugLogger.java Wed Apr 23 16:13:47 2014 +0200
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime.logging;
+
+import java.io.PrintWriter;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
+
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.events.RuntimeEvent;
+
+/**
+ * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
+ */
+
+public final class DebugLogger {
+
+ /** Disabled logger used for all loggers that need an instance, but shouldn't output anything */
+ public static final DebugLogger DISABLED_LOGGER = new DebugLogger("disabled", Level.OFF, false);
+
+ private final Logger logger;
+ private final boolean isEnabled;
+
+ private int indent;
+
+ private static final int INDENT_SPACE = 4;
+
+ /** A quiet logger only logs {@link RuntimeEvent}s and does't output any text, regardless of level */
+ private final boolean isQuiet;
+
+ /**
+ * Constructor
+ *
+ * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
+ *
+ * @param loggerName name of logger - this is the unique key with which it can be identified
+ * @param loggerLevel level of the logger
+ * @param isQuiet is this a quiet logger, i.e. enabled for things like e.g. RuntimeEvent:s, but quiet otherwise
+ */
+ public DebugLogger(final String loggerName, final Level loggerLevel, final boolean isQuiet) {
+ this.logger = instantiateLogger(loggerName, loggerLevel);
+ this.isQuiet = isQuiet;
+ assert logger != null;
+ this.isEnabled = getLevel() != Level.OFF;
+ }
+
+ private static Logger instantiateLogger(final String name, final Level level) {
+ final Logger logger = java.util.logging.Logger.getLogger(name);
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ for (final Handler h : logger.getHandlers()) {
+ logger.removeHandler(h);
+ }
+
+ logger.setLevel(level);
+ logger.setUseParentHandlers(false);
+ final Handler c = new ConsoleHandler();
+
+ c.setFormatter(new Formatter() {
+ @Override
+ public String format(final LogRecord record) {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append('[')
+ .append(record.getLoggerName())
+ .append("] ")
+ .append(record.getMessage())
+ .append('\n');
+
+ return sb.toString();
+ }
+ });
+ logger.addHandler(c);
+ c.setLevel(level);
+ return null;
+ }
+ }, createLoggerControlAccCtxt());
+
+ return logger;
+ }
+
+ /**
+ * Do not currently support chaining this with parent logger. Logger level null
+ * means disabled
+ * @return level
+ */
+ public Level getLevel() {
+ return logger.getLevel() == null ? Level.OFF : logger.getLevel();
+ }
+
+ /**
+ * Get the output writer for the logger. Loggers always default to
+ * stderr for output as they are used mainly to output debug info
+ *
+ * Can be inherited so this should not be static.
+ *
+ * @return print writer for log output.
+ */
+ @SuppressWarnings("static-method")
+ public PrintWriter getOutputStream() {
+ return Context.getCurrentErr();
+ }
+
+ /**
+ * Add quotes around a string
+ * @param str string
+ * @return quoted string
+ */
+ public static String quote(final String str) {
+ if (str.isEmpty()) {
+ return "''";
+ }
+
+ char startQuote = '\0';
+ char endQuote = '\0';
+ char quote = '\0';
+
+ if (str.startsWith("\\") || str.startsWith("\"")) {
+ startQuote = str.charAt(0);
+ }
+ if (str.endsWith("\\") || str.endsWith("\"")) {
+ endQuote = str.charAt(str.length() - 1);
+ }
+
+ if (startQuote == '\0' || endQuote == '\0') {
+ quote = startQuote == '\0' ? endQuote : startQuote;
+ }
+ if (quote == '\0') {
+ quote = '\'';
+ }
+
+ return (startQuote == '\0' ? quote : startQuote) + str + (endQuote == '\0' ? quote : endQuote);
+ }
+
+ /**
+ * Check if the logger is enabled
+ * @return true if enabled
+ */
+ public boolean isEnabled() {
+ return 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"
+ *
+ * @param pos indent position
+ */
+ public void indent(final int pos) {
+ if (isEnabled) {
+ indent += pos * INDENT_SPACE;
+ }
+ }
+
+ /**
+ * Add an indent position
+ */
+ public void indent() {
+ indent += INDENT_SPACE;
+ }
+
+ /**
+ * Unindent a position
+ */
+ public void unindent() {
+ indent -= INDENT_SPACE;
+ if (indent < 0) {
+ indent = 0;
+ }
+ }
+
+ private static void logEvent(final RuntimeEvent<?> event) {
+ if (event != null) {
+ final Global global = Context.getGlobal();
+ if (global.has("Debug")) {
+ final ScriptObject debug = (ScriptObject)global.get("Debug");
+ final ScriptFunction addRuntimeEvent = (ScriptFunction)debug.get("addRuntimeEvent");
+ ScriptRuntime.apply(addRuntimeEvent, debug, event);
+ }
+ }
+ }
+
+ /**
+ * Check if the logger is above the level of detail given
+ * @see java.util.logging.Level
+ *
+ * The higher the level, the more severe the warning
+ *
+ * @param level logging level
+ * @return true if level is above the given one
+ */
+ public boolean levelCoarserThan(final Level level) {
+ return getLevel().intValue() > level.intValue();
+ }
+
+ /**
+ * Check if the logger is above or equal to the level
+ * of detail given
+ * @see java.util.logging.Level
+ *
+ * The higher the level, the more severe the warning
+ *
+ * @param level logging level
+ * @return true if level is above the given one
+ */
+ public boolean levelCoarserThanOrEqual(final Level level) {
+ return getLevel().intValue() >= level.intValue();
+ }
+
+ /**
+ * Check if the logger is below the level of detail given
+ * @see java.util.logging.Level
+ *
+ * The higher the level, the more severe the warning
+ *
+ * @param level logging level
+ * @return true if level is above the given one
+ */
+ public boolean levelFinerThan(final Level level) {
+ return getLevel().intValue() < level.intValue();
+ }
+
+ /**
+ * Check if the logger is below or equal to the level
+ * of detail given
+ * @see java.util.logging.Level
+ *
+ * The higher the level, the more severe the warning
+ *
+ * @param level logging level
+ * @return true if level is above the given one
+ */
+ public boolean levelFinerThanOrEqual(final Level level) {
+ return getLevel().intValue() <= level.intValue();
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
+ * @param str the string to log
+ */
+ public void finest(final String str) {
+ log(Level.FINEST, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void finest(final RuntimeEvent<?> event, final String str) {
+ finest(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINEST} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void finest(final Object... objs) {
+ log(Level.FINEST, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINEST} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void finest(final RuntimeEvent<?> event, final Object... objs) {
+ finest(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINER} on this logger
+ * @param str the string to log
+ */
+ public void finer(final String str) {
+ log(Level.FINER, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINER} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void finer(final RuntimeEvent<?> event, final String str) {
+ finer(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINER} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void finer(final Object... objs) {
+ log(Level.FINER, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINER} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void finer(final RuntimeEvent<?> event, final Object... objs) {
+ finer(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param str the string to log
+ */
+ public void fine(final String str) {
+ log(Level.FINE, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void fine(final RuntimeEvent<?> event, final String str) {
+ fine(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void fine(final Object... objs) {
+ log(Level.FINE, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void fine(final RuntimeEvent<?> event, final Object... objs) {
+ fine(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#CONFIG} on this logger
+ * @param str the string to log
+ */
+ public void config(final String str) {
+ log(Level.CONFIG, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#CONFIG} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void config(final RuntimeEvent<?> event, final String str) {
+ config(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#CONFIG} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void config(final Object... objs) {
+ log(Level.CONFIG, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#CONFIG} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void config(final RuntimeEvent<?> event, final Object... objs) {
+ config(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#INFO} on this logger
+ * @param str the string to log
+ */
+ public void info(final String str) {
+ log(Level.INFO, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#INFO} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void info(final RuntimeEvent<?> event, final String str) {
+ info(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void info(final Object... objs) {
+ log(Level.INFO, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void info(final RuntimeEvent<?> event, final Object... objs) {
+ info(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#WARNING} on this logger
+ * @param str the string to log
+ */
+ public void warning(final String str) {
+ log(Level.WARNING, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#WARNING} on this logger
+ * @param event optional runtime event to log
+ * @param str the string to log
+ */
+ public void warning(final RuntimeEvent<?> event, final String str) {
+ warning(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void warning(final Object... objs) {
+ log(Level.WARNING, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ * @param event optional runtime event to log
+ */
+ public void warning(final RuntimeEvent<?> event, final Object... objs) {
+ warning(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#SEVERE} on this logger
+ * @param str the string to log
+ */
+ public void severe(final String str) {
+ log(Level.SEVERE, str);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#SEVERE} on this logger
+ * @param str the string to log
+ * @param event optional runtime event to log
+ */
+ public void severe(final RuntimeEvent<?> event, final String str) {
+ severe(str);
+ logEvent(event);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void severe(final Object... objs) {
+ log(Level.SEVERE, objs);
+ }
+
+ /**
+ * Shorthand for outputting a log string as log level
+ * {@link java.util.logging.Level#FINE} on this logger
+ * @param event optional runtime event to log
+ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+ */
+ public void severe(final RuntimeEvent<?> event, final Object... objs) {
+ severe(objs);
+ logEvent(event);
+ }
+
+ /**
+ * Output log line on this logger at a given level of verbosity
+ * @see java.util.logging.Level
+ *
+ * @param level minimum log level required for logging to take place
+ * @param str string to log
+ */
+ public void log(final Level level, final String str) {
+ if (isEnabled && !isQuiet) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0 ; i < indent ; i++) {
+ sb.append(' ');
+ }
+ sb.append(str);
+ logger.log(level, sb.toString());
+ }
+ }
+
+ /**
+ * Output log line on this logger at a given level of verbosity
+ * @see java.util.logging.Level
+ *
+ * @param level minimum log level required for logging to take place
+ * @param objs objects for which to invoke toString and concatenate to log
+ */
+ public void log(final Level level, final Object... objs) {
+ if (isEnabled && !isQuiet) {
+ final StringBuilder sb = new StringBuilder();
+ for (final Object obj : objs) {
+ sb.append(obj);
+ }
+ log(level, sb.toString());
+ }
+ }
+
+ /**
+ * Access control context for logger level and instantiation permissions
+ * @return access control context
+ */
+ private static AccessControlContext createLoggerControlAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new LoggingPermission("control", null));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/logging/Loggable.java Wed Apr 23 16:13:47 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.nashorn.internal.runtime.logging;
+
+import jdk.nashorn.internal.objects.Global;
+
+/**
+ * Interface implemented by classes that are loggable.
+ * Their instances will provide functionality for initializing
+ * a logger (usually by asking Global for it, with a reference
+ * to this.getClass()) and a method to return the logger in
+ * use
+ *
+ * Typically a class implementing this interface also has the
+ * Logger annotation
+ *
+ * @see Logger
+ */
+public interface Loggable {
+ /**
+ * Initialize a logger, by asking Global to get or create it
+ * and then keep it in a table by name
+ *
+ * @param global global
+ * @return the initialized logger
+ */
+ public DebugLogger initLogger(final Global global);
+
+ /**
+ * Return the logger in use
+ * @return logger
+ */
+ public DebugLogger getLogger();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/logging/Logger.java Wed Apr 23 16:13:47 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.nashorn.internal.runtime.logging;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation is associated with a class that has a logger.
+ * It contains a name property of the logger name. e.g. a class
+ * whose logger can be initialized by --log:fields, should be
+ * annotated @Logger(name="fields"). Multiple classes can have
+ * the same annotation, which will make them use the same logger
+ * object. Usually a class with this annotation is also a Loggable,
+ * but it is not a hard demand
+ *
+ * @see Loggable
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Logger {
+ /**
+ * Get the name of the logger
+ * @return logger name
+ */
+ public String name() default "";
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java Wed Apr 23 16:13:47 2014 +0200
@@ -36,7 +36,7 @@
*
* {@code --log=module1:level1,module2:level2... }
*/
-public final class KeyValueOption extends Option<String> {
+public class KeyValueOption extends Option<String> {
/**
* Map of keys given
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/LoggingOption.java Wed Apr 23 16:13:47 2014 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime.options;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+
+/**
+ * Class that collects logging options like --log=compiler:finest,fields,recompile:fine into
+ * a map form that can be used to instantiate loggers in the Global object on demand
+ */
+public class LoggingOption extends KeyValueOption {
+
+ /**
+ * Logging info. Basically a logger name maps to this,
+ * which is a tuple of log level and the "is quiet" flag,
+ * which is a special log level used to collect RuntimeEvents
+ * only, but not output anything
+ */
+ public static class LoggerInfo {
+ private final Level level;
+ private final boolean isQuiet;
+
+ LoggerInfo(final Level level, final boolean isQuiet) {
+ this.level = level;
+ this.isQuiet = isQuiet;
+ }
+
+ /**
+ * Get the log level
+ * @return log level
+ */
+ public Level getLevel() {
+ return level;
+ }
+
+ /**
+ * Get the quiet flag
+ * @return true if quiet flag is set
+ */
+ public boolean isQuiet() {
+ return isQuiet;
+ }
+ }
+
+ private final Map<String, LoggerInfo> loggers = new HashMap<>();
+
+ LoggingOption(final String value) {
+ super(value);
+ initialize(getValues());
+ }
+
+ /**
+ * Return the logger info collected from this command line option
+ *
+ * @return map of logger name to logger info
+ */
+ public Map<String, LoggerInfo> getLoggers() {
+ return Collections.unmodifiableMap(loggers);
+ }
+
+ /**
+ * Initialization function that is called to instantiate the logging system. It takes
+ * logger names (keys) and logging labels respectively
+ *
+ * @param map a map where the key is a logger name and the value a logging level
+ * @throws IllegalArgumentException if level or names cannot be parsed
+ */
+ private void initialize(final Map<String, String> logMap) throws IllegalArgumentException {
+ try {
+ for (final Entry<String, String> entry : logMap.entrySet()) {
+ Level level;
+ final String name = lastPart(entry.getKey());
+ final String levelString = entry.getValue().toUpperCase(Locale.ENGLISH);
+ final boolean isQuiet;
+
+ if ("".equals(levelString)) {
+ level = Level.INFO;
+ isQuiet = false;
+ } else if ("QUIET".equals(levelString)) {
+ level = Level.INFO;
+ isQuiet = true;
+ } else {
+ level = Level.parse(levelString);
+ isQuiet = false;
+ }
+
+ loggers.put(name, new LoggerInfo(level, isQuiet));
+ }
+ } catch (final IllegalArgumentException | SecurityException e) {
+ throw e;
+ }
+ }
+
+
+
+ private static String lastPart(final String packageName) {
+ final String[] parts = packageName.split("\\.");
+ if (parts.length == 0) {
+ return packageName;
+ }
+ return parts[parts.length - 1];
+ }
+
+
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Wed Apr 23 16:13:47 2014 +0200
@@ -48,7 +48,6 @@
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
-import jdk.nashorn.internal.runtime.Logging;
import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
/**
@@ -532,9 +531,7 @@
case "keyvalues":
return new KeyValueOption(value);
case "log":
- final KeyValueOption kv = new KeyValueOption(value);
- Logging.initialize(kv.getValues());
- return kv;
+ return new LoggingOption(value);
case "boolean":
return new Option<>(value != null && Boolean.parseBoolean(value));
case "integer":
--- a/nashorn/src/jdk/nashorn/tools/Shell.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java Wed Apr 23 16:13:47 2014 +0200
@@ -178,7 +178,6 @@
*
* @return null if there are problems with option parsing.
*/
- @SuppressWarnings("resource")
private static Context makeContext(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) {
final PrintStream pout = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
final PrintStream perr = err instanceof PrintStream ? (PrintStream) err : new PrintStream(err);
@@ -392,7 +391,6 @@
* @param global global scope object to use
* @return return code
*/
- @SuppressWarnings("resource")
private static int readEvalPrint(final Context context, final Global global) {
final String prompt = bundle.getString("shell.prompt");
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
--- a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Wed Apr 23 16:13:47 2014 +0200
@@ -50,7 +50,7 @@
public boolean exclude(File file, String content);
}
- private void log(String msg) {
+ private static void log(final String msg) {
org.testng.Reporter.log(msg, true);
}
@@ -63,7 +63,7 @@
options.set("parse.only", true);
options.set("scripting", true);
- ErrorManager errors = new ErrorManager();
+ final ErrorManager errors = new ErrorManager();
this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
}
@@ -153,7 +153,7 @@
}
};
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();
if (errors.getNumberOfErrors() > 0) {
log("Parse failed: " + file.getAbsolutePath());
@@ -162,6 +162,7 @@
passed++;
}
} catch (final Throwable exp) {
+ exp.printStackTrace();
log("Parse failed: " + file.getAbsolutePath() + " : " + exp);
if (VERBOSE) {
exp.printStackTrace(System.out);
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java Tue Apr 22 14:09:46 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java Wed Apr 23 16:13:47 2014 +0200
@@ -149,7 +149,7 @@
}
@Override
- protected void log(String msg) {
+ protected void log(final String msg) {
System.err.println(msg);
}
@@ -235,6 +235,7 @@
outputFile.write(out.toByteArray());
errorFile.write(err.toByteArray());
}
+ ex.printStackTrace();
throw ex;
}
}
@@ -280,6 +281,7 @@
} catch (final Throwable ex) {
result.exception = ex;
result.passed = false;
+ ex.printStackTrace();
}
return result;
}
@@ -306,12 +308,12 @@
final TestFactory<ScriptRunnable> testFactory = new TestFactory<ScriptRunnable>() {
@Override
- public ScriptRunnable createTest(String framework, File testFile, List<String> engineOptions, Map<String, String> testOptions, List<String> arguments) {
+ public ScriptRunnable createTest(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> arguments) {
return new ScriptRunnable(framework, testFile, engineOptions, testOptions, arguments);
}
@Override
- public void log(String msg) {
+ public void log(final String msg) {
System.err.println(msg);
}
};
@@ -431,7 +433,9 @@
public static void main(final String[] args) throws Exception {
parseArgs(args);
- while(new ParallelTestRunner().run());
+ while(new ParallelTestRunner().run()) {
+ ;
+ }
}
private static void parseArgs(final String[] args) {