8022524: Memory leaks in nashorn sources and tests found by jhat analysis

Thu, 08 Aug 2013 16:38:32 +0530

author
sundar
date
Thu, 08 Aug 2013 16:38:32 +0530
changeset 489
dd79c04ef7df
parent 488
9a3e3bb30db3
child 490
0d7484bf8597
child 491
14ea21d58f83

8022524: Memory leaks in nashorn sources and tests found by jhat analysis
Reviewed-by: attila, hannesw

make/project.properties file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/CompileUnit.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/Global.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/NativeArray.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/NativeDate.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/NativeJSON.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/NativeObject.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/GlobalObject.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/JSONFunctions.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ListAdapter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptFunction.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/UserAccessorProperty.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8020357.js file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/codegen/CompilerTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/parser/ParserTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/make/project.properties	Wed Aug 07 16:38:44 2013 +0200
     1.2 +++ b/make/project.properties	Thu Aug 08 16:38:32 2013 +0530
     1.3 @@ -223,9 +223,9 @@
     1.4  run.test.user.country=TR
     1.5  
     1.6  #  -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
     1.7 -run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country}
     1.8 +run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError
     1.9  
    1.10 -#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M  
    1.11 +#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M  
    1.12  run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
    1.13  
    1.14  run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
     2.1 --- a/src/jdk/nashorn/internal/codegen/CompileUnit.java	Wed Aug 07 16:38:44 2013 +0200
     2.2 +++ b/src/jdk/nashorn/internal/codegen/CompileUnit.java	Thu Aug 08 16:38:32 2013 +0530
     2.3 @@ -33,7 +33,7 @@
     2.4      private final String className;
     2.5  
     2.6      /** Current class generator */
     2.7 -    private final ClassEmitter classEmitter;
     2.8 +    private ClassEmitter classEmitter;
     2.9  
    2.10      private long weight;
    2.11  
    2.12 @@ -64,7 +64,11 @@
    2.13       * @param clazz class with code for this compile unit
    2.14       */
    2.15      void setCode(final Class<?> clazz) {
    2.16 +        clazz.getClass(); // null check
    2.17          this.clazz = clazz;
    2.18 +        // Revisit this - refactor to avoid null-ed out non-final fields
    2.19 +        // null out emitter
    2.20 +        this.classEmitter = null;
    2.21      }
    2.22  
    2.23      /**
     3.1 --- a/src/jdk/nashorn/internal/objects/Global.java	Wed Aug 07 16:38:44 2013 +0200
     3.2 +++ b/src/jdk/nashorn/internal/objects/Global.java	Thu Aug 08 16:38:32 2013 +0530
     3.3 @@ -41,6 +41,8 @@
     3.4  import java.util.LinkedHashMap;
     3.5  import java.util.List;
     3.6  import java.util.Map;
     3.7 +import java.util.concurrent.Callable;
     3.8 +import java.util.concurrent.ConcurrentHashMap;
     3.9  import jdk.internal.dynalink.linker.GuardedInvocation;
    3.10  import jdk.internal.dynalink.linker.LinkRequest;
    3.11  import jdk.nashorn.internal.objects.annotations.Attribute;
    3.12 @@ -72,8 +74,8 @@
    3.13   */
    3.14  @ScriptClass("Global")
    3.15  public final class Global extends ScriptObject implements GlobalObject, Scope {
    3.16 -    private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
    3.17 -    private static final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
    3.18 +    private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
    3.19 +    private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
    3.20  
    3.21      /** ECMA 15.1.2.2 parseInt (string , radix) */
    3.22      @Property(attributes = Attribute.NOT_ENUMERABLE)
    3.23 @@ -709,6 +711,35 @@
    3.24          classCache.put(source, new SoftReference<Class<?>>(clazz));
    3.25      }
    3.26  
    3.27 +    private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
    3.28 +        final T obj = map.get(key);
    3.29 +        if (obj != null) {
    3.30 +            return obj;
    3.31 +        }
    3.32 +
    3.33 +        try {
    3.34 +            final T newObj = creator.call();
    3.35 +            final T existingObj = map.putIfAbsent(key, newObj);
    3.36 +            return existingObj != null ? existingObj : newObj;
    3.37 +        } catch (final Exception exp) {
    3.38 +            throw new RuntimeException(exp);
    3.39 +        }
    3.40 +    }
    3.41 +
    3.42 +    private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
    3.43 +
    3.44 +    @Override
    3.45 +    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
    3.46 +        return getLazilyCreatedValue(key, creator, namedInvokers);
    3.47 +    }
    3.48 +
    3.49 +    private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
    3.50 +
    3.51 +    @Override
    3.52 +    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
    3.53 +        return getLazilyCreatedValue(key, creator, dynamicInvokers);
    3.54 +    }
    3.55 +
    3.56      /**
    3.57       * This is the eval used when 'indirect' eval call is made.
    3.58       *
     4.1 --- a/src/jdk/nashorn/internal/objects/NativeArray.java	Wed Aug 07 16:38:44 2013 +0200
     4.2 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Thu Aug 08 16:38:32 2013 +0530
     4.3 @@ -39,6 +39,7 @@
     4.4  import java.util.Comparator;
     4.5  import java.util.Iterator;
     4.6  import java.util.List;
     4.7 +import java.util.concurrent.Callable;
     4.8  import jdk.nashorn.api.scripting.ScriptObjectMirror;
     4.9  import jdk.nashorn.internal.objects.annotations.Attribute;
    4.10  import jdk.nashorn.internal.objects.annotations.Constructor;
    4.11 @@ -68,20 +69,88 @@
    4.12   */
    4.13  @ScriptClass("Array")
    4.14  public final class NativeArray extends ScriptObject {
    4.15 -    private static final InvokeByName JOIN = new InvokeByName("join", ScriptObject.class);
    4.16 +    private static final Object JOIN                     = new Object();
    4.17 +    private static final Object EVERY_CALLBACK_INVOKER   = new Object();
    4.18 +    private static final Object SOME_CALLBACK_INVOKER    = new Object();
    4.19 +    private static final Object FOREACH_CALLBACK_INVOKER = new Object();
    4.20 +    private static final Object MAP_CALLBACK_INVOKER     = new Object();
    4.21 +    private static final Object FILTER_CALLBACK_INVOKER  = new Object();
    4.22 +    private static final Object REDUCE_CALLBACK_INVOKER  = new Object();
    4.23 +    private static final Object CALL_CMP                 = new Object();
    4.24 +    private static final Object TO_LOCALE_STRING         = new Object();
    4.25  
    4.26 -    private static final MethodHandle EVERY_CALLBACK_INVOKER   = createIteratorCallbackInvoker(boolean.class);
    4.27 -    private static final MethodHandle SOME_CALLBACK_INVOKER    = createIteratorCallbackInvoker(boolean.class);
    4.28 -    private static final MethodHandle FOREACH_CALLBACK_INVOKER = createIteratorCallbackInvoker(void.class);
    4.29 -    private static final MethodHandle MAP_CALLBACK_INVOKER     = createIteratorCallbackInvoker(Object.class);
    4.30 -    private static final MethodHandle FILTER_CALLBACK_INVOKER  = createIteratorCallbackInvoker(boolean.class);
    4.31 +    private static InvokeByName getJOIN() {
    4.32 +        return Global.instance().getInvokeByName(JOIN,
    4.33 +                new Callable<InvokeByName>() {
    4.34 +                    @Override
    4.35 +                    public InvokeByName call() {
    4.36 +                        return new InvokeByName("join", ScriptObject.class);
    4.37 +                    }
    4.38 +                });
    4.39 +    }
    4.40  
    4.41 -    private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
    4.42 -            Object.class, Undefined.class, Object.class, Object.class, long.class, Object.class);
    4.43 -    private static final MethodHandle CALL_CMP                = Bootstrap.createDynamicInvoker("dyn:call", double.class,
    4.44 -            ScriptFunction.class, Object.class, Object.class, Object.class);
    4.45 +    private static MethodHandle createIteratorCallbackInvoker(final Object key, final Class<?> rtype) {
    4.46 +        return Global.instance().getDynamicInvoker(key,
    4.47 +            new Callable<MethodHandle>() {
    4.48 +                @Override
    4.49 +                public MethodHandle call() {
    4.50 +                    return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
    4.51 +                        long.class, Object.class);
    4.52 +                }
    4.53 +            });
    4.54 +    }
    4.55  
    4.56 -    private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
    4.57 +    private static MethodHandle getEVERY_CALLBACK_INVOKER() {
    4.58 +        return createIteratorCallbackInvoker(EVERY_CALLBACK_INVOKER, boolean.class);
    4.59 +    }
    4.60 +
    4.61 +    private static MethodHandle getSOME_CALLBACK_INVOKER() {
    4.62 +        return createIteratorCallbackInvoker(SOME_CALLBACK_INVOKER, boolean.class);
    4.63 +    }
    4.64 +
    4.65 +    private static MethodHandle getFOREACH_CALLBACK_INVOKER() {
    4.66 +        return createIteratorCallbackInvoker(FOREACH_CALLBACK_INVOKER, void.class);
    4.67 +    }
    4.68 +
    4.69 +    private static MethodHandle getMAP_CALLBACK_INVOKER() {
    4.70 +        return createIteratorCallbackInvoker(MAP_CALLBACK_INVOKER, Object.class);
    4.71 +    }
    4.72 +
    4.73 +    private static MethodHandle getFILTER_CALLBACK_INVOKER() {
    4.74 +        return createIteratorCallbackInvoker(FILTER_CALLBACK_INVOKER, boolean.class);
    4.75 +    }
    4.76 +
    4.77 +    private static MethodHandle getREDUCE_CALLBACK_INVOKER() {
    4.78 +        return Global.instance().getDynamicInvoker(REDUCE_CALLBACK_INVOKER,
    4.79 +                new Callable<MethodHandle>() {
    4.80 +                    @Override
    4.81 +                    public MethodHandle call() {
    4.82 +                        return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class,
    4.83 +                             Undefined.class, Object.class, Object.class, long.class, Object.class);
    4.84 +                    }
    4.85 +                });
    4.86 +    }
    4.87 +
    4.88 +    private static MethodHandle getCALL_CMP() {
    4.89 +        return Global.instance().getDynamicInvoker(CALL_CMP,
    4.90 +                new Callable<MethodHandle>() {
    4.91 +                    @Override
    4.92 +                    public MethodHandle call() {
    4.93 +                        return Bootstrap.createDynamicInvoker("dyn:call", double.class,
    4.94 +                            ScriptFunction.class, Object.class, Object.class, Object.class);
    4.95 +                    }
    4.96 +                });
    4.97 +    }
    4.98 +
    4.99 +    private static InvokeByName getTO_LOCALE_STRING() {
   4.100 +        return Global.instance().getInvokeByName(TO_LOCALE_STRING,
   4.101 +                new Callable<InvokeByName>() {
   4.102 +                    @Override
   4.103 +                    public InvokeByName call() {
   4.104 +                        return new InvokeByName("toLocaleString", ScriptObject.class, String.class);
   4.105 +                    }
   4.106 +                });
   4.107 +    }
   4.108  
   4.109      // initialized by nasgen
   4.110      private static PropertyMap $nasgenmap$;
   4.111 @@ -357,11 +426,12 @@
   4.112      public static Object toString(final Object self) {
   4.113          final Object obj = Global.toObject(self);
   4.114          if (obj instanceof ScriptObject) {
   4.115 +            final InvokeByName joinInvoker = getJOIN();
   4.116              final ScriptObject sobj = (ScriptObject)obj;
   4.117              try {
   4.118 -                final Object join = JOIN.getGetter().invokeExact(sobj);
   4.119 +                final Object join = joinInvoker.getGetter().invokeExact(sobj);
   4.120                  if (Bootstrap.isCallable(join)) {
   4.121 -                    return JOIN.getInvoker().invokeExact(join, sobj);
   4.122 +                    return joinInvoker.getInvoker().invokeExact(join, sobj);
   4.123                  }
   4.124              } catch (final RuntimeException | Error e) {
   4.125                  throw e;
   4.126 @@ -393,11 +463,12 @@
   4.127  
   4.128                  try {
   4.129                      if (val instanceof ScriptObject) {
   4.130 +                        final InvokeByName localeInvoker = getTO_LOCALE_STRING();
   4.131                          final ScriptObject sobj           = (ScriptObject)val;
   4.132 -                        final Object       toLocaleString = TO_LOCALE_STRING.getGetter().invokeExact(sobj);
   4.133 +                        final Object       toLocaleString = localeInvoker.getGetter().invokeExact(sobj);
   4.134  
   4.135                          if (Bootstrap.isCallable(toLocaleString)) {
   4.136 -                            sb.append((String)TO_LOCALE_STRING.getInvoker().invokeExact(toLocaleString, sobj));
   4.137 +                            sb.append((String)localeInvoker.getInvoker().invokeExact(toLocaleString, sobj));
   4.138                          } else {
   4.139                              throw typeError("not.a.function", "toLocaleString");
   4.140                          }
   4.141 @@ -814,6 +885,7 @@
   4.142          final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
   4.143  
   4.144          Collections.sort(list, new Comparator<Object>() {
   4.145 +            private final MethodHandle call_cmp = getCALL_CMP();
   4.146              @Override
   4.147              public int compare(final Object x, final Object y) {
   4.148                  if (x == ScriptRuntime.UNDEFINED && y == ScriptRuntime.UNDEFINED) {
   4.149 @@ -826,7 +898,7 @@
   4.150  
   4.151                  if (cmp != null) {
   4.152                      try {
   4.153 -                        return (int)Math.signum((double)CALL_CMP.invokeExact(cmp, cmpThis, x, y));
   4.154 +                        return (int)Math.signum((double)call_cmp.invokeExact(cmp, cmpThis, x, y));
   4.155                      } catch (final RuntimeException | Error e) {
   4.156                          throw e;
   4.157                      } catch (final Throwable t) {
   4.158 @@ -1103,9 +1175,11 @@
   4.159  
   4.160      private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) {
   4.161          return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) {
   4.162 +            private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER();
   4.163 +
   4.164              @Override
   4.165              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.166 -                return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
   4.167 +                return (result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self));
   4.168              }
   4.169          }.apply();
   4.170      }
   4.171 @@ -1121,9 +1195,11 @@
   4.172      @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
   4.173      public static Object some(final Object self, final Object callbackfn, final Object thisArg) {
   4.174          return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
   4.175 +            private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
   4.176 +
   4.177              @Override
   4.178              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.179 -                return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
   4.180 +                return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self));
   4.181              }
   4.182          }.apply();
   4.183      }
   4.184 @@ -1139,9 +1215,11 @@
   4.185      @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
   4.186      public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) {
   4.187          return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) {
   4.188 +            private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER();
   4.189 +
   4.190              @Override
   4.191              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.192 -                FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
   4.193 +                forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self);
   4.194                  return true;
   4.195              }
   4.196          }.apply();
   4.197 @@ -1158,9 +1236,11 @@
   4.198      @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
   4.199      public static Object map(final Object self, final Object callbackfn, final Object thisArg) {
   4.200          return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
   4.201 +            private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
   4.202 +
   4.203              @Override
   4.204              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.205 -                final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
   4.206 +                final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self);
   4.207                  result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r);
   4.208                  return true;
   4.209              }
   4.210 @@ -1186,10 +1266,11 @@
   4.211      public static Object filter(final Object self, final Object callbackfn, final Object thisArg) {
   4.212          return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) {
   4.213              private long to = 0;
   4.214 +            private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
   4.215  
   4.216              @Override
   4.217              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.218 -                if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) {
   4.219 +                if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) {
   4.220                      result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val);
   4.221                  }
   4.222                  return true;
   4.223 @@ -1217,10 +1298,12 @@
   4.224  
   4.225          //if initial value is ScriptRuntime.UNDEFINED - step forward once.
   4.226          return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) {
   4.227 +            private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER();
   4.228 +
   4.229              @Override
   4.230              protected boolean forEach(final Object val, final long i) throws Throwable {
   4.231                  // TODO: why can't I declare the second arg as Undefined.class?
   4.232 -                result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
   4.233 +                result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
   4.234                  return true;
   4.235              }
   4.236          }.apply();
   4.237 @@ -1273,10 +1356,4 @@
   4.238  
   4.239          return false;
   4.240      }
   4.241 -
   4.242 -    private static MethodHandle createIteratorCallbackInvoker(final Class<?> rtype) {
   4.243 -        return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
   4.244 -                long.class, Object.class);
   4.245 -
   4.246 -    }
   4.247  }
     5.1 --- a/src/jdk/nashorn/internal/objects/NativeDate.java	Wed Aug 07 16:38:44 2013 +0200
     5.2 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Thu Aug 08 16:38:32 2013 +0530
     5.3 @@ -33,6 +33,7 @@
     5.4  
     5.5  import java.util.Locale;
     5.6  import java.util.TimeZone;
     5.7 +import java.util.concurrent.Callable;
     5.8  import jdk.nashorn.internal.objects.annotations.Attribute;
     5.9  import jdk.nashorn.internal.objects.annotations.Constructor;
    5.10  import jdk.nashorn.internal.objects.annotations.Function;
    5.11 @@ -95,8 +96,17 @@
    5.12              "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    5.13      };
    5.14  
    5.15 -    private static final InvokeByName TO_ISO_STRING = new InvokeByName("toISOString", ScriptObject.class, Object.class,
    5.16 -            Object.class);
    5.17 +    private static final Object TO_ISO_STRING = new Object();
    5.18 +
    5.19 +    private static InvokeByName getTO_ISO_STRING() {
    5.20 +        return Global.instance().getInvokeByName(TO_ISO_STRING,
    5.21 +                new Callable<InvokeByName>() {
    5.22 +                    @Override
    5.23 +                    public InvokeByName call() {
    5.24 +                        return new InvokeByName("toISOString", ScriptObject.class, Object.class, Object.class);
    5.25 +                    }
    5.26 +                });
    5.27 +    }
    5.28  
    5.29      private double time;
    5.30      private final TimeZone timezone;
    5.31 @@ -861,9 +871,10 @@
    5.32          }
    5.33  
    5.34          try {
    5.35 -            final Object func = TO_ISO_STRING.getGetter().invokeExact(sobj);
    5.36 +            final InvokeByName toIsoString = getTO_ISO_STRING();
    5.37 +            final Object func = toIsoString.getGetter().invokeExact(sobj);
    5.38              if (Bootstrap.isCallable(func)) {
    5.39 -                return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
    5.40 +                return toIsoString.getInvoker().invokeExact(func, sobj, key);
    5.41              }
    5.42              throw typeError("not.a.function", ScriptRuntime.safeToString(func));
    5.43          } catch (final RuntimeException | Error e) {
     6.1 --- a/src/jdk/nashorn/internal/objects/NativeJSON.java	Wed Aug 07 16:38:44 2013 +0200
     6.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSON.java	Thu Aug 08 16:38:32 2013 +0530
     6.3 @@ -35,6 +35,7 @@
     6.4  import java.util.Iterator;
     6.5  import java.util.List;
     6.6  import java.util.Map;
     6.7 +import java.util.concurrent.Callable;
     6.8  import jdk.nashorn.internal.objects.annotations.Attribute;
     6.9  import jdk.nashorn.internal.objects.annotations.Function;
    6.10  import jdk.nashorn.internal.objects.annotations.ScriptClass;
    6.11 @@ -55,9 +56,31 @@
    6.12   */
    6.13  @ScriptClass("JSON")
    6.14  public final class NativeJSON extends ScriptObject {
    6.15 -    private static final InvokeByName TO_JSON = new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
    6.16 -    private static final MethodHandle REPLACER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
    6.17 -            ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
    6.18 +    private static final Object TO_JSON = new Object();
    6.19 +
    6.20 +    private static InvokeByName getTO_JSON() {
    6.21 +        return Global.instance().getInvokeByName(TO_JSON,
    6.22 +                new Callable<InvokeByName>() {
    6.23 +                    @Override
    6.24 +                    public InvokeByName call() {
    6.25 +                        return new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
    6.26 +                    }
    6.27 +                });
    6.28 +    }
    6.29 +
    6.30 +
    6.31 +    private static final Object REPLACER_INVOKER = new Object();
    6.32 +
    6.33 +    private static MethodHandle getREPLACER_INVOKER() {
    6.34 +        return Global.instance().getDynamicInvoker(REPLACER_INVOKER,
    6.35 +                new Callable<MethodHandle>() {
    6.36 +                    @Override
    6.37 +                    public MethodHandle call() {
    6.38 +                        return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
    6.39 +                            ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
    6.40 +                    }
    6.41 +                });
    6.42 +    }
    6.43  
    6.44      // initialized by nasgen
    6.45      @SuppressWarnings("unused")
    6.46 @@ -187,15 +210,16 @@
    6.47  
    6.48          try {
    6.49              if (value instanceof ScriptObject) {
    6.50 +                final InvokeByName toJSONInvoker = getTO_JSON();
    6.51                  final ScriptObject svalue = (ScriptObject)value;
    6.52 -                final Object toJSON = TO_JSON.getGetter().invokeExact(svalue);
    6.53 +                final Object toJSON = toJSONInvoker.getGetter().invokeExact(svalue);
    6.54                  if (Bootstrap.isCallable(toJSON)) {
    6.55 -                    value = TO_JSON.getInvoker().invokeExact(toJSON, svalue, key);
    6.56 +                    value = toJSONInvoker.getInvoker().invokeExact(toJSON, svalue, key);
    6.57                  }
    6.58              }
    6.59  
    6.60              if (state.replacerFunction != null) {
    6.61 -                value = REPLACER_INVOKER.invokeExact(state.replacerFunction, holder, key, value);
    6.62 +                value = getREPLACER_INVOKER().invokeExact(state.replacerFunction, holder, key, value);
    6.63              }
    6.64          } catch(Error|RuntimeException t) {
    6.65              throw t;
     7.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java	Wed Aug 07 16:38:44 2013 +0200
     7.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Thu Aug 08 16:38:32 2013 +0530
     7.3 @@ -36,6 +36,7 @@
     7.4  import java.util.HashSet;
     7.5  import java.util.List;
     7.6  import java.util.Set;
     7.7 +import java.util.concurrent.Callable;
     7.8  import jdk.internal.dynalink.beans.BeansLinker;
     7.9  import jdk.internal.dynalink.beans.StaticClass;
    7.10  import jdk.internal.dynalink.linker.GuardedInvocation;
    7.11 @@ -70,7 +71,18 @@
    7.12   */
    7.13  @ScriptClass("Object")
    7.14  public final class NativeObject {
    7.15 -    private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
    7.16 +    private static final Object TO_STRING = new Object();
    7.17 +
    7.18 +    private static InvokeByName getTO_STRING() {
    7.19 +        return Global.instance().getInvokeByName(TO_STRING,
    7.20 +                new Callable<InvokeByName>() {
    7.21 +                    @Override
    7.22 +                    public InvokeByName call() {
    7.23 +                        return new InvokeByName("toString", ScriptObject.class);
    7.24 +                    }
    7.25 +                });
    7.26 +    }
    7.27 +
    7.28      private static final MethodType MIRROR_GETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class);
    7.29      private static final MethodType MIRROR_SETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class, Object.class);
    7.30  
    7.31 @@ -402,12 +414,13 @@
    7.32      public static Object toLocaleString(final Object self) {
    7.33          final Object obj = JSType.toScriptObject(self);
    7.34          if (obj instanceof ScriptObject) {
    7.35 +            final InvokeByName toStringInvoker = getTO_STRING();
    7.36              final ScriptObject sobj = (ScriptObject)self;
    7.37              try {
    7.38 -                final Object toString = TO_STRING.getGetter().invokeExact(sobj);
    7.39 +                final Object toString = toStringInvoker.getGetter().invokeExact(sobj);
    7.40  
    7.41                  if (Bootstrap.isCallable(toString)) {
    7.42 -                    return TO_STRING.getInvoker().invokeExact(toString, sobj);
    7.43 +                    return toStringInvoker.getInvoker().invokeExact(toString, sobj);
    7.44                  }
    7.45              } catch (final RuntimeException | Error e) {
    7.46                  throw e;
     8.1 --- a/src/jdk/nashorn/internal/runtime/GlobalObject.java	Wed Aug 07 16:38:44 2013 +0200
     8.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalObject.java	Thu Aug 08 16:38:32 2013 +0530
     8.3 @@ -26,8 +26,10 @@
     8.4  package jdk.nashorn.internal.runtime;
     8.5  
     8.6  import java.lang.invoke.MethodHandle;
     8.7 +import java.util.concurrent.Callable;
     8.8  import jdk.internal.dynalink.linker.GuardedInvocation;
     8.9  import jdk.internal.dynalink.linker.LinkRequest;
    8.10 +import jdk.nashorn.internal.runtime.linker.InvokeByName;
    8.11  
    8.12  /**
    8.13   * Runtime interface to the global scope objects.
    8.14 @@ -210,4 +212,20 @@
    8.15       * @param clazz compiled Class object for the source
    8.16       */
    8.17      public void cacheClass(Source source, Class<?> clazz);
    8.18 +
    8.19 +    /**
    8.20 +     * Get cached InvokeByName object for the given key
    8.21 +     * @param key key to be associated with InvokeByName object
    8.22 +     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
    8.23 +     * @return InvokeByName object associated with the key.
    8.24 +     */
    8.25 +    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator);
    8.26 +
    8.27 +    /**
    8.28 +     * Get cached dynamic method handle for the given key
    8.29 +     * @param key key to be associated with dynamic method handle
    8.30 +     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
    8.31 +     * @return dynamic method handle associated with the key.
    8.32 +     */
    8.33 +    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator);
    8.34  }
     9.1 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Wed Aug 07 16:38:44 2013 +0200
     9.2 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu Aug 08 16:38:32 2013 +0530
     9.3 @@ -27,6 +27,7 @@
     9.4  
     9.5  import java.lang.invoke.MethodHandle;
     9.6  import java.util.Iterator;
     9.7 +import java.util.concurrent.Callable;
     9.8  import jdk.nashorn.internal.ir.LiteralNode;
     9.9  import jdk.nashorn.internal.ir.Node;
    9.10  import jdk.nashorn.internal.ir.ObjectNode;
    9.11 @@ -42,8 +43,19 @@
    9.12   */
    9.13  public final class JSONFunctions {
    9.14      private JSONFunctions() {}
    9.15 -    private static final MethodHandle REVIVER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
    9.16 -            ScriptFunction.class, ScriptObject.class, String.class, Object.class);
    9.17 +
    9.18 +    private static final Object REVIVER_INVOKER = new Object();
    9.19 +
    9.20 +    private static MethodHandle getREVIVER_INVOKER() {
    9.21 +        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(REVIVER_INVOKER,
    9.22 +                new Callable<MethodHandle>() {
    9.23 +                    @Override
    9.24 +                    public MethodHandle call() {
    9.25 +                        return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
    9.26 +                            ScriptFunction.class, ScriptObject.class, String.class, Object.class);
    9.27 +                    }
    9.28 +                });
    9.29 +    }
    9.30  
    9.31      /**
    9.32       * Returns JSON-compatible quoted version of the given string.
    9.33 @@ -117,7 +129,7 @@
    9.34  
    9.35          try {
    9.36               // Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
    9.37 -             return REVIVER_INVOKER.invokeExact(reviver, holder, JSType.toString(name), val);
    9.38 +             return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
    9.39          } catch(Error|RuntimeException t) {
    9.40              throw t;
    9.41          } catch(final Throwable t) {
    10.1 --- a/src/jdk/nashorn/internal/runtime/ListAdapter.java	Wed Aug 07 16:38:44 2013 +0200
    10.2 +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java	Thu Aug 08 16:38:32 2013 +0530
    10.3 @@ -31,6 +31,7 @@
    10.4  import java.util.ListIterator;
    10.5  import java.util.NoSuchElementException;
    10.6  import java.util.RandomAccess;
    10.7 +import java.util.concurrent.Callable;
    10.8  import jdk.nashorn.internal.runtime.linker.Bootstrap;
    10.9  import jdk.nashorn.internal.runtime.linker.InvokeByName;
   10.10  
   10.11 @@ -49,16 +50,73 @@
   10.12   */
   10.13  public final class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
   10.14      // These add to the back and front of the list
   10.15 -    private static final InvokeByName PUSH    = new InvokeByName("push",    ScriptObject.class, void.class, Object.class);
   10.16 -    private static final InvokeByName UNSHIFT = new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
   10.17 +    private static final Object PUSH    = new Object();
   10.18 +    private static InvokeByName getPUSH() {
   10.19 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(PUSH,
   10.20 +                new Callable<InvokeByName>() {
   10.21 +                    @Override
   10.22 +                    public InvokeByName call() {
   10.23 +                        return new InvokeByName("push", ScriptObject.class, void.class, Object.class);
   10.24 +                    }
   10.25 +                });
   10.26 +    }
   10.27 +
   10.28 +    private static final Object UNSHIFT = new Object();
   10.29 +    private static InvokeByName getUNSHIFT() {
   10.30 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(UNSHIFT,
   10.31 +                new Callable<InvokeByName>() {
   10.32 +                    @Override
   10.33 +                    public InvokeByName call() {
   10.34 +                        return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
   10.35 +                    }
   10.36 +                });
   10.37 +    }
   10.38  
   10.39      // These remove from the back and front of the list
   10.40 -    private static final InvokeByName POP   = new InvokeByName("pop",   ScriptObject.class, Object.class);
   10.41 -    private static final InvokeByName SHIFT = new InvokeByName("shift", ScriptObject.class, Object.class);
   10.42 +    private static final Object POP = new Object();
   10.43 +    private static InvokeByName getPOP() {
   10.44 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(POP,
   10.45 +                new Callable<InvokeByName>() {
   10.46 +                    @Override
   10.47 +                    public InvokeByName call() {
   10.48 +                        return new InvokeByName("pop", ScriptObject.class, Object.class);
   10.49 +                    }
   10.50 +                });
   10.51 +    }
   10.52 +
   10.53 +    private static final Object SHIFT = new Object();
   10.54 +    private static InvokeByName getSHIFT() {
   10.55 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SHIFT,
   10.56 +                new Callable<InvokeByName>() {
   10.57 +                    @Override
   10.58 +                    public InvokeByName call() {
   10.59 +                        return new InvokeByName("shift", ScriptObject.class, Object.class);
   10.60 +                    }
   10.61 +                });
   10.62 +    }
   10.63  
   10.64      // These insert and remove in the middle of the list
   10.65 -    private static final InvokeByName SPLICE_ADD    = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
   10.66 -    private static final InvokeByName SPLICE_REMOVE = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
   10.67 +    private static final Object SPLICE_ADD = new Object();
   10.68 +    private static InvokeByName getSPLICE_ADD() {
   10.69 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_ADD,
   10.70 +                new Callable<InvokeByName>() {
   10.71 +                    @Override
   10.72 +                    public InvokeByName call() {
   10.73 +                        return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
   10.74 +                    }
   10.75 +                });
   10.76 +    }
   10.77 +
   10.78 +    private static final Object SPLICE_REMOVE = new Object();
   10.79 +    private static InvokeByName getSPLICE_REMOVE() {
   10.80 +        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_REMOVE,
   10.81 +                new Callable<InvokeByName>() {
   10.82 +                    @Override
   10.83 +                    public InvokeByName call() {
   10.84 +                        return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
   10.85 +                    }
   10.86 +                });
   10.87 +    }
   10.88  
   10.89      private final ScriptObject obj;
   10.90  
   10.91 @@ -109,9 +167,10 @@
   10.92      @Override
   10.93      public void addFirst(Object e) {
   10.94          try {
   10.95 -            final Object fn = UNSHIFT.getGetter().invokeExact(obj);
   10.96 -            checkFunction(fn, UNSHIFT);
   10.97 -            UNSHIFT.getInvoker().invokeExact(fn, obj, e);
   10.98 +            final InvokeByName unshiftInvoker = getUNSHIFT();
   10.99 +            final Object fn = unshiftInvoker.getGetter().invokeExact(obj);
  10.100 +            checkFunction(fn, unshiftInvoker);
  10.101 +            unshiftInvoker.getInvoker().invokeExact(fn, obj, e);
  10.102          } catch(RuntimeException | Error ex) {
  10.103              throw ex;
  10.104          } catch(Throwable t) {
  10.105 @@ -122,9 +181,10 @@
  10.106      @Override
  10.107      public void addLast(Object e) {
  10.108          try {
  10.109 -            final Object fn = PUSH.getGetter().invokeExact(obj);
  10.110 -            checkFunction(fn, PUSH);
  10.111 -            PUSH.getInvoker().invokeExact(fn, obj, e);
  10.112 +            final InvokeByName pushInvoker = getPUSH();
  10.113 +            final Object fn = pushInvoker.getGetter().invokeExact(obj);
  10.114 +            checkFunction(fn, pushInvoker);
  10.115 +            pushInvoker.getInvoker().invokeExact(fn, obj, e);
  10.116          } catch(RuntimeException | Error ex) {
  10.117              throw ex;
  10.118          } catch(Throwable t) {
  10.119 @@ -142,9 +202,10 @@
  10.120              } else {
  10.121                  final int size = size();
  10.122                  if(index < size) {
  10.123 -                    final Object fn = SPLICE_ADD.getGetter().invokeExact(obj);
  10.124 -                    checkFunction(fn, SPLICE_ADD);
  10.125 -                    SPLICE_ADD.getInvoker().invokeExact(fn, obj, index, 0, e);
  10.126 +                    final InvokeByName spliceAddInvoker = getSPLICE_ADD();
  10.127 +                    final Object fn = spliceAddInvoker.getGetter().invokeExact(obj);
  10.128 +                    checkFunction(fn, spliceAddInvoker);
  10.129 +                    spliceAddInvoker.getInvoker().invokeExact(fn, obj, index, 0, e);
  10.130                  } else if(index == size) {
  10.131                      addLast(e);
  10.132                  } else {
  10.133 @@ -234,9 +295,10 @@
  10.134  
  10.135      private Object invokeShift() {
  10.136          try {
  10.137 -            final Object fn = SHIFT.getGetter().invokeExact(obj);
  10.138 -            checkFunction(fn, SHIFT);
  10.139 -            return SHIFT.getInvoker().invokeExact(fn, obj);
  10.140 +            final InvokeByName shiftInvoker = getSHIFT();
  10.141 +            final Object fn = shiftInvoker.getGetter().invokeExact(obj);
  10.142 +            checkFunction(fn, shiftInvoker);
  10.143 +            return shiftInvoker.getInvoker().invokeExact(fn, obj);
  10.144          } catch(RuntimeException | Error ex) {
  10.145              throw ex;
  10.146          } catch(Throwable t) {
  10.147 @@ -246,9 +308,10 @@
  10.148  
  10.149      private Object invokePop() {
  10.150          try {
  10.151 -            final Object fn = POP.getGetter().invokeExact(obj);
  10.152 -            checkFunction(fn, POP);
  10.153 -            return POP.getInvoker().invokeExact(fn, obj);
  10.154 +            final InvokeByName popInvoker = getPOP();
  10.155 +            final Object fn = popInvoker.getGetter().invokeExact(obj);
  10.156 +            checkFunction(fn, popInvoker);
  10.157 +            return popInvoker.getInvoker().invokeExact(fn, obj);
  10.158          } catch(RuntimeException | Error ex) {
  10.159              throw ex;
  10.160          } catch(Throwable t) {
  10.161 @@ -263,9 +326,10 @@
  10.162  
  10.163      private void invokeSpliceRemove(int fromIndex, int count) {
  10.164          try {
  10.165 -            final Object fn = SPLICE_REMOVE.getGetter().invokeExact(obj);
  10.166 -            checkFunction(fn, SPLICE_REMOVE);
  10.167 -            SPLICE_REMOVE.getInvoker().invokeExact(fn, obj, fromIndex, count);
  10.168 +            final InvokeByName spliceRemoveInvoker = getSPLICE_REMOVE();
  10.169 +            final Object fn = spliceRemoveInvoker.getGetter().invokeExact(obj);
  10.170 +            checkFunction(fn, spliceRemoveInvoker);
  10.171 +            spliceRemoveInvoker.getInvoker().invokeExact(fn, obj, fromIndex, count);
  10.172          } catch(RuntimeException | Error ex) {
  10.173              throw ex;
  10.174          } catch(Throwable t) {
    11.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Aug 07 16:38:44 2013 +0200
    11.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Aug 08 16:38:32 2013 +0530
    11.3 @@ -52,13 +52,19 @@
    11.4  public final class RecompilableScriptFunctionData extends ScriptFunctionData {
    11.5  
    11.6      /** FunctionNode with the code for this ScriptFunction */
    11.7 -    private FunctionNode functionNode;
    11.8 +    private volatile FunctionNode functionNode;
    11.9 +
   11.10 +    /** Source from which FunctionNode was parsed. */
   11.11 +    private final Source source;
   11.12 +
   11.13 +    /** Token of this function within the source. */
   11.14 +    private final long token;
   11.15  
   11.16      /** Allocator map from makeMap() */
   11.17      private final PropertyMap allocatorMap;
   11.18  
   11.19      /** Code installer used for all further recompilation/specialization of this ScriptFunction */
   11.20 -    private final CodeInstaller<ScriptEnvironment> installer;
   11.21 +    private volatile CodeInstaller<ScriptEnvironment> installer;
   11.22  
   11.23      /** Name of class where allocator function resides */
   11.24      private final String allocatorClassName;
   11.25 @@ -103,6 +109,8 @@
   11.26                true);
   11.27  
   11.28          this.functionNode       = functionNode;
   11.29 +        this.source             = functionNode.getSource();
   11.30 +        this.token              = tokenFor(functionNode);
   11.31          this.installer          = installer;
   11.32          this.allocatorClassName = allocatorClassName;
   11.33          this.allocatorMap       = allocatorMap;
   11.34 @@ -110,9 +118,6 @@
   11.35  
   11.36      @Override
   11.37      String toSource() {
   11.38 -        final Source source = functionNode.getSource();
   11.39 -        final long   token  = tokenFor(functionNode);
   11.40 -
   11.41          if (source != null && token != 0) {
   11.42              return source.getString(Token.descPosition(token), Token.descLength(token));
   11.43          }
   11.44 @@ -123,8 +128,6 @@
   11.45      @Override
   11.46      public String toString() {
   11.47          final StringBuilder sb = new StringBuilder();
   11.48 -        final Source source = functionNode.getSource();
   11.49 -        final long   token  = tokenFor(functionNode);
   11.50  
   11.51          if (source != null) {
   11.52              sb.append(source.getName())
   11.53 @@ -190,6 +193,12 @@
   11.54  
   11.55           // code exists - look it up and add it into the automatically sorted invoker list
   11.56           addCode(functionNode);
   11.57 +
   11.58 +         if (! functionNode.canSpecialize()) {
   11.59 +             // allow GC to claim IR stuff that is not needed anymore
   11.60 +             functionNode = null;
   11.61 +             installer = null;
   11.62 +         }
   11.63      }
   11.64  
   11.65      private MethodHandle addCode(final FunctionNode fn) {
   11.66 @@ -325,7 +334,7 @@
   11.67           * footprint too large to store a parse snapshot, or if it is meaningless
   11.68           * to do so, such as e.g. for runScript
   11.69           */
   11.70 -        if (!functionNode.canSpecialize()) {
   11.71 +        if (functionNode == null || !functionNode.canSpecialize()) {
   11.72              return mh;
   11.73          }
   11.74  
    12.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Aug 07 16:38:44 2013 +0200
    12.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Aug 08 16:38:32 2013 +0530
    12.3 @@ -496,32 +496,24 @@
    12.4          MethodHandle boundHandle;
    12.5          MethodHandle guard = null;
    12.6  
    12.7 +        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
    12.8 +
    12.9          if (data.needsCallee()) {
   12.10              final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
   12.11 -            if (NashornCallSiteDescriptor.isScope(desc)) {
   12.12 +            if (scopeCall) {
   12.13                  // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
   12.14                  // (callee, this, args...) => (callee, args...)
   12.15                  boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
   12.16                  // (callee, args...) => (callee, [this], args...)
   12.17                  boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
   12.18 +
   12.19              } else {
   12.20                  // It's already (callee, this, args...), just what we need
   12.21                  boundHandle = callHandle;
   12.22 -
   12.23 -                // For non-strict functions, check whether this-object is primitive type.
   12.24 -                // If so add a to-object-wrapper argument filter.
   12.25 -                // Else install a guard that will trigger a relink when the argument becomes primitive.
   12.26 -                if (needsWrappedThis()) {
   12.27 -                    if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
   12.28 -                        boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
   12.29 -                    } else {
   12.30 -                        guard = getNonStrictFunctionGuard(this);
   12.31 -                    }
   12.32 -                }
   12.33              }
   12.34          } else {
   12.35              final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments());
   12.36 -            if (NashornCallSiteDescriptor.isScope(desc)) {
   12.37 +            if (scopeCall) {
   12.38                  // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
   12.39                  // (this, args...) => (args...)
   12.40                  boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
   12.41 @@ -533,6 +525,17 @@
   12.42              }
   12.43          }
   12.44  
   12.45 +        // For non-strict functions, check whether this-object is primitive type.
   12.46 +        // If so add a to-object-wrapper argument filter.
   12.47 +        // Else install a guard that will trigger a relink when the argument becomes primitive.
   12.48 +        if (!scopeCall && needsWrappedThis()) {
   12.49 +            if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
   12.50 +                boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
   12.51 +            } else {
   12.52 +                guard = getNonStrictFunctionGuard(this);
   12.53 +            }
   12.54 +        }
   12.55 +
   12.56          boundHandle = pairArguments(boundHandle, type);
   12.57  
   12.58          return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this) : guard);
    13.1 --- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Wed Aug 07 16:38:44 2013 +0200
    13.2 +++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Thu Aug 08 16:38:32 2013 +0530
    13.3 @@ -27,6 +27,7 @@
    13.4  
    13.5  import java.lang.invoke.MethodHandle;
    13.6  import java.lang.invoke.MethodHandles;
    13.7 +import java.util.concurrent.Callable;
    13.8  
    13.9  import jdk.nashorn.internal.codegen.CompilerConstants;
   13.10  import jdk.nashorn.internal.lookup.Lookup;
   13.11 @@ -68,12 +69,32 @@
   13.12              "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
   13.13  
   13.14      /** Dynamic invoker for getter */
   13.15 -    private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
   13.16 -            Object.class, Object.class);
   13.17 +    private static final Object INVOKE_UA_GETTER = new Object();
   13.18 +
   13.19 +    private static MethodHandle getINVOKE_UA_GETTER() {
   13.20 +
   13.21 +        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
   13.22 +                new Callable<MethodHandle>() {
   13.23 +                    @Override
   13.24 +                    public MethodHandle call() {
   13.25 +                        return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
   13.26 +                            Object.class, Object.class);
   13.27 +                    }
   13.28 +                });
   13.29 +    }
   13.30  
   13.31      /** Dynamic invoker for setter */
   13.32 -    private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
   13.33 -            Object.class, Object.class, Object.class);
   13.34 +    private static Object INVOKE_UA_SETTER = new Object();
   13.35 +    private static MethodHandle getINVOKE_UA_SETTER() {
   13.36 +        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
   13.37 +                new Callable<MethodHandle>() {
   13.38 +                    @Override
   13.39 +                    public MethodHandle call() {
   13.40 +                        return Bootstrap.createDynamicInvoker("dyn:call", void.class,
   13.41 +                            Object.class, Object.class, Object.class);
   13.42 +                    }
   13.43 +                });
   13.44 +    }
   13.45  
   13.46      /**
   13.47       * Constructor
   13.48 @@ -191,7 +212,7 @@
   13.49  
   13.50          if (func instanceof ScriptFunction) {
   13.51              try {
   13.52 -                return INVOKE_UA_GETTER.invokeExact(func, self);
   13.53 +                return getINVOKE_UA_GETTER().invokeExact(func, self);
   13.54              } catch(final Error|RuntimeException t) {
   13.55                  throw t;
   13.56              } catch(final Throwable t) {
   13.57 @@ -208,7 +229,7 @@
   13.58  
   13.59          if (func instanceof ScriptFunction) {
   13.60              try {
   13.61 -                INVOKE_UA_SETTER.invokeExact(func, self, value);
   13.62 +                getINVOKE_UA_SETTER().invokeExact(func, self, value);
   13.63              } catch(final Error|RuntimeException t) {
   13.64                  throw t;
   13.65              } catch(final Throwable t) {
    14.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Wed Aug 07 16:38:44 2013 +0200
    14.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Thu Aug 08 16:38:32 2013 +0530
    14.3 @@ -48,7 +48,7 @@
    14.4      private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
    14.5  
    14.6      private final String className;
    14.7 -    private final byte[] classBytes;
    14.8 +    private volatile byte[] classBytes;
    14.9  
   14.10      JavaAdapterClassLoader(String className, byte[] classBytes) {
   14.11          this.className = className.replace('/', '.');
   14.12 @@ -56,6 +56,13 @@
   14.13      }
   14.14  
   14.15      /**
   14.16 +     * clear classBytes after loading class.
   14.17 +     */
   14.18 +    void clearClassBytes() {
   14.19 +       this.classBytes = null;
   14.20 +    }
   14.21 +
   14.22 +    /**
   14.23       * Loads the generated adapter class into the JVM.
   14.24       * @param parentLoader the parent class loader for the generated class loader
   14.25       * @return the generated adapter class
   14.26 @@ -103,6 +110,7 @@
   14.27              @Override
   14.28              protected Class<?> findClass(final String name) throws ClassNotFoundException {
   14.29                  if(name.equals(className)) {
   14.30 +                    assert classBytes != null : "what? already cleared .class bytes!!";
   14.31                      return defineClass(name, classBytes, 0, classBytes.length, GENERATED_PROTECTION_DOMAIN);
   14.32                  } else {
   14.33                      throw new ClassNotFoundException(name);
    15.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Wed Aug 07 16:38:44 2013 +0200
    15.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Thu Aug 08 16:38:32 2013 +0530
    15.3 @@ -224,7 +224,10 @@
    15.4              this.commonLoader = findCommonLoader(definingLoader);
    15.5              final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);
    15.6              this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();
    15.7 -            this.instanceAdapterClass = gen.createAdapterClassLoader().generateClass(commonLoader);
    15.8 +            final JavaAdapterClassLoader jacl = gen.createAdapterClassLoader();
    15.9 +            this.instanceAdapterClass = jacl.generateClass(commonLoader);
   15.10 +            // loaded Class - no need to keep class bytes around
   15.11 +            jacl.clearClassBytes();
   15.12              this.adapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();
   15.13              this.adaptationResult = AdaptationResult.SUCCESSFUL_RESULT;
   15.14          }
    16.1 --- a/test/script/basic/JDK-8020357.js	Wed Aug 07 16:38:44 2013 +0200
    16.2 +++ b/test/script/basic/JDK-8020357.js	Thu Aug 08 16:38:32 2013 +0530
    16.3 @@ -33,17 +33,6 @@
    16.4  
    16.5  var limit = Math.pow(2, UNSIGNED_INT_BITS)/BYTES_PER_INT_32
    16.6  
    16.7 -try {
    16.8 -    // A value at or under the limit should either succeed if we have
    16.9 -    // enough heap, or throw an OutOfMemoryError if we don't.
   16.10 -    Int32Array(limit - 1)
   16.11 -} catch(e) {
   16.12 -    if(!(e instanceof java.lang.OutOfMemoryError)) {
   16.13 -        // Only print an unexpected result; OutOfMemoryError is expected
   16.14 -        print(e)
   16.15 -    }
   16.16 -}
   16.17 -
   16.18  // A value over the limit should throw a RangeError.
   16.19  try {
   16.20      Int32Array(limit)
    17.1 --- a/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java	Wed Aug 07 16:38:44 2013 +0200
    17.2 +++ b/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java	Thu Aug 08 16:38:32 2013 +0530
    17.3 @@ -33,6 +33,7 @@
    17.4  import javax.script.ScriptEngineManager;
    17.5  import javax.script.ScriptException;
    17.6  import org.testng.TestNG;
    17.7 +import org.testng.annotations.AfterClass;
    17.8  import org.testng.annotations.BeforeClass;
    17.9  import org.testng.annotations.Test;
   17.10  
   17.11 @@ -44,7 +45,7 @@
   17.12  public class BooleanAccessTest {
   17.13  
   17.14      private static ScriptEngine e = null;
   17.15 -    private static SharedObject o = new SharedObject();
   17.16 +    private static SharedObject o = null;
   17.17  
   17.18      public static void main(final String[] args) {
   17.19          TestNG.main(args);
   17.20 @@ -54,10 +55,17 @@
   17.21      public static void setUpClass() throws ScriptException {
   17.22          final ScriptEngineManager m = new ScriptEngineManager();
   17.23          e = m.getEngineByName("nashorn");
   17.24 +        o = new SharedObject();
   17.25          e.put("o", o);
   17.26          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   17.27      }
   17.28  
   17.29 +    @AfterClass
   17.30 +    public static void tearDownClass() {
   17.31 +        e = null;
   17.32 +        o = null;
   17.33 +    }
   17.34 +
   17.35      @Test
   17.36      public void accessFieldBoolean() throws ScriptException {
   17.37          e.eval("var p_boolean = o.publicBoolean;");
    18.1 --- a/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java	Wed Aug 07 16:38:44 2013 +0200
    18.2 +++ b/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java	Thu Aug 08 16:38:32 2013 +0530
    18.3 @@ -36,6 +36,7 @@
    18.4  import javax.script.ScriptEngineManager;
    18.5  import javax.script.ScriptException;
    18.6  import org.testng.TestNG;
    18.7 +import org.testng.annotations.AfterClass;
    18.8  import org.testng.annotations.BeforeClass;
    18.9  import org.testng.annotations.Test;
   18.10  
   18.11 @@ -47,7 +48,7 @@
   18.12  public class MethodAccessTest {
   18.13  
   18.14      private static ScriptEngine e = null;
   18.15 -    private static SharedObject o = new SharedObject();
   18.16 +    private static SharedObject o = null;
   18.17  
   18.18      public static void main(final String[] args) {
   18.19          TestNG.main(args);
   18.20 @@ -57,12 +58,19 @@
   18.21      public static void setUpClass() throws ScriptException {
   18.22          final ScriptEngineManager m = new ScriptEngineManager();
   18.23          e = m.getEngineByName("nashorn");
   18.24 +        o = new SharedObject();
   18.25          o.setEngine(e);
   18.26          e.put("o", o);
   18.27          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   18.28          e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
   18.29      }
   18.30  
   18.31 +    @AfterClass
   18.32 +    public static void tearDownClass() {
   18.33 +        e = null;
   18.34 +        o = null;
   18.35 +    }
   18.36 +
   18.37      @Test
   18.38      public void accessMethodthrowsCheckedException() throws ScriptException {
   18.39          e.eval("try {" +
    19.1 --- a/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java	Wed Aug 07 16:38:44 2013 +0200
    19.2 +++ b/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java	Thu Aug 08 16:38:32 2013 +0530
    19.3 @@ -33,6 +33,7 @@
    19.4  import javax.script.ScriptEngineManager;
    19.5  import javax.script.ScriptException;
    19.6  import org.testng.TestNG;
    19.7 +import org.testng.annotations.AfterClass;
    19.8  import org.testng.annotations.BeforeClass;
    19.9  import org.testng.annotations.Test;
   19.10  
   19.11 @@ -44,7 +45,7 @@
   19.12  public class NumberAccessTest {
   19.13  
   19.14      private static ScriptEngine e = null;
   19.15 -    private static SharedObject o = new SharedObject();
   19.16 +    private static SharedObject o = null;
   19.17  
   19.18      public static void main(final String[] args) {
   19.19          TestNG.main(args);
   19.20 @@ -54,10 +55,17 @@
   19.21      public static void setUpClass() throws ScriptException {
   19.22          final ScriptEngineManager m = new ScriptEngineManager();
   19.23          e = m.getEngineByName("nashorn");
   19.24 +        o = new SharedObject();
   19.25          e.put("o", o);
   19.26          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   19.27      }
   19.28  
   19.29 +    @AfterClass
   19.30 +    public static void tearDownClass() {
   19.31 +        e = null;
   19.32 +        o = null;
   19.33 +    }
   19.34 +
   19.35      // --------------------------------long
   19.36      // tests------------------------------------
   19.37      @Test
    20.1 --- a/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java	Wed Aug 07 16:38:44 2013 +0200
    20.2 +++ b/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java	Thu Aug 08 16:38:32 2013 +0530
    20.3 @@ -32,6 +32,7 @@
    20.4  import javax.script.ScriptEngineManager;
    20.5  import javax.script.ScriptException;
    20.6  import org.testng.TestNG;
    20.7 +import org.testng.annotations.AfterClass;
    20.8  import org.testng.annotations.BeforeClass;
    20.9  import org.testng.annotations.Test;
   20.10  
   20.11 @@ -43,7 +44,7 @@
   20.12  public class NumberBoxingTest {
   20.13  
   20.14      private static ScriptEngine e = null;
   20.15 -    private static SharedObject o = new SharedObject();
   20.16 +    private static SharedObject o = null;
   20.17  
   20.18      public static void main(final String[] args) {
   20.19          TestNG.main(args);
   20.20 @@ -53,10 +54,17 @@
   20.21      public static void setUpClass() throws ScriptException {
   20.22          final ScriptEngineManager m = new ScriptEngineManager();
   20.23          e = m.getEngineByName("nashorn");
   20.24 +        o = new SharedObject();
   20.25          e.put("o", o);
   20.26          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   20.27      }
   20.28  
   20.29 +    @AfterClass
   20.30 +    public static void tearDownClass() {
   20.31 +        e = null;
   20.32 +        o = null;
   20.33 +    }
   20.34 +
   20.35      // --------------------------------long
   20.36      // tests------------------------------------
   20.37      @Test
    21.1 --- a/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java	Wed Aug 07 16:38:44 2013 +0200
    21.2 +++ b/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java	Thu Aug 08 16:38:32 2013 +0530
    21.3 @@ -32,6 +32,7 @@
    21.4  import javax.script.ScriptEngineManager;
    21.5  import javax.script.ScriptException;
    21.6  import org.testng.TestNG;
    21.7 +import org.testng.annotations.AfterClass;
    21.8  import org.testng.annotations.BeforeClass;
    21.9  import org.testng.annotations.Test;
   21.10  
   21.11 @@ -43,7 +44,7 @@
   21.12  public class ObjectAccessTest {
   21.13  
   21.14      private static ScriptEngine e = null;
   21.15 -    private static SharedObject o = new SharedObject();
   21.16 +    private static SharedObject o = null;
   21.17  
   21.18      public static void main(final String[] args) {
   21.19          TestNG.main(args);
   21.20 @@ -53,11 +54,18 @@
   21.21      public static void setUpClass() throws ScriptException {
   21.22          final ScriptEngineManager m = new ScriptEngineManager();
   21.23          e = m.getEngineByName("nashorn");
   21.24 +        o = new SharedObject();
   21.25          e.put("o", o);
   21.26          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   21.27          e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
   21.28      }
   21.29  
   21.30 +    @AfterClass
   21.31 +    public static void tearDownClass() {
   21.32 +        e = null;
   21.33 +        o = null;
   21.34 +    }
   21.35 +
   21.36      @Test
   21.37      public void accessFieldObject() throws ScriptException {
   21.38          e.eval("var p_object = o.publicObject;");
    22.1 --- a/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java	Wed Aug 07 16:38:44 2013 +0200
    22.2 +++ b/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java	Thu Aug 08 16:38:32 2013 +0530
    22.3 @@ -32,6 +32,7 @@
    22.4  import javax.script.ScriptEngineManager;
    22.5  import javax.script.ScriptException;
    22.6  import org.testng.TestNG;
    22.7 +import org.testng.annotations.AfterClass;
    22.8  import org.testng.annotations.BeforeClass;
    22.9  import org.testng.annotations.Test;
   22.10  
   22.11 @@ -43,7 +44,7 @@
   22.12  public class StringAccessTest {
   22.13  
   22.14      private static ScriptEngine e = null;
   22.15 -    private static SharedObject o = new SharedObject();
   22.16 +    private static SharedObject o = null;
   22.17  
   22.18      public static void main(final String[] args) {
   22.19          TestNG.main(args);
   22.20 @@ -53,10 +54,17 @@
   22.21      public static void setUpClass() throws ScriptException {
   22.22          final ScriptEngineManager m = new ScriptEngineManager();
   22.23          e = m.getEngineByName("nashorn");
   22.24 +        o = new SharedObject();
   22.25          e.put("o", o);
   22.26          e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
   22.27      }
   22.28  
   22.29 +    @AfterClass
   22.30 +    public static void tearDownClass() {
   22.31 +        e = null;
   22.32 +        o = null;
   22.33 +    }
   22.34 +
   22.35      @Test
   22.36      public void accessFieldString() throws ScriptException {
   22.37          e.eval("var p_string = o.publicString;");
    23.1 --- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Aug 07 16:38:44 2013 +0200
    23.2 +++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Thu Aug 08 16:38:32 2013 +0530
    23.3 @@ -35,6 +35,8 @@
    23.4  import jdk.nashorn.internal.runtime.Source;
    23.5  import jdk.nashorn.internal.runtime.options.Options;
    23.6  import org.testng.Assert;
    23.7 +import org.testng.annotations.AfterClass;
    23.8 +import org.testng.annotations.BeforeClass;
    23.9  import org.testng.annotations.Test;
   23.10  
   23.11  /**
   23.12 @@ -58,7 +60,8 @@
   23.13      private Context context;
   23.14      private ScriptObject global;
   23.15  
   23.16 -    public CompilerTest() {
   23.17 +    @BeforeClass
   23.18 +    public void setupTest() {
   23.19          final Options options = new Options("nashorn");
   23.20          options.set("anon.functions", true);
   23.21          options.set("compile.only", true);
   23.22 @@ -79,6 +82,12 @@
   23.23          this.global = context.createGlobal();
   23.24      }
   23.25  
   23.26 +    @AfterClass
   23.27 +    public void tearDownTest() {
   23.28 +        this.context = null;
   23.29 +        this.global = null;
   23.30 +    }
   23.31 +
   23.32      @Test
   23.33      public void compileAllTests() {
   23.34          if (TEST262) {
    24.1 --- a/test/src/jdk/nashorn/internal/parser/ParserTest.java	Wed Aug 07 16:38:44 2013 +0200
    24.2 +++ b/test/src/jdk/nashorn/internal/parser/ParserTest.java	Thu Aug 08 16:38:32 2013 +0530
    24.3 @@ -28,10 +28,11 @@
    24.4  import java.io.File;
    24.5  import jdk.nashorn.internal.runtime.Context;
    24.6  import jdk.nashorn.internal.runtime.ErrorManager;
    24.7 -import jdk.nashorn.internal.runtime.ScriptObject;
    24.8  import jdk.nashorn.internal.runtime.Source;
    24.9  import jdk.nashorn.internal.runtime.options.Options;
   24.10  import org.testng.Assert;
   24.11 +import org.testng.annotations.AfterClass;
   24.12 +import org.testng.annotations.BeforeClass;
   24.13  import org.testng.annotations.Test;
   24.14  
   24.15  /**
   24.16 @@ -54,9 +55,9 @@
   24.17      }
   24.18  
   24.19      private Context context;
   24.20 -    private ScriptObject global;
   24.21  
   24.22 -    public ParserTest() {
   24.23 +    @BeforeClass
   24.24 +    public void setupTest() {
   24.25          final Options options = new Options("nashorn");
   24.26          options.set("anon.functions", true);
   24.27          options.set("parse.only", true);
   24.28 @@ -64,7 +65,11 @@
   24.29  
   24.30          ErrorManager errors = new ErrorManager();
   24.31          this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
   24.32 -        this.global = context.createGlobal();
   24.33 +    }
   24.34 +
   24.35 +    @AfterClass
   24.36 +    public void tearDownTest() {
   24.37 +        this.context = null;
   24.38      }
   24.39  
   24.40      @Test
   24.41 @@ -125,8 +130,6 @@
   24.42              log("Begin parsing " + file.getAbsolutePath());
   24.43          }
   24.44  
   24.45 -        final ScriptObject oldGlobal = Context.getGlobal();
   24.46 -        final boolean globalChanged = (oldGlobal != global);
   24.47          try {
   24.48              final char[] buffer = Source.readFully(file);
   24.49              boolean excluded = false;
   24.50 @@ -150,9 +153,6 @@
   24.51                  }
   24.52              };
   24.53              errors.setLimit(0);
   24.54 -            if (globalChanged) {
   24.55 -                Context.setGlobal(global);
   24.56 -            }
   24.57              final Source   source   = new Source(file.getAbsolutePath(), buffer);
   24.58              new Parser(context.getEnv(), source, errors).parse();
   24.59              if (errors.getNumberOfErrors() > 0) {
   24.60 @@ -167,10 +167,6 @@
   24.61                  exp.printStackTrace(System.out);
   24.62              }
   24.63              failed++;
   24.64 -        } finally {
   24.65 -            if (globalChanged) {
   24.66 -                Context.setGlobal(oldGlobal);
   24.67 -            }
   24.68          }
   24.69  
   24.70          if (VERBOSE) {

mercurial