Wed, 29 Apr 2015 14:05:42 -0700
Merge
1.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Apr 29 12:16:43 2015 -0700 1.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Apr 29 14:05:42 2015 -0700 1.3 @@ -4526,7 +4526,7 @@ 1.4 } 1.5 1.6 if (addInitializer && !compiler.isOnDemandCompilation()) { 1.7 - compiler.addFunctionInitializer(data, functionNode); 1.8 + functionNode.getCompileUnit().addFunctionInitializer(data, functionNode); 1.9 } 1.10 1.11 // We don't emit a ScriptFunction on stack for the outermost compiled function (as there's no code being
2.1 --- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed Apr 29 12:16:43 2015 -0700 2.2 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed Apr 29 14:05:42 2015 -0700 2.3 @@ -57,7 +57,6 @@ 2.4 import jdk.nashorn.internal.ir.debug.PrintVisitor; 2.5 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 2.6 import jdk.nashorn.internal.runtime.CodeInstaller; 2.7 -import jdk.nashorn.internal.runtime.FunctionInitializer; 2.8 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; 2.9 import jdk.nashorn.internal.runtime.ScriptEnvironment; 2.10 import jdk.nashorn.internal.runtime.logging.DebugLogger; 2.11 @@ -581,18 +580,7 @@ 2.12 continue; 2.13 } 2.14 unit.setCode(installedClasses.get(unit.getUnitClassName())); 2.15 - } 2.16 - 2.17 - if (!compiler.isOnDemandCompilation()) { 2.18 - // Initialize functions 2.19 - final Map<Integer, FunctionInitializer> initializers = compiler.getFunctionInitializers(); 2.20 - if (initializers != null) { 2.21 - for (final Entry<Integer, FunctionInitializer> entry : initializers.entrySet()) { 2.22 - final FunctionInitializer initializer = entry.getValue(); 2.23 - initializer.setCode(installedClasses.get(initializer.getClassName())); 2.24 - compiler.getScriptFunctionData(entry.getKey()).initializeCode(initializer); 2.25 - } 2.26 - } 2.27 + unit.initializeFunctionsCode(); 2.28 } 2.29 2.30 if (log.isEnabled()) {
3.1 --- a/src/jdk/nashorn/internal/codegen/CompileUnit.java Wed Apr 29 12:16:43 2015 -0700 3.2 +++ b/src/jdk/nashorn/internal/codegen/CompileUnit.java Wed Apr 29 14:05:42 2015 -0700 3.3 @@ -26,10 +26,16 @@ 3.4 package jdk.nashorn.internal.codegen; 3.5 3.6 import java.io.Serializable; 3.7 +import java.util.Collection; 3.8 +import java.util.Collections; 3.9 +import java.util.IdentityHashMap; 3.10 +import java.util.Map; 3.11 import java.util.Objects; 3.12 import java.util.Set; 3.13 import java.util.TreeSet; 3.14 import jdk.nashorn.internal.ir.CompileUnitHolder; 3.15 +import jdk.nashorn.internal.ir.FunctionNode; 3.16 +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; 3.17 3.18 /** 3.19 * Used to track split class compilation. Note that instances of the class are serializable, but all fields are 3.20 @@ -50,6 +56,8 @@ 3.21 3.22 private transient Class<?> clazz; 3.23 3.24 + private transient Map<FunctionNode, RecompilableScriptFunctionData> functions = new IdentityHashMap<>(); 3.25 + 3.26 private transient boolean isUsed; 3.27 3.28 private static int emittedUnitCount; 3.29 @@ -121,6 +129,32 @@ 3.30 this.classEmitter = null; 3.31 } 3.32 3.33 + void addFunctionInitializer(final RecompilableScriptFunctionData data, final FunctionNode functionNode) { 3.34 + functions.put(functionNode, data); 3.35 + } 3.36 + 3.37 + /** 3.38 + * Returns true if this compile unit is responsible for initializing the specified function data with specified 3.39 + * function node. 3.40 + * @param data the function data to check 3.41 + * @param functionNode the function node to check 3.42 + * @return true if this unit is responsible for initializing the function data with the function node, otherwise 3.43 + * false 3.44 + */ 3.45 + public boolean isInitializing(final RecompilableScriptFunctionData data, final FunctionNode functionNode) { 3.46 + return functions.get(functionNode) == data; 3.47 + } 3.48 + 3.49 + void initializeFunctionsCode() { 3.50 + for(final Map.Entry<FunctionNode, RecompilableScriptFunctionData> entry : functions.entrySet()) { 3.51 + entry.getValue().initializeCode(entry.getKey()); 3.52 + } 3.53 + } 3.54 + 3.55 + Collection<FunctionNode> getFunctionNodes() { 3.56 + return Collections.unmodifiableCollection(functions.keySet()); 3.57 + } 3.58 + 3.59 /** 3.60 * Add weight to this compile unit 3.61 * @param w weight to add
4.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java Wed Apr 29 12:16:43 2015 -0700 4.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java Wed Apr 29 14:05:42 2015 -0700 4.3 @@ -565,7 +565,7 @@ 4.4 * @return a copy of this compiler's current mapping of invalidated optimistic program points to their types. 4.5 */ 4.6 public Map<Integer, Type> getInvalidatedProgramPoints() { 4.7 - return invalidatedProgramPoints == null ? null : new TreeMap<>(invalidatedProgramPoints); 4.8 + return invalidatedProgramPoints.isEmpty() ? null : new TreeMap<>(invalidatedProgramPoints); 4.9 } 4.10 4.11 TypeMap getTypeMap() { 4.12 @@ -704,21 +704,6 @@ 4.13 return sb.toString(); 4.14 } 4.15 4.16 - Map<Integer, FunctionInitializer> functionInitializers; 4.17 - 4.18 - void addFunctionInitializer(final RecompilableScriptFunctionData functionData, final FunctionNode functionNode) { 4.19 - if (functionInitializers == null) { 4.20 - functionInitializers = new HashMap<>(); 4.21 - } 4.22 - if (!functionInitializers.containsKey(functionData)) { 4.23 - functionInitializers.put(functionData.getFunctionNodeId(), new FunctionInitializer(functionNode)); 4.24 - } 4.25 - } 4.26 - 4.27 - Map<Integer, FunctionInitializer> getFunctionInitializers() { 4.28 - return functionInitializers; 4.29 - } 4.30 - 4.31 /** 4.32 * Persist current compilation with the given {@code cacheKey}. 4.33 * @param cacheKey cache key 4.34 @@ -726,15 +711,17 @@ 4.35 */ 4.36 public void persistClassInfo(final String cacheKey, final FunctionNode functionNode) { 4.37 if (cacheKey != null && env._persistent_cache) { 4.38 - Map<Integer, FunctionInitializer> initializers; 4.39 // If this is an on-demand compilation create a function initializer for the function being compiled. 4.40 // Otherwise use function initializer map generated by codegen. 4.41 - if (functionInitializers == null) { 4.42 - initializers = new HashMap<>(); 4.43 - final FunctionInitializer initializer = new FunctionInitializer(functionNode, getInvalidatedProgramPoints()); 4.44 - initializers.put(functionNode.getId(), initializer); 4.45 + Map<Integer, FunctionInitializer> initializers = new HashMap<>(); 4.46 + if (isOnDemandCompilation()) { 4.47 + initializers.put(functionNode.getId(), new FunctionInitializer(functionNode, getInvalidatedProgramPoints())); 4.48 } else { 4.49 - initializers = functionInitializers; 4.50 + for (final CompileUnit compileUnit : getCompileUnits()) { 4.51 + for (final FunctionNode fn : compileUnit.getFunctionNodes()) { 4.52 + initializers.put(fn.getId(), new FunctionInitializer(fn)); 4.53 + } 4.54 + } 4.55 } 4.56 final String mainClassName = getFirstCompileUnit().getUnitClassName(); 4.57 installer.storeScript(cacheKey, source, mainClassName, bytecode, initializers, constantData.toArray(), compilationId);
5.1 --- a/src/jdk/nashorn/internal/codegen/TypeEvaluator.java Wed Apr 29 12:16:43 2015 -0700 5.2 +++ b/src/jdk/nashorn/internal/codegen/TypeEvaluator.java Wed Apr 29 14:05:42 2015 -0700 5.3 @@ -227,7 +227,8 @@ 5.4 // gradually introduce them as needed. An easy one would be to do the same for .call(this) idiom. 5.5 final CallNode callExpr = (CallNode)expr; 5.6 final Expression fnExpr = callExpr.getFunction(); 5.7 - if (fnExpr instanceof FunctionNode) { 5.8 + // Skip evaluation if running with eager compilation as we may violate constraints in RecompilableScriptFunctionData 5.9 + if (fnExpr instanceof FunctionNode && compiler.getContext().getEnv()._lazy_compilation) { 5.10 final FunctionNode fn = (FunctionNode)fnExpr; 5.11 if (callExpr.getArgs().isEmpty()) { 5.12 final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(fn.getId());
6.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Wed Apr 29 12:16:43 2015 -0700 6.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Wed Apr 29 14:05:42 2015 -0700 6.3 @@ -1281,7 +1281,7 @@ 6.4 compiler.persistClassInfo(cacheKey, compiledFunction); 6.5 } else { 6.6 Compiler.updateCompilationId(storedScript.getCompilationId()); 6.7 - script = install(storedScript, source, installer); 6.8 + script = storedScript.installScript(source, installer); 6.9 } 6.10 6.11 cacheClass(source, script); 6.12 @@ -1303,51 +1303,6 @@ 6.13 } 6.14 6.15 /** 6.16 - * Install a previously compiled class from the code cache. 6.17 - * 6.18 - * @param storedScript cached script containing class bytes and constants 6.19 - * @return main script class 6.20 - */ 6.21 - private static Class<?> install(final StoredScript storedScript, final Source source, final CodeInstaller<ScriptEnvironment> installer) { 6.22 - 6.23 - final Map<String, Class<?>> installedClasses = new HashMap<>(); 6.24 - final Map<String, byte[]> classBytes = storedScript.getClassBytes(); 6.25 - final Object[] constants = storedScript.getConstants(); 6.26 - final String mainClassName = storedScript.getMainClassName(); 6.27 - final byte[] mainClassBytes = classBytes.get(mainClassName); 6.28 - final Class<?> mainClass = installer.install(mainClassName, mainClassBytes); 6.29 - final Map<Integer, FunctionInitializer> initializers = storedScript.getInitializers(); 6.30 - 6.31 - installedClasses.put(mainClassName, mainClass); 6.32 - 6.33 - for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) { 6.34 - final String className = entry.getKey(); 6.35 - if (className.equals(mainClassName)) { 6.36 - continue; 6.37 - } 6.38 - final byte[] code = entry.getValue(); 6.39 - 6.40 - installedClasses.put(className, installer.install(className, code)); 6.41 - } 6.42 - 6.43 - installer.initialize(installedClasses.values(), source, constants); 6.44 - 6.45 - for (final Object constant : constants) { 6.46 - if (constant instanceof RecompilableScriptFunctionData) { 6.47 - final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constant; 6.48 - data.initTransients(source, installer); 6.49 - final FunctionInitializer initializer = initializers.get(data.getFunctionNodeId()); 6.50 - if (initializer != null) { 6.51 - initializer.setCode(installedClasses.get(initializer.getClassName())); 6.52 - data.initializeCode(initializer); 6.53 - } 6.54 - } 6.55 - } 6.56 - 6.57 - return mainClass; 6.58 - } 6.59 - 6.60 - /** 6.61 * Cache for compiled script classes. 6.62 */ 6.63 @SuppressWarnings("serial")
7.1 --- a/src/jdk/nashorn/internal/runtime/FunctionInitializer.java Wed Apr 29 12:16:43 2015 -0700 7.2 +++ b/src/jdk/nashorn/internal/runtime/FunctionInitializer.java Wed Apr 29 14:05:42 2015 -0700 7.3 @@ -60,17 +60,6 @@ 7.4 } 7.5 7.6 /** 7.7 - * Copy constructor. 7.8 - * 7.9 - * @param init original initializer 7.10 - */ 7.11 - FunctionInitializer(final FunctionInitializer init) { 7.12 - this.className = init.getClassName(); 7.13 - this.methodType = init.getMethodType(); 7.14 - this.flags = init.getFlags(); 7.15 - } 7.16 - 7.17 - /** 7.18 * Constructor. 7.19 * 7.20 * @param functionNode the function node 7.21 @@ -130,7 +119,7 @@ 7.22 * Set the class implementing the function 7.23 * @param code the class 7.24 */ 7.25 - public void setCode(final Class<?> code) { 7.26 + void setCode(final Class<?> code) { 7.27 // Make sure code has not been set and has expected class name 7.28 if (this.code != null) { 7.29 throw new IllegalStateException("code already set");
8.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Apr 29 12:16:43 2015 -0700 8.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Apr 29 14:05:42 2015 -0700 8.3 @@ -32,7 +32,6 @@ 8.4 import java.lang.invoke.MethodType; 8.5 import java.util.Collection; 8.6 import java.util.Collections; 8.7 -import java.util.HashMap; 8.8 import java.util.HashSet; 8.9 import java.util.Map; 8.10 import java.util.Set; 8.11 @@ -503,7 +502,7 @@ 8.12 8.13 if (script != null) { 8.14 Compiler.updateCompilationId(script.getCompilationId()); 8.15 - return installStoredScript(script, newInstaller); 8.16 + return script.installFunction(this, newInstaller); 8.17 } 8.18 } 8.19 8.20 @@ -518,56 +517,6 @@ 8.21 return new FunctionInitializer(compiledFn, compiler.getInvalidatedProgramPoints()); 8.22 } 8.23 8.24 - private static Map<String, Class<?>> installStoredScriptClasses(final StoredScript script, final CodeInstaller<ScriptEnvironment> installer) { 8.25 - final Map<String, Class<?>> installedClasses = new HashMap<>(); 8.26 - final Map<String, byte[]> classBytes = script.getClassBytes(); 8.27 - final String mainClassName = script.getMainClassName(); 8.28 - final byte[] mainClassBytes = classBytes.get(mainClassName); 8.29 - 8.30 - final Class<?> mainClass = installer.install(mainClassName, mainClassBytes); 8.31 - 8.32 - installedClasses.put(mainClassName, mainClass); 8.33 - 8.34 - for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) { 8.35 - final String className = entry.getKey(); 8.36 - final byte[] bytecode = entry.getValue(); 8.37 - 8.38 - if (className.equals(mainClassName)) { 8.39 - continue; 8.40 - } 8.41 - 8.42 - installedClasses.put(className, installer.install(className, bytecode)); 8.43 - } 8.44 - return installedClasses; 8.45 - } 8.46 - 8.47 - /** 8.48 - * Install this script using the given {@code installer}. 8.49 - * 8.50 - * @param script the compiled script 8.51 - * @return the function initializer 8.52 - */ 8.53 - private FunctionInitializer installStoredScript(final StoredScript script, final CodeInstaller<ScriptEnvironment> newInstaller) { 8.54 - final Map<String, Class<?>> installedClasses = installStoredScriptClasses(script, newInstaller); 8.55 - 8.56 - final Map<Integer, FunctionInitializer> initializers = script.getInitializers(); 8.57 - assert initializers != null; 8.58 - assert initializers.size() == 1; 8.59 - final FunctionInitializer initializer = initializers.values().iterator().next(); 8.60 - 8.61 - final Object[] constants = script.getConstants(); 8.62 - for (int i = 0; i < constants.length; i++) { 8.63 - if (constants[i] instanceof RecompilableScriptFunctionData) { 8.64 - // replace deserialized function data with the ones we already have 8.65 - constants[i] = getScriptFunctionData(((RecompilableScriptFunctionData) constants[i]).getFunctionNodeId()); 8.66 - } 8.67 - } 8.68 - 8.69 - newInstaller.initialize(installedClasses.values(), source, constants); 8.70 - initializer.setCode(installedClasses.get(initializer.getClassName())); 8.71 - return initializer; 8.72 - } 8.73 - 8.74 boolean usePersistentCodeCache() { 8.75 final ScriptEnvironment env = installer.getOwner(); 8.76 return env._persistent_cache && env._optimistic_types; 8.77 @@ -645,13 +594,21 @@ 8.78 * by the compiler internals in Nashorn and is public for implementation reasons only. Attempting to invoke it 8.79 * externally will result in an exception. 8.80 * 8.81 - * @param initializer FunctionInitializer for this data 8.82 + * @param functionNode FunctionNode for this data 8.83 */ 8.84 - public void initializeCode(final FunctionInitializer initializer) { 8.85 + public void initializeCode(final FunctionNode functionNode) { 8.86 // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit. 8.87 - if(!code.isEmpty()) { 8.88 + if (!code.isEmpty() || functionNode.getId() != functionNodeId || !functionNode.getCompileUnit().isInitializing(this, functionNode)) { 8.89 throw new IllegalStateException(name); 8.90 } 8.91 + addCode(lookup(functionNode), null, null, functionNode.getFlags()); 8.92 + } 8.93 + 8.94 + /** 8.95 + * Initializes this function with the given function code initializer. 8.96 + * @param initializer function code initializer 8.97 + */ 8.98 + void initializeCode(final FunctionInitializer initializer) { 8.99 addCode(lookup(initializer, true), null, null, initializer.getFlags()); 8.100 } 8.101
9.1 --- a/src/jdk/nashorn/internal/runtime/StoredScript.java Wed Apr 29 12:16:43 2015 -0700 9.2 +++ b/src/jdk/nashorn/internal/runtime/StoredScript.java Wed Apr 29 14:05:42 2015 -0700 9.3 @@ -27,7 +27,7 @@ 9.4 9.5 import java.io.Serializable; 9.6 import java.util.Arrays; 9.7 -import java.util.LinkedHashMap; 9.8 +import java.util.HashMap; 9.9 import java.util.Map; 9.10 9.11 /** 9.12 @@ -77,44 +77,70 @@ 9.13 return compilationId; 9.14 } 9.15 9.16 - /** 9.17 - * Returns the main class name. 9.18 - * @return the main class name 9.19 - */ 9.20 - public String getMainClassName() { 9.21 - return mainClassName; 9.22 + private Map<String, Class<?>> installClasses(final Source source, final CodeInstaller<ScriptEnvironment> installer) { 9.23 + final Map<String, Class<?>> installedClasses = new HashMap<>(); 9.24 + final byte[] mainClassBytes = classBytes.get(mainClassName); 9.25 + final Class<?> mainClass = installer.install(mainClassName, mainClassBytes); 9.26 + 9.27 + installedClasses.put(mainClassName, mainClass); 9.28 + 9.29 + for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) { 9.30 + final String className = entry.getKey(); 9.31 + 9.32 + if (!className.equals(mainClassName)) { 9.33 + installedClasses.put(className, installer.install(className, entry.getValue())); 9.34 + } 9.35 + } 9.36 + 9.37 + installer.initialize(installedClasses.values(), source, constants); 9.38 + return installedClasses; 9.39 + } 9.40 + 9.41 + FunctionInitializer installFunction(final RecompilableScriptFunctionData data, final CodeInstaller<ScriptEnvironment> installer) { 9.42 + final Map<String, Class<?>> installedClasses = installClasses(data.getSource(), installer); 9.43 + 9.44 + assert initializers != null; 9.45 + assert initializers.size() == 1; 9.46 + final FunctionInitializer initializer = initializers.values().iterator().next(); 9.47 + 9.48 + for (int i = 0; i < constants.length; i++) { 9.49 + if (constants[i] instanceof RecompilableScriptFunctionData) { 9.50 + // replace deserialized function data with the ones we already have 9.51 + final RecompilableScriptFunctionData newData = data.getScriptFunctionData(((RecompilableScriptFunctionData) constants[i]).getFunctionNodeId()); 9.52 + assert newData != null; 9.53 + newData.initTransients(data.getSource(), installer); 9.54 + constants[i] = newData; 9.55 + } 9.56 + } 9.57 + 9.58 + initializer.setCode(installedClasses.get(initializer.getClassName())); 9.59 + return initializer; 9.60 } 9.61 9.62 /** 9.63 - * Returns a map of class names to class bytes. 9.64 - * @return map of class bytes 9.65 + * Install as script. 9.66 + * 9.67 + * @param source the source 9.68 + * @param installer the installer 9.69 + * @return main script class 9.70 */ 9.71 - public Map<String, byte[]> getClassBytes() { 9.72 - final Map<String, byte[]> clonedMap = new LinkedHashMap<>(); 9.73 - for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) { 9.74 - clonedMap.put(entry.getKey(), entry.getValue().clone()); 9.75 + Class<?> installScript(final Source source, final CodeInstaller<ScriptEnvironment> installer) { 9.76 + 9.77 + final Map<String, Class<?>> installedClasses = installClasses(source, installer); 9.78 + 9.79 + for (final Object constant : constants) { 9.80 + if (constant instanceof RecompilableScriptFunctionData) { 9.81 + final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constant; 9.82 + data.initTransients(source, installer); 9.83 + final FunctionInitializer initializer = initializers.get(data.getFunctionNodeId()); 9.84 + if (initializer != null) { 9.85 + initializer.setCode(installedClasses.get(initializer.getClassName())); 9.86 + data.initializeCode(initializer); 9.87 + } 9.88 + } 9.89 } 9.90 - return clonedMap; 9.91 - } 9.92 9.93 - /** 9.94 - * Returns the constants array. 9.95 - * @return constants array 9.96 - */ 9.97 - public Object[] getConstants() { 9.98 - return constants.clone(); 9.99 - } 9.100 - 9.101 - /** 9.102 - * Returns the function initializers map. 9.103 - * @return The initializers map. 9.104 - */ 9.105 - public Map<Integer, FunctionInitializer> getInitializers() { 9.106 - final Map<Integer, FunctionInitializer> clonedMap = new LinkedHashMap<>(); 9.107 - for (final Map.Entry<Integer, FunctionInitializer> entry : initializers.entrySet()) { 9.108 - clonedMap.put(entry.getKey(), new FunctionInitializer(entry.getValue())); 9.109 - } 9.110 - return clonedMap; 9.111 + return installedClasses.get(mainClassName); 9.112 } 9.113 9.114 @Override
10.1 --- a/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Wed Apr 29 12:16:43 2015 -0700 10.2 +++ b/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Wed Apr 29 14:05:42 2015 -0700 10.3 @@ -26,7 +26,7 @@ 10.4 package jdk.nashorn.internal.runtime.regexp; 10.5 10.6 import java.util.Collections; 10.7 -import java.util.Set; 10.8 +import java.util.Map; 10.9 import java.util.WeakHashMap; 10.10 import jdk.nashorn.internal.runtime.ParserException; 10.11 import jdk.nashorn.internal.runtime.options.Options; 10.12 @@ -45,11 +45,10 @@ 10.13 /** Weak cache of already validated regexps - when reparsing, we don't, for example 10.14 * need to recompile (reverify) all regexps that have previously been parsed by this 10.15 * RegExpFactory in a previous compilation. This saves significant time in e.g. avatar 10.16 - * startup */ 10.17 - private static final Set<String> VALID_CACHE_SET = 10.18 - Collections.newSetFromMap( 10.19 - Collections.synchronizedMap( 10.20 - new WeakHashMap<String, Boolean>())); 10.21 + * startup 10.22 + */ 10.23 + private static final Map<String, RegExp> REGEXP_CACHE = 10.24 + Collections.synchronizedMap(new WeakHashMap<String, RegExp>()); 10.25 10.26 static { 10.27 final String impl = Options.getStringProperty("nashorn.regexp.impl", JONI); 10.28 @@ -87,7 +86,13 @@ 10.29 * @throws ParserException if invalid source or flags 10.30 */ 10.31 public static RegExp create(final String pattern, final String flags) { 10.32 - return instance.compile(pattern, flags); 10.33 + final String key = pattern + "/" + flags; 10.34 + RegExp regexp = REGEXP_CACHE.get(key); 10.35 + if (regexp == null) { 10.36 + regexp = instance.compile(pattern, flags); 10.37 + REGEXP_CACHE.put(key, regexp); 10.38 + } 10.39 + return regexp; 10.40 } 10.41 10.42 /** 10.43 @@ -98,11 +103,8 @@ 10.44 * 10.45 * @throws ParserException if invalid source or flags 10.46 */ 10.47 - // @SuppressWarnings({"unused"}) 10.48 public static void validate(final String pattern, final String flags) throws ParserException { 10.49 - if (VALID_CACHE_SET.add(pattern + flags)) { 10.50 - instance.compile(pattern, flags); 10.51 - } 10.52 + create(pattern, flags); 10.53 } 10.54 10.55 /**
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/script/basic/JDK-8053905.js Wed Apr 29 14:05:42 2015 -0700 11.3 @@ -0,0 +1,38 @@ 11.4 +/* 11.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +/** 11.28 + * JDK-8053905: Eager code generation fails for earley boyer with split threshold set to 1000 11.29 + * 11.30 + * @test 11.31 + * @runif external.octane 11.32 + * @fork 11.33 + * @option -Dnashorn.compiler.splitter.threshold=1000 11.34 + * @option -scripting 11.35 + * @option --lazy-compilation=false 11.36 + */ 11.37 + 11.38 +var fn = __DIR__ + 'compile-octane.js'; 11.39 +arguments.push("earley-boyer"); // run only earley-boyer 11.40 +var url = new java.io.File(fn).toURL(); 11.41 +load(url);
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/script/basic/JDK-8053905.js.EXPECTED Wed Apr 29 14:05:42 2015 -0700 12.3 @@ -0,0 +1,2 @@ 12.4 +Compiling 'earley-boyer'... 12.5 +Done.
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/script/basic/JDK-8066407.js Wed Apr 29 14:05:42 2015 -0700 13.3 @@ -0,0 +1,48 @@ 13.4 +/* 13.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. 13.11 + * 13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.15 + * version 2 for more details (a copy is included in the LICENSE file that 13.16 + * accompanied this code). 13.17 + * 13.18 + * You should have received a copy of the GNU General Public License version 13.19 + * 2 along with this work; if not, write to the Free Software Foundation, 13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.21 + * 13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.23 + * or visit www.oracle.com if you need additional information or have any 13.24 + * questions. 13.25 + */ 13.26 + 13.27 +/** 13.28 + * JDK-8066407: Function with same body not reparsed after SyntaxError 13.29 + * 13.30 + * @test 13.31 + * @run 13.32 + */ 13.33 + 13.34 +function testFunction(body) { 13.35 + try { 13.36 + Function(body); 13.37 + Assert.fail("Should have thrown"); 13.38 + } catch (e) { 13.39 + Assert.assertEquals(e.name, "SyntaxError"); 13.40 + count++; 13.41 + } 13.42 + 13.43 +} 13.44 + 13.45 +var count = 0; 13.46 + 13.47 +testFunction("/a/r"); 13.48 +testFunction("/a/r"); 13.49 +testFunction("/a/r"); 13.50 + 13.51 +Assert.assertTrue(count === 3);
14.1 --- a/test/script/basic/compile-octane-splitter.js Wed Apr 29 12:16:43 2015 -0700 14.2 +++ b/test/script/basic/compile-octane-splitter.js Wed Apr 29 14:05:42 2015 -0700 14.3 @@ -29,11 +29,10 @@ 14.4 * forever, so make this test future safe, we specify them explicitly 14.5 * 14.6 * @test 14.7 + * @runif external.octane 14.8 * @fork 14.9 + * @option -scripting 14.10 * @option -Dnashorn.compiler.splitter.threshold=1000 14.11 - * @fork 14.12 - * @runif external.octane 14.13 - * @option -scripting 14.14 * @option -Dnashorn.typeInfo.disabled=true 14.15 * @option --class-cache-size=0 14.16 * @option --persistent-code-cache=false
15.1 --- a/test/src/jdk/nashorn/api/scripting/test/ScriptEngineTest.java Wed Apr 29 12:16:43 2015 -0700 15.2 +++ b/test/src/jdk/nashorn/api/scripting/test/ScriptEngineTest.java Wed Apr 29 14:05:42 2015 -0700 15.3 @@ -676,41 +676,6 @@ 15.4 assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", "")); 15.5 } 15.6 15.7 - // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. 15.8 - @Test 15.9 - public void functionalInterfaceStringTest() throws Exception { 15.10 - final ScriptEngineManager manager = new ScriptEngineManager(); 15.11 - final ScriptEngine e = manager.getEngineByName("nashorn"); 15.12 - final AtomicBoolean invoked = new AtomicBoolean(false); 15.13 - e.put("f", new Function<String, String>() { 15.14 - @Override 15.15 - public String apply(String t) { 15.16 - invoked.set(true); 15.17 - return t; 15.18 - } 15.19 - }); 15.20 - assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); 15.21 - assertTrue(invoked.get()); 15.22 - } 15.23 - 15.24 - // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. 15.25 - @Test 15.26 - public void functionalInterfaceObjectTest() throws Exception { 15.27 - final ScriptEngineManager manager = new ScriptEngineManager(); 15.28 - final ScriptEngine e = manager.getEngineByName("nashorn"); 15.29 - final AtomicBoolean invoked = new AtomicBoolean(false); 15.30 - e.put("c", new Consumer<Object>() { 15.31 - @Override 15.32 - public void accept(Object t) { 15.33 - assertTrue(t instanceof ScriptObjectMirror); 15.34 - assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); 15.35 - invoked.set(true); 15.36 - } 15.37 - }); 15.38 - e.eval("var x = 'xy'; x += 'z';c({a:x})"); 15.39 - assertTrue(invoked.get()); 15.40 - } 15.41 - 15.42 // @bug 8068524: NashornScriptEngineFactory.getParameter() throws IAE 15.43 // for an unknown key, doesn't conform to the general spec 15.44 @Test