8019947: inherited property invalidation does not work with two globals in same context
authorsundar
Fri, 05 Jul 2013 14:38:04 +0530
changeset 18851 bdb92c95f886
parent 18850 e53ea5f14dd3
child 18852 604c1d681b6f
8019947: inherited property invalidation does not work with two globals in same context Reviewed-by: jlaskey, lagergren, hannesw, attila
nashorn/make/build-nasgen.xml
nashorn/make/build.xml
nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java
nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
nashorn/src/jdk/nashorn/internal/objects/Global.java
nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
nashorn/src/jdk/nashorn/internal/objects/NativeError.java
nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
nashorn/src/jdk/nashorn/internal/objects/NativeString.java
nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
nashorn/src/jdk/nashorn/internal/runtime/Context.java
nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
nashorn/src/jdk/nashorn/internal/scripts/JO.java
nashorn/src/jdk/nashorn/tools/Shell.java
nashorn/test/script/basic/JDK-8019947.js
nashorn/test/script/basic/JDK-8019947.js.EXPECTED
--- a/nashorn/make/build-nasgen.xml	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/make/build-nasgen.xml	Fri Jul 05 14:38:04 2013 +0530
@@ -42,11 +42,6 @@
             <arg value="jdk.nashorn.internal.objects"/>
             <arg value="${basedir}/build/classes"/>
         </java>
-
-        <move todir="${basedir}/build/classes/jdk/nashorn/internal/objects">
-            <fileset dir="${basedir}/build/classes/jdk/nashorn/internal/objects"/>
-            <mapper type="glob" from="*.class" to="*.clazz"/>
-        </move>
     </target>
 
     <target name="run-nasgen-eclipse">
@@ -66,7 +61,6 @@
             <fileset dir="${basedir}/build/eclipse/.nasgentmp/jdk/nashorn/internal/objects">
                 <include name="*.class"/>
             </fileset>
-            <mapper type="glob" from="*.class" to="*.clazz"/>
         </move>
 
         <delete includeemptydirs="true"><fileset dir="${basedir}/build/eclipse/.nasgentmp" includes="**"/></delete>
@@ -75,7 +69,6 @@
             <fileset dir="${basedir}/build/eclipse/jdk/nashorn/internal/objects">
                 <include name="**/*.class"/>
             </fileset>
-            <mapper type="glob" from="*.class" to="*.clazz"/>
         </copy>
     </target>
 
--- a/nashorn/make/build.xml	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/make/build.xml	Fri Jul 05 14:38:04 2013 +0530
@@ -100,7 +100,8 @@
            target="${javac.target}"
            debug="${javac.debug}"
            encoding="${javac.encoding}"
-           includeantruntime="false">
+           includeantruntime="false" fork="true">
+      <compilerarg value="-J-Djava.ext.dirs="/>
       <compilerarg value="-Xlint:unchecked"/>
       <compilerarg value="-Xlint:deprecation"/>
       <compilerarg value="-XDignore.symbol.file"/>
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Fri Jul 05 14:38:04 2013 +0530
@@ -308,9 +308,9 @@
     public void putAll(final Map<? extends String, ? extends Object> map) {
         final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
         final boolean globalChanged = (oldGlobal != global);
-        final boolean strict = sobj.isStrictContext();
         inGlobal(new Callable<Object>() {
             @Override public Object call() {
+                final boolean strict = global.isStrictContext();
                 for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
                     final Object value = entry.getValue();
                     final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Fri Jul 05 14:38:04 2013 +0530
@@ -109,6 +109,8 @@
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.objects.ScriptFunctionImpl;
 import jdk.nashorn.internal.parser.Lexer.RegexToken;
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.Context;
@@ -148,11 +150,9 @@
  */
 final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> {
 
-    /** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
-    private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
-
-    /** Name of the ScriptFunctionImpl, cannot be referred to as .class @see FunctionObjectCreator */
-    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionImpl";
+    private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
+
+    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Type.getInternalName(ScriptFunctionImpl.class);
 
     /** Constant data & installation. The only reason the compiler keeps this is because it is assigned
      *  by reflection in class installation */
@@ -3203,11 +3203,7 @@
         }.makeObject(method);
     }
 
-    /*
-     * Globals are special. We cannot refer to any Global (or NativeObject) class by .class, as they are different
-     * for different contexts. As far as I can tell, the only NativeObject that we need to deal with like this
-     * is from the code pipeline is Global
-     */
+    // calls on Global class.
     private MethodEmitter globalInstance() {
         return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Fri Jul 05 14:38:04 2013 +0530
@@ -67,12 +67,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    AccessorPropertyDescriptor() {
-        this(false, false, UNDEFINED, UNDEFINED);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set) {
-        super(Global.objectPrototype(), $nasgenmap$);
+    AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
+        super(global.getObjectPrototype(), global.getAccessorPropertyDescriptorMap());
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.get          = get;
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Fri Jul 05 14:38:04 2013 +0530
@@ -40,12 +40,17 @@
 abstract class ArrayBufferView extends ScriptObject {
 
     // initialized by nasgen
-    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
     ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
         checkConstructorArgs(buffer, byteOffset, elementLength);
-        this.setProto(getPrototype());
+        final Global global = Global.instance();
+        this.setMap(global.getArrayBufferViewMap());
+        this.setProto(getPrototype(global));
         this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
     }
 
@@ -283,7 +288,7 @@
 
     protected abstract Factory factory();
 
-    protected abstract ScriptObject getPrototype();
+    protected abstract ScriptObject getPrototype(final Global global);
 
     protected boolean isFloatArray() {
         return false;
--- a/nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java	Fri Jul 05 14:38:04 2013 +0530
@@ -39,7 +39,7 @@
     private final ScriptFunction targetFunction;
 
     BoundScriptFunctionImpl(ScriptFunctionData data, ScriptFunction targetFunction) {
-        super(data);
+        super(data, Global.instance());
         setPrototype(ScriptRuntime.UNDEFINED);
         this.targetFunction = targetFunction;
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Fri Jul 05 14:38:04 2013 +0530
@@ -25,7 +25,6 @@
 
 package jdk.nashorn.internal.objects;
 
-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.sameValue;
 
 import java.util.Objects;
@@ -65,12 +64,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    DataPropertyDescriptor() {
-        this(false, false, false, UNDEFINED);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value) {
-        super(Global.objectPrototype(), $nasgenmap$);
+    DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
+        super(global.getObjectPrototype(), global.getDataPropertyDescriptorMap());
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.writable     = writable;
--- a/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Fri Jul 05 14:38:04 2013 +0530
@@ -55,12 +55,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    GenericPropertyDescriptor() {
-        this(false, false);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    GenericPropertyDescriptor(final boolean configurable, final boolean enumerable) {
-        super(Global.objectPrototype(), $nasgenmap$);
+    GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
+        super(global.getObjectPrototype(), global.getGenericPropertyDescriptorMap());
         this.configurable = configurable;
         this.enumerable   = enumerable;
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java	Fri Jul 05 14:38:04 2013 +0530
@@ -363,6 +363,35 @@
     private ScriptObject   builtinFloat32Array;
     private ScriptObject   builtinFloat64Array;
 
+    private PropertyMap    accessorPropertyDescriptorMap;
+    private PropertyMap    arrayBufferViewMap;
+    private PropertyMap    dataPropertyDescriptorMap;
+    private PropertyMap    genericPropertyDescriptorMap;
+    private PropertyMap    nativeArgumentsMap;
+    private PropertyMap    nativeArrayMap;
+    private PropertyMap    nativeArrayBufferMap;
+    private PropertyMap    nativeBooleanMap;
+    private PropertyMap    nativeDateMap;
+    private PropertyMap    nativeErrorMap;
+    private PropertyMap    nativeEvalErrorMap;
+    private PropertyMap    nativeJSAdapterMap;
+    private PropertyMap    nativeJavaImporterMap;
+    private PropertyMap    nativeNumberMap;
+    private PropertyMap    nativeRangeErrorMap;
+    private PropertyMap    nativeReferenceErrorMap;
+    private PropertyMap    nativeRegExpMap;
+    private PropertyMap    nativeRegExpExecResultMap;
+    private PropertyMap    nativeStrictArgumentsMap;
+    private PropertyMap    nativeStringMap;
+    private PropertyMap    nativeSyntaxErrorMap;
+    private PropertyMap    nativeTypeErrorMap;
+    private PropertyMap    nativeURIErrorMap;
+    private PropertyMap    prototypeObjectMap;
+    private PropertyMap    objectMap;
+    private PropertyMap    functionMap;
+    private PropertyMap    strictFunctionMap;
+    private PropertyMap    boundFunctionMap;
+
     // Flag to indicate that a split method issued a return statement
     private int splitState = -1;
 
@@ -379,8 +408,6 @@
     private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object[].class);
     private static final MethodHandle EXIT              = findOwnMH("exit",              Object.class, Object.class, Object.class);
 
-    private final Context context;
-
     // initialized by nasgen
     @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
@@ -391,7 +418,7 @@
      * @param context the context
      */
     public Global(final Context context) {
-        this.context = context;
+        this.setContext(context);
         this.setIsScope();
         /*
          * Duplicate global's map and use it. This way the initial Map filled
@@ -425,7 +452,7 @@
      * @return the script environment
      */
     static ScriptEnvironment getEnv() {
-        return instance().context.getEnv();
+        return instance().getContext().getEnv();
     }
 
     /**
@@ -434,7 +461,7 @@
      * @return the context
      */
     static Context getThisContext() {
-        return instance().context;
+        return instance().getContext();
     }
 
     // GlobalObject interface implementation
@@ -457,11 +484,11 @@
     @Override
     public Object wrapAsObject(final Object obj) {
         if (obj instanceof Boolean) {
-            return new NativeBoolean((Boolean)obj);
+            return new NativeBoolean((Boolean)obj, this);
         } else if (obj instanceof Number) {
-            return new NativeNumber(((Number)obj).doubleValue());
+            return new NativeNumber(((Number)obj).doubleValue(), this);
         } else if (obj instanceof String || obj instanceof ConsString) {
-            return new NativeString((CharSequence)obj);
+            return new NativeString((CharSequence)obj, this);
         } else if (obj instanceof Object[]) { // extension
             return new NativeArray((Object[])obj);
         } else if (obj instanceof double[]) { // extension
@@ -490,7 +517,7 @@
 
     @Override
     public ScriptObject newObject() {
-        return new JO(getObjectPrototype());
+        return new JO(getObjectPrototype(), getObjectMap());
     }
 
     @Override
@@ -567,52 +594,52 @@
 
     @Override
     public ScriptObject newError(final String msg) {
-        return new NativeError(msg);
+        return new NativeError(msg, this);
     }
 
     @Override
     public ScriptObject newEvalError(final String msg) {
-        return new NativeEvalError(msg);
+        return new NativeEvalError(msg, this);
     }
 
     @Override
     public ScriptObject newRangeError(final String msg) {
-        return new NativeRangeError(msg);
+        return new NativeRangeError(msg, this);
     }
 
     @Override
     public ScriptObject newReferenceError(final String msg) {
-        return new NativeReferenceError(msg);
+        return new NativeReferenceError(msg, this);
     }
 
     @Override
     public ScriptObject newSyntaxError(final String msg) {
-        return new NativeSyntaxError(msg);
+        return new NativeSyntaxError(msg, this);
     }
 
     @Override
     public ScriptObject newTypeError(final String msg) {
-        return new NativeTypeError(msg);
+        return new NativeTypeError(msg, this);
     }
 
     @Override
     public ScriptObject newURIError(final String msg) {
-        return new NativeURIError(msg);
+        return new NativeURIError(msg, this);
     }
 
     @Override
     public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
-        return new GenericPropertyDescriptor(configurable, enumerable);
+        return new GenericPropertyDescriptor(configurable, enumerable, this);
     }
 
     @Override
     public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
-        return new DataPropertyDescriptor(configurable, enumerable, writable, value);
+        return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
     }
 
     @Override
     public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
-        final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set);
+        final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
 
         if (get == null) {
             desc.delete(PropertyDescriptor.GET, false);
@@ -701,7 +728,7 @@
         final Global global = Global.instance();
         final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
 
-        return global.context.eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
+        return global.getContext().eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
     }
 
     /**
@@ -741,7 +768,7 @@
     public static Object load(final Object self, final Object source) throws IOException {
         final Global global = Global.instance();
         final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
-        return global.context.load(scope, source);
+        return global.getContext().load(scope, source);
     }
 
     /**
@@ -761,7 +788,7 @@
         final Object from = hasArgs ? args[0] : UNDEFINED;
         final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;
 
-        return global.context.loadWithNewGlobal(from, arguments);
+        return global.getContext().loadWithNewGlobal(from, arguments);
     }
 
     /**
@@ -777,6 +804,7 @@
         return UNDEFINED;
     }
 
+    // builtin prototype accessors
     ScriptObject getFunctionPrototype() {
         return ScriptFunction.getPrototype(builtinFunction);
     }
@@ -885,11 +913,123 @@
         return ScriptFunction.getPrototype(builtinFloat64Array);
     }
 
+    // Builtin PropertyMap accessors
+    PropertyMap getAccessorPropertyDescriptorMap() {
+        return accessorPropertyDescriptorMap;
+    }
+
+    PropertyMap getArrayBufferViewMap() {
+        return arrayBufferViewMap;
+    }
+
+    PropertyMap getDataPropertyDescriptorMap() {
+        return dataPropertyDescriptorMap;
+    }
+
+    PropertyMap getGenericPropertyDescriptorMap() {
+        return genericPropertyDescriptorMap;
+    }
+
+    PropertyMap getArgumentsMap() {
+        return nativeArgumentsMap;
+    }
+
+    PropertyMap getArrayMap() {
+        return nativeArrayMap;
+    }
+
+    PropertyMap getArrayBufferMap() {
+        return nativeArrayBufferMap;
+    }
+
+    PropertyMap getBooleanMap() {
+        return nativeBooleanMap;
+    }
+
+    PropertyMap getDateMap() {
+        return nativeDateMap;
+    }
+
+    PropertyMap getErrorMap() {
+        return nativeErrorMap;
+    }
+
+    PropertyMap getEvalErrorMap() {
+        return nativeEvalErrorMap;
+    }
+
+    PropertyMap getJSAdapterMap() {
+        return nativeJSAdapterMap;
+    }
+
+    PropertyMap getJavaImporterMap() {
+        return nativeJavaImporterMap;
+    }
+
+    PropertyMap getNumberMap() {
+        return nativeNumberMap;
+    }
+
+    PropertyMap getRangeErrorMap() {
+        return nativeRangeErrorMap;
+    }
+
+    PropertyMap getReferenceErrorMap() {
+        return nativeReferenceErrorMap;
+    }
+
+    PropertyMap getRegExpMap() {
+        return nativeRegExpMap;
+    }
+
+    PropertyMap getRegExpExecResultMap() {
+        return nativeRegExpExecResultMap;
+    }
+
+    PropertyMap getStrictArgumentsMap() {
+        return nativeStrictArgumentsMap;
+    }
+
+    PropertyMap getStringMap() {
+        return nativeStringMap;
+    }
+
+    PropertyMap getSyntaxErrorMap() {
+        return nativeSyntaxErrorMap;
+    }
+
+    PropertyMap getTypeErrorMap() {
+        return nativeTypeErrorMap;
+    }
+
+    PropertyMap getURIErrorMap() {
+        return nativeURIErrorMap;
+    }
+
+    PropertyMap getPrototypeObjectMap() {
+        return prototypeObjectMap;
+    }
+
+    PropertyMap getObjectMap() {
+        return objectMap;
+    }
+
+    PropertyMap getFunctionMap() {
+        return functionMap;
+    }
+
+    PropertyMap getStrictFunctionMap() {
+        return strictFunctionMap;
+    }
+
+    PropertyMap getBoundFunctionMap() {
+        return boundFunctionMap;
+    }
+
     private ScriptFunction getBuiltinArray() {
         return builtinArray;
     }
 
-
     /**
      * Called from compiled script code to test if builtin has been overridden
      *
@@ -1395,7 +1535,11 @@
     private void init() {
         assert Context.getGlobal() == this : "this global is not set as current";
 
-        final ScriptEnvironment env = context.getEnv();
+        final ScriptEnvironment env = getContext().getEnv();
+
+        // duplicate PropertyMaps of Native* classes
+        copyInitialMaps();
+
         // initialize Function and Object constructor
         initFunctionAndObject();
 
@@ -1441,10 +1585,10 @@
         final ScriptObject arrayPrototype = getArrayPrototype();
         arrayPrototype.addOwnProperty("length", Attribute.NOT_ENUMERABLE|Attribute.NOT_CONFIGURABLE, 0.0);
 
-        this.DEFAULT_DATE = new NativeDate(Double.NaN);
+        this.DEFAULT_DATE = new NativeDate(Double.NaN, this);
 
         // initialize default regexp object
-        this.DEFAULT_REGEXP = new NativeRegExp("(?:)");
+        this.DEFAULT_REGEXP = new NativeRegExp("(?:)", this);
 
         // RegExp.prototype should behave like a RegExp object. So copy the
         // properties.
@@ -1560,7 +1704,7 @@
 
         // Nashorn extension: global.$OPTIONS (scripting-mode-only)
         final ScriptObject options = newObject();
-        final ScriptEnvironment scriptEnv = context.getEnv();
+        final ScriptEnvironment scriptEnv = getContext().getEnv();
         copyOptions(options, scriptEnv);
         addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
 
@@ -1713,6 +1857,37 @@
         }
     }
 
+    private void copyInitialMaps() {
+        this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
+        this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
+        this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
+        this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
+        this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
+        this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
+        this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
+        this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
+        this.nativeDateMap = NativeDate.getInitialMap().duplicate();
+        this.nativeErrorMap = NativeError.getInitialMap().duplicate();
+        this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
+        this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
+        this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
+        this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
+        this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
+        this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
+        this.nativeRegExpMap = NativeRegExp.getInitialMap().duplicate();
+        this.nativeRegExpExecResultMap = NativeRegExpExecResult.getInitialMap().duplicate();
+        this.nativeStrictArgumentsMap = NativeStrictArguments.getInitialMap().duplicate();
+        this.nativeStringMap = NativeString.getInitialMap().duplicate();
+        this.nativeSyntaxErrorMap = NativeSyntaxError.getInitialMap().duplicate();
+        this.nativeTypeErrorMap = NativeTypeError.getInitialMap().duplicate();
+        this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
+        this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
+        this.objectMap = JO.getInitialMap().duplicate();
+        this.functionMap = ScriptFunctionImpl.getInitialMap();
+        this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
+        this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
+    }
+
     // Function and Object constructors are inter-dependent. Also,
     // Function.prototype
     // functions are not properly initialized. We fix the references here.
@@ -1793,13 +1968,8 @@
         }
     }
 
-
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(Global.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
     }
 
     RegExpResult getLastRegExpResult() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java	Fri Jul 05 14:38:04 2013 +0530
@@ -70,14 +70,18 @@
         map$ = map;
     }
 
+    static PropertyMap getInitialMap() {
+        return map$;
+    }
+
     private Object length;
     private Object callee;
     private ArrayData namedArgs;
     // This is lazily initialized - only when delete is invoked at all
     private BitSet deleted;
 
-    NativeArguments(final ScriptObject proto, final Object[] arguments, final Object callee, final int numParams) {
-        super(proto, map$);
+    NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         setIsArguments();
 
         setArray(ArrayData.allocate(arguments));
@@ -550,8 +554,13 @@
     public static ScriptObject allocate(final Object[] arguments, final ScriptFunction callee, final int numParams) {
         // Strict functions won't always have a callee for arguments, and will pass null instead.
         final boolean isStrict = callee == null || callee.isStrict();
-        final ScriptObject proto = Global.objectPrototype();
-        return isStrict ? new NativeStrictArguments(proto, arguments, numParams) : new NativeArguments(proto, arguments, callee, numParams);
+        final Global global = Global.instance();
+        final ScriptObject proto = global.getObjectPrototype();
+        if (isStrict) {
+            return new NativeStrictArguments(arguments, numParams, proto, global.getStrictArgumentsMap());
+        } else {
+            return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap());
+        }
     }
 
     /**
@@ -623,11 +632,6 @@
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(NativeArguments.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeArguments.class, name, MH.type(rtype, types));
     }
-
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Fri Jul 05 14:38:04 2013 +0530
@@ -86,6 +86,10 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
     /*
      * Constructors.
      */
@@ -130,7 +134,11 @@
     }
 
     NativeArray(final ArrayData arrayData) {
-        super(Global.instance().getArrayPrototype(), $nasgenmap$);
+        this(arrayData, Global.instance());
+    }
+
+    NativeArray(final ArrayData arrayData, final Global global) {
+        super(global.getArrayPrototype(), global.getArrayMap());
         this.setArray(arrayData);
         this.setIsArray();
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Fri Jul 05 14:38:04 2013 +0530
@@ -43,6 +43,10 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
     @Constructor(arity = 1)
     public static Object constructor(final boolean newObj, final Object self, final Object... args) {
         if (args.length == 0) {
@@ -52,9 +56,13 @@
         return new NativeArrayBuffer(JSType.toInt32(args[0]));
     }
 
+    protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
+        super(global.getArrayBufferPrototype(), global.getArrayBufferMap());
+        this.buffer = byteArray;
+    }
+
     protected NativeArrayBuffer(final byte[] byteArray) {
-        super(Global.instance().getArrayBufferPrototype(), $nasgenmap$);
-        this.buffer = byteArray;
+        this(byteArray, Global.instance());
     }
 
     protected NativeArrayBuffer(final int byteLength) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Fri Jul 05 14:38:04 2013 +0530
@@ -56,15 +56,23 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeBoolean(final boolean value) {
-        this(value, Global.instance().getBooleanPrototype());
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    private NativeBoolean(final boolean value, final ScriptObject proto) {
-        super(proto, $nasgenmap$);
+    private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         this.value = value;
     }
 
+    NativeBoolean(final boolean flag, final Global global) {
+        this(flag, global.getBooleanPrototype(), global.getBooleanMap());
+    }
+
+    NativeBoolean(final boolean flag) {
+        this(flag, Global.instance());
+    }
+
     @Override
     public String safeToString() {
         return "[Boolean " + toString() + "]";
@@ -131,11 +139,7 @@
         final boolean flag = JSType.toBoolean(value);
 
         if (newObj) {
-            final ScriptObject proto = (self instanceof ScriptObject) ?
-                ((ScriptObject)self).getProto() :
-                Global.instance().getBooleanPrototype();
-
-            return new NativeBoolean(flag, proto);
+            return new NativeBoolean(flag);
         }
 
         return flag;
@@ -176,10 +180,6 @@
     }
 
     private static MethodHandle findWrapFilter() {
-        try {
-            return MethodHandles.lookup().findStatic(NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
-        } catch (NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Fri Jul 05 14:38:04 2013 +0530
@@ -104,18 +104,30 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeDate() {
-        this(System.currentTimeMillis());
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    NativeDate(final double time) {
-        super(Global.instance().getDatePrototype(), $nasgenmap$);
+    private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         final ScriptEnvironment env = Global.getEnv();
 
         this.time = time;
         this.timezone = env._timezone;
     }
 
+    NativeDate(final double time, final Global global) {
+        this(time, global.getDatePrototype(), global.getDateMap());
+    }
+
+    private NativeDate (final double time) {
+        this(time, Global.instance());
+    }
+
+    private NativeDate() {
+        this(System.currentTimeMillis());
+    }
+
     @Override
     public String getClassName() {
         return "Date";
@@ -153,6 +165,10 @@
      */
     @Constructor(arity = 7)
     public static Object construct(final boolean isNew, final Object self, final Object... args) {
+        if (! isNew) {
+            return toStringImpl(new NativeDate(), FORMAT_DATE_TIME);
+        }
+
         NativeDate result;
         switch (args.length) {
         case 0:
@@ -182,7 +198,7 @@
             break;
          }
 
-         return isNew ? result : toStringImpl(new NativeDate(), FORMAT_DATE_TIME);
+         return result;
     }
 
     @Override
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java	Fri Jul 05 14:38:04 2013 +0530
@@ -51,8 +51,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeDebug() {
-        super(Global.objectPrototype(), $nasgenmap$);
+    private NativeDebug() {
+        // don't create me!
+        throw new UnsupportedOperationException();
     }
 
     @Override
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -87,8 +87,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeError(final Object msg) {
-        super(Global.instance().getErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -96,6 +100,14 @@
         }
     }
 
+    NativeError(final Object msg, final Global global) {
+        this(msg, global.getErrorPrototype(), global.getErrorMap());
+    }
+
+    private NativeError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
@@ -354,11 +366,7 @@
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeError.class, name, MH.type(rtype, types));
     }
 
     private static String getScriptStackString(final ScriptObject sobj, final Throwable exp) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,8 +58,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeEvalError(final Object msg) {
-        super(Global.instance().getEvalErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -67,12 +71,19 @@
         }
     }
 
+    NativeEvalError(final Object msg, final Global global) {
+        this(msg, global.getEvalErrorPrototype(), global.getEvalErrorMap());
+    }
+
+    private NativeEvalError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
     }
 
-
     /**
      * ECMA 15.11.6.1 EvalError
      *
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -192,7 +192,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getFloat32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getFloat32ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -202,7 +202,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getFloat64ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getFloat64ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java	Fri Jul 05 14:38:04 2013 +0530
@@ -61,6 +61,7 @@
 
     // do *not* create me!
     private NativeFunction() {
+        throw new UnsupportedOperationException();
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -151,7 +151,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt16ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt16ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -154,7 +154,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt32ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -144,7 +144,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt8ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt8ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Fri Jul 05 14:38:04 2013 +0530
@@ -49,6 +49,7 @@
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.scripts.JO;
 
 /**
  * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be
@@ -146,8 +147,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeJSAdapter(final ScriptObject proto, final Object overrides, final ScriptObject adaptee) {
-        super(proto, $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         this.adaptee = wrapAdaptee(adaptee);
         if (overrides instanceof ScriptObject) {
             this.overrides = true;
@@ -159,9 +164,7 @@
     }
 
     private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
-        final ScriptObject sobj = new jdk.nashorn.internal.scripts.JO();
-        sobj.setProto(adaptee);
-        return sobj;
+        return new JO(adaptee, Global.instance().getObjectMap());
     }
 
     @Override
@@ -570,11 +573,12 @@
             throw typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
         }
 
+        final Global global = Global.instance();
         if (proto != null && !(proto instanceof ScriptObject)) {
-            proto = Global.instance().getJSAdapterPrototype();
+            proto = global.getJSAdapterPrototype();
         }
 
-        return new NativeJSAdapter((ScriptObject)proto, overrides, (ScriptObject)adaptee);
+        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, global.getJSAdapterMap());
     }
 
     @Override
@@ -736,10 +740,6 @@
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(NativeJSAdapter.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeJSAdapter.class, name, MH.type(rtype, types));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java	Fri Jul 05 14:38:04 2013 +0530
@@ -62,8 +62,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeJSON() {
-        super(Global.objectPrototype(), $nasgenmap$);
+    private NativeJSON() {
+        // don't create me!!
+        throw new UnsupportedOperationException();
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java	Fri Jul 05 14:38:04 2013 +0530
@@ -60,6 +60,8 @@
     private static PropertyMap $nasgenmap$;
 
     private NativeJava() {
+        // don't create me
+        throw new UnsupportedOperationException();
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Fri Jul 05 14:38:04 2013 +0530
@@ -59,11 +59,23 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeJavaImporter(final Object[] args) {
-        super(Global.instance().getJavaImporterPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         this.args = args;
     }
 
+    private NativeJavaImporter(final Object[] args, final Global global) {
+        this(args, global.getJavaImporterPrototype(), global.getJavaImporterMap());
+    }
+
+    private NativeJavaImporter(final Object[] args) {
+        this(args, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "JavaImporter";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java	Fri Jul 05 14:38:04 2013 +0530
@@ -45,8 +45,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeMath() {
-        super(Global.objectPrototype(), $nasgenmap$);
+    private NativeMath() {
+        // don't create me!
+        throw new UnsupportedOperationException();
     }
 
     /** ECMA 15.8.1.1 - E, always a double constant. Not writable or configurable */
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Fri Jul 05 14:38:04 2013 +0530
@@ -87,17 +87,26 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeNumber(final double value) {
-        this(value, Global.instance().getNumberPrototype());
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    private NativeNumber(final double value, final ScriptObject proto) {
-        super(proto, $nasgenmap$);
+    private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         this.value = value;
         this.isInt  = isRepresentableAsInt(value);
         this.isLong = isRepresentableAsLong(value);
     }
 
+    NativeNumber(final double value, final Global global) {
+        this(value, global.getNumberPrototype(), global.getNumberMap());
+    }
+
+    private NativeNumber(final double value) {
+        this(value, Global.instance());
+    }
+
+
     @Override
     public String safeToString() {
         return "[Number " + toString() + "]";
@@ -165,16 +174,7 @@
     public static Object constructor(final boolean newObj, final Object self, final Object... args) {
         final double num = (args.length > 0) ? JSType.toNumber(args[0]) : 0.0;
 
-        if (newObj) {
-            final ScriptObject proto =
-                (self instanceof ScriptObject) ?
-                    ((ScriptObject)self).getProto() :
-                    Global.instance().getNumberPrototype();
-
-            return new NativeNumber(num, proto);
-        }
-
-        return num;
+        return newObj? new NativeNumber(num) : num;
     }
 
     /**
@@ -380,10 +380,6 @@
     }
 
     private static MethodHandle findWrapFilter() {
-        try {
-            return MethodHandles.lookup().findStatic(NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,6 +58,8 @@
     private static PropertyMap $nasgenmap$;
 
     private NativeObject() {
+        // don't create me!
+        throw new UnsupportedOperationException();
     }
 
     private static ECMAException notAnObject(final Object obj) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,8 +58,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeRangeError(final Object msg) {
-        super(Global.instance().getRangeErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -67,6 +71,14 @@
         }
     }
 
+    NativeRangeError(final Object msg, final Global global) {
+        this(msg, global.getRangeErrorPrototype(), global.getRangeErrorMap());
+    }
+
+    private NativeRangeError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,8 +58,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeReferenceError(final Object msg) {
-        super(Global.instance().getReferenceErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -67,6 +71,14 @@
         }
     }
 
+    NativeReferenceError(final Object msg, final Global global) {
+        this(msg, global.getReferenceErrorPrototype(), global.getReferenceErrorMap());
+    }
+
+    private NativeReferenceError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Fri Jul 05 14:38:04 2013 +0530
@@ -71,7 +71,17 @@
     @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
-    NativeRegExp(final String input, final String flagString) {
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private NativeRegExp(final Global global) {
+        super(global.getRegExpPrototype(), global.getRegExpMap());
+        this.globalObject = global;
+    }
+
+    NativeRegExp(final String input, final String flagString, final Global global) {
+        this(global);
         try {
             this.regexp = RegExpFactory.create(input, flagString);
         } catch (final ParserException e) {
@@ -81,17 +91,24 @@
         }
 
         this.setLastIndex(0);
-        init();
+    }
+
+    NativeRegExp(final String input, final String flagString) {
+        this(input, flagString, Global.instance());
+    }
+
+    NativeRegExp(final String string, final Global global) {
+        this(string, "", global);
     }
 
     NativeRegExp(final String string) {
-        this(string, "");
+        this(string, Global.instance());
     }
 
     NativeRegExp(final NativeRegExp regExp) {
+        this(Global.instance());
         this.lastIndex  = regExp.getLastIndexObject();
         this.regexp      = regExp.getRegExp();
-        init();
     }
 
     @Override
@@ -615,7 +632,7 @@
             return null;
         }
 
-        return new NativeRegExpExecResult(match);
+        return new NativeRegExpExecResult(match, globalObject);
     }
 
     /**
@@ -886,12 +903,6 @@
         this.lastIndex = JSType.toObject(lastIndex);
     }
 
-    private void init() {
-        // Keep reference to global object to support "static" properties of RegExp
-        this.globalObject = Global.instance();
-        this.setProto(globalObject.getRegExpPrototype());
-    }
-
     private static NativeRegExp checkRegExp(final Object self) {
         Global.checkObjectCoercible(self);
         if (self instanceof NativeRegExp) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Fri Jul 05 14:38:04 2013 +0530
@@ -53,8 +53,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeRegExpExecResult(final RegExpResult result) {
-        super(Global.instance().getArrayPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    NativeRegExpExecResult(final RegExpResult result, final Global global) {
+        super(global.getArrayPrototype(), global.getRegExpExecResultMap());
         setIsArray();
         this.setArray(ArrayData.allocate(result.getGroups().clone()));
         this.index = result.getIndex();
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Fri Jul 05 14:38:04 2013 +0530
@@ -64,11 +64,15 @@
         map$ = map;
     }
 
+    static PropertyMap getInitialMap() {
+        return map$;
+    }
+
     private Object   length;
     private final Object[] namedArgs;
 
-    NativeStrictArguments(final ScriptObject proto, final Object[] values, final int numParams) {
-        super(proto, map$);
+    NativeStrictArguments(final Object[] values, final int numParams,final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         setIsArguments();
 
         final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower();
@@ -143,10 +147,6 @@
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(NativeStrictArguments.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeStrictArguments.class, name, MH.type(rtype, types));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Fri Jul 05 14:38:04 2013 +0530
@@ -41,7 +41,7 @@
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFactory.LookupException;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -74,12 +74,20 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeString(final CharSequence value) {
-        this(value, Global.instance().getStringPrototype());
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
     }
 
-    private NativeString(final CharSequence value, final ScriptObject proto) {
-        super(proto, $nasgenmap$);
+    private NativeString(final CharSequence value) {
+        this(value, Global.instance());
+    }
+
+    NativeString(final CharSequence value, final Global global) {
+        this(value, global.getStringPrototype(), global.getStringMap());
+    }
+
+    private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
         assert value instanceof String || value instanceof ConsString;
         this.value = value;
     }
@@ -147,9 +155,9 @@
 
         if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
             try {
-                MethodHandle mh = MethodHandles.lookup().findStatic(NativeString.class, "get", desc.getMethodType());
+                MethodHandle mh = MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType());
                 return new GuardedInvocation(mh, NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
-            } catch (final NoSuchMethodException | IllegalAccessException e) {
+            } catch (final LookupException e) {
                 // Shouldn't happen. Fall back to super
             }
         }
@@ -1065,10 +1073,7 @@
     }
 
     private static Object newObj(final Object self, final CharSequence str) {
-        if (self instanceof ScriptObject) {
-            return new NativeString(str, ((ScriptObject)self).getProto());
-        }
-        return new NativeString(str, Global.instance().getStringPrototype());
+        return new NativeString(str);
     }
 
     /**
@@ -1202,10 +1207,6 @@
     }
 
     private static MethodHandle findWrapFilter() {
-        try {
-            return MethodHandles.lookup().findStatic(NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,8 +58,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeSyntaxError(final Object msg) {
-        super(Global.instance().getSyntaxErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    NativeSyntaxError(final Object msg, final Global global) {
+        super(global.getSyntaxErrorPrototype(), global.getSyntaxErrorMap());
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -67,6 +71,10 @@
         }
     }
 
+    private NativeSyntaxError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -58,8 +58,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeTypeError(final Object msg) {
-        super(Global.instance().getTypeErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    NativeTypeError(final Object msg, final Global global) {
+        super(global.getTypeErrorPrototype(), global.getTypeErrorMap());
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -67,6 +71,10 @@
         }
     }
 
+    private NativeTypeError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java	Fri Jul 05 14:38:04 2013 +0530
@@ -57,8 +57,12 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    NativeURIError(final Object msg) {
-        super(Global.instance().getURIErrorPrototype(), $nasgenmap$);
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    NativeURIError(final Object msg, final Global global) {
+        super(global.getURIErrorPrototype(), global.getURIErrorMap());
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
@@ -66,6 +70,10 @@
         }
     }
 
+    private NativeURIError(final Object msg) {
+        this(msg, Global.instance());
+    }
+
     @Override
     public String getClassName() {
         return "Error";
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -150,7 +150,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint16ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint16ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -169,7 +169,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint32ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Fri Jul 05 14:38:04 2013 +0530
@@ -143,7 +143,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint8ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint8ArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Fri Jul 05 14:38:04 2013 +0530
@@ -160,7 +160,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint8ClampedArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint8ClampedArrayPrototype();
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java	Fri Jul 05 14:38:04 2013 +0530
@@ -57,8 +57,17 @@
         map$ = map;
     }
 
+    static PropertyMap getInitialMap() {
+        return map$;
+    }
+
+    private PrototypeObject(final Global global, final PropertyMap map) {
+        super(map != map$? map.addAll(global.getPrototypeObjectMap()) : global.getPrototypeObjectMap());
+        setProto(global.getObjectPrototype());
+    }
+
     PrototypeObject() {
-        this(map$);
+        this(Global.instance(), map$);
     }
 
     /**
@@ -67,12 +76,11 @@
      * @param map property map
      */
     public PrototypeObject(final PropertyMap map) {
-        super(map != map$ ? map.addAll(map$) : map$);
-        setProto(Global.objectPrototype());
+        this(Global.instance(), map);
     }
 
     PrototypeObject(final ScriptFunction func) {
-        this(map$);
+        this(Global.instance(), map$);
         this.constructor = func;
     }
 
@@ -107,10 +115,6 @@
     }
 
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        try {
-            return MethodHandles.lookup().findStatic(PrototypeObject.class, name, MH.type(rtype, types));
-        } catch (final NoSuchMethodException | IllegalAccessException e) {
-            throw new MethodHandleFactory.LookupException(e);
-        }
+        return MH.findStatic(MethodHandles.lookup(), PrototypeObject.class, name, MH.type(rtype, types));
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Fri Jul 05 14:38:04 2013 +0530
@@ -53,9 +53,26 @@
     // property map for non-strict, non-bound functions.
     private static final PropertyMap map$;
 
+    static PropertyMap getInitialMap() {
+        return map$;
+    }
+
+    static PropertyMap getInitialStrictMap() {
+        return strictmodemap$;
+    }
+
+    static PropertyMap getInitialBoundMap() {
+        return boundfunctionmap$;
+    }
+
     // Marker object for lazily initialized prototype object
     private static final Object LAZY_PROTOTYPE = new Object();
 
+    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
+        super(name, invokeHandle, global.getFunctionMap(), null, specs, false, true, true);
+        init(global);
+    }
+
     /**
      * Constructor called by Nasgen generated code, no membercount, use the default map.
      * Creates builtin functions only.
@@ -65,8 +82,12 @@
      * @param specs specialized versions of this method, if available, null otherwise
      */
     ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
-        super(name, invokeHandle, map$, null, specs, false, true, true);
-        init();
+        this(name, invokeHandle, specs, Global.instance());
+    }
+
+    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
+        super(name, invokeHandle, map.addAll(global.getFunctionMap()), null, specs, false, true, true);
+        init(global);
     }
 
     /**
@@ -79,8 +100,12 @@
      * @param specs specialized versions of this method, if available, null otherwise
      */
     ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
-        super(name, invokeHandle, map.addAll(map$), null, specs, false, true, true);
-        init();
+        this(name, invokeHandle, map, specs, Global.instance());
+    }
+
+    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor, final Global global) {
+        super(name, methodHandle, getMap(global, isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
+        init(global);
     }
 
     /**
@@ -95,8 +120,12 @@
      * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
      */
     ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        super(name, methodHandle, getMap(isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
-        init();
+        this(name, methodHandle, scope, specs, isStrict, isBuiltin, isConstructor, Global.instance());
+    }
+
+    private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
+        super(data, getMap(global, data.isStrict()), scope);
+        init(global);
     }
 
     /**
@@ -106,17 +135,17 @@
      * @param scope scope object
      */
     public ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope) {
-        super(data, getMap(data.isStrict()), scope);
-        init();
+        this(data, scope, Global.instance());
     }
 
     /**
      * Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
      * @param data the script function data for the bound function.
+     * @param global the global object
      */
-    ScriptFunctionImpl(final ScriptFunctionData data) {
-        super(data, boundfunctionmap$, null);
-        init();
+    ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
+        super(data, global.getBoundFunctionMap(), null);
+        init(global);
     }
 
     static {
@@ -159,8 +188,8 @@
     }
 
     // Choose the map based on strict mode!
-    private static PropertyMap getMap(final boolean strict) {
-        return strict ? strictmodemap$ : map$;
+    private static PropertyMap getMap(final Global global, final boolean strict) {
+        return strict ? global.getStrictFunctionMap() : global.getFunctionMap();
     }
 
     private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
@@ -255,8 +284,8 @@
     }
 
     // Internals below..
-    private void init() {
-        this.setProto(Global.instance().getFunctionPrototype());
+    private void init(final Global global) {
+        this.setProto(global.getFunctionPrototype());
         this.prototype = LAZY_PROTOTYPE;
 
         // We have to fill user accessor functions late as these are stored
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Fri Jul 05 14:38:04 2013 +0530
@@ -36,7 +36,6 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.AccessControlContext;
@@ -55,6 +54,7 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.options.Options;
 
@@ -123,8 +123,8 @@
             sm.checkPermission(new RuntimePermission("nashorn.setGlobal"));
         }
 
-        if (global != null && !(global instanceof GlobalObject)) {
-            throw new IllegalArgumentException("global does not implement GlobalObject!");
+        if (global != null && !(global instanceof Global)) {
+            throw new IllegalArgumentException("global is not an instance of Global!");
         }
 
         setGlobalTrusted(global);
@@ -257,8 +257,7 @@
              new PrivilegedAction<ClassLoader>() {
                 @Override
                 public ClassLoader run() {
-                    final StructureLoader structureLoader = new StructureLoader(sharedLoader, Context.this);
-                    return new ScriptLoader(structureLoader, Context.this);
+                    return new ScriptLoader(sharedLoader, Context.this);
                 }
              });
         this.errors    = errors;
@@ -817,25 +816,12 @@
              new PrivilegedAction<ScriptLoader>() {
                 @Override
                 public ScriptLoader run() {
-                    // Generated code won't refer to any class generated by context
-                    // script loader and so parent loader can be the structure
-                    // loader -- which is parent of the context script loader.
-                    return new ScriptLoader((StructureLoader)scriptLoader.getParent(), Context.this);
+                    return new ScriptLoader(sharedLoader, Context.this);
                 }
              });
     }
 
     private ScriptObject newGlobalTrusted() {
-        try {
-            final Class<?> clazz = Class.forName("jdk.nashorn.internal.objects.Global", true, scriptLoader);
-            final Constructor<?> cstr = clazz.getConstructor(Context.class);
-            return (ScriptObject) cstr.newInstance(this);
-        } catch (final Exception e) {
-            printStackTrace(e);
-            if (e instanceof RuntimeException) {
-                throw (RuntimeException)e;
-            }
-            throw new RuntimeException(e);
-        }
+        return new Global(this);
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Fri Jul 05 14:38:04 2013 +0530
@@ -34,9 +34,6 @@
 
 /**
  * Utilities used by Global class.
- *
- * These are actual implementation methods for functions exposed by global
- * scope. The code lives here to share the code across the contexts.
  */
 public final class GlobalFunctions {
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java	Fri Jul 05 14:38:04 2013 +0530
@@ -30,14 +30,7 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 
 /**
- * Runtime interface to the global scope of the current context.
- * NOTE: never access {@code jdk.nashorn.internal.objects.Global} class directly
- * from runtime/parser/codegen/ir etc. Always go through this interface.
- * <p>
- * The reason for this is that all objects in the @{code jdk.nashorn.internal.objects.*} package
- * are different per Context and loaded separately by each Context class loader. Attempting
- * to directly refer to an object in this package from the rest of the runtime
- * will lead to {@code ClassNotFoundException} thrown upon link time
+ * Runtime interface to the global scope objects.
  */
 
 public interface GlobalObject {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Jul 05 14:38:04 2013 +0530
@@ -1027,6 +1027,15 @@
     }
 
     /**
+     * Set the current context.
+     * @param ctx context instance to set
+     */
+    protected final void setContext(final Context ctx) {
+        ctx.getClass();
+        this.context = ctx;
+    }
+
+    /**
      * Return the map of an object.
      * @return PropertyMap object.
      */
--- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java	Fri Jul 05 14:38:04 2013 +0530
@@ -25,30 +25,19 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.codegen.Compiler.OBJECTS_PACKAGE;
 import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE;
 import static jdk.nashorn.internal.codegen.Compiler.binaryName;
 import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.CodeSigner;
-import java.security.CodeSource;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 
 /**
- * Responsible for on the fly construction of structure classes as well
- * as loading jdk.nashorn.internal.objects.* classes.
+ * Responsible for on the fly construction of structure classes.
  *
  */
 final class StructureLoader extends NashornLoader {
     private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName();
-    private static final String OBJECTS_PACKAGE_EXTERNAL  = binaryName(OBJECTS_PACKAGE);
 
     /**
      * Constructor.
@@ -68,45 +57,9 @@
             return loadedClass;
         }
 
-        if (name.startsWith(binaryName(OBJECTS_PACKAGE_EXTERNAL))) {
-            try {
-                return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
-                    @Override
-                    public Class<?> run() throws ClassNotFoundException {
-                        final String      source  = name.replace('.','/') + ".clazz";
-                        final URL         url     = getResource(source);
-                        try (final InputStream is = getResourceAsStream(source)) {
-                            if (is == null) {
-                                throw new ClassNotFoundException(name);
-                            }
-
-                            byte[] code;
-                            try {
-                                code = Source.readBytes(is);
-                            } catch (final IOException e) {
-                                Context.printStackTrace(e);
-                                throw new ClassNotFoundException(name, e);
-                            }
-
-                            final Class<?> cl = defineClass(name, code, 0, code.length, new CodeSource(url, (CodeSigner[])null));
-                            if (resolve) {
-                                resolveClass(cl);
-                            }
-                            return cl;
-                        } catch (final IOException e) {
-                            throw new RuntimeException(e);
-                        }
-                    }
-                });
-            } catch (final PrivilegedActionException  e) {
-                throw new ClassNotFoundException(name, e);
-            }
-        }
-
         return super.loadClassTrusted(name, resolve);
     }
 
-
     @Override
     protected Class<?> findClass(final String name) throws ClassNotFoundException {
         if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) {
--- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java	Fri Jul 05 14:38:04 2013 +0530
@@ -36,10 +36,11 @@
     private static final PropertyMap map$ = PropertyMap.newMap(JO.class);
 
     /**
-     * Constructor
+     * Returns the initial property map to be used.
+     * @return the initial property map.
      */
-    public JO() {
-        super(map$);
+    public static PropertyMap getInitialMap() {
+        return map$;
     }
 
     /**
@@ -52,16 +53,17 @@
     }
 
     /**
-     * Constructor given an initial prototype using the default property map
+     * Constructor given an initial prototype and an initial property map.
      *
      * @param proto the prototype object
+     * @param map the property map
      */
-    public JO(final ScriptObject proto) {
-        super(proto, map$);
+    public JO(final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
     }
 
     /**
-     * Used by FunctionObjectCreator. A method handle of this method is passed to the ScriptFunction constructor.
+     * A method handle of this method is passed to the ScriptFunction constructor.
      *
      * @param map  the property map to use for allocatorMap
      *
--- a/nashorn/src/jdk/nashorn/tools/Shell.java	Thu Jul 04 17:28:04 2013 +0200
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java	Fri Jul 05 14:38:04 2013 +0530
@@ -47,6 +47,7 @@
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -446,7 +447,7 @@
                 }
 
                 if (res != null && res != ScriptRuntime.UNDEFINED) {
-                    err.println(ScriptRuntime.safeToString(res));
+                    err.println(JSType.toString(res));
                 }
             }
         } finally {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019947.js	Fri Jul 05 14:38:04 2013 +0530
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019947: inherited property invalidation does not work with two globals in same context
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+function func(arr) {
+    try {
+       print(arr.toString());
+    } catch (e) {
+       print(e.stack);
+    }
+}
+
+var arr = ["hello", "world"]
+
+func(arr);
+
+var global = loadWithNewGlobal({
+   name: "t",
+   script: <<EOF
+
+
+function func(arr) {
+   try {
+       print(arr.toString());
+   } catch (e) {
+       print(e.stack);
+   }
+}
+
+var arr = [1, 2, 3];
+
+func(arr);
+
+delete Array.prototype.toString;
+
+// Object.prototype.toString should be visible
+// after Array.prototype.toString is deleted.
+func(arr);
+this;
+EOF
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019947.js.EXPECTED	Fri Jul 05 14:38:04 2013 +0530
@@ -0,0 +1,3 @@
+hello,world
+1,2,3
+[object Array]