changeset 425:c96745616167

Merge
author sundar
date Mon, 08 Jul 2013 18:43:41 +0530
parents 542b7803f038 a75e75cc6a61
children 8108ba8366fd
files
diffstat 151 files changed, 21212 insertions(+), 1320 deletions(-) [+]
line wrap: on
line diff
--- a/buildtools/nasgen/build.xml	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/build.xml	Mon Jul 08 18:43:41 2013 +0530
@@ -42,7 +42,8 @@
            destdir="${build.classes.dir}"
            classpath="${javac.classpath}"
            debug="${javac.debug}"
-           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/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.tools.nasgen;
 
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
@@ -36,14 +37,24 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_TYPE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
@@ -160,18 +171,30 @@
         return new MethodGenerator(mv, access, name, desc);
     }
 
-    static void emitStaticInitPrefix(final MethodGenerator mi, final String className) {
+    static void emitStaticInitPrefix(final MethodGenerator mi, final String className, final int memberCount) {
         mi.visitCode();
-        mi.pushNull();
-        mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
-        mi.loadClass(className);
-        mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC);
-        // stack: PropertyMap
+        if (memberCount > 0) {
+            // new ArrayList(int)
+            mi.newObject(ARRAYLIST_TYPE);
+            mi.dup();
+            mi.push(memberCount);
+            mi.invokeSpecial(ARRAYLIST_TYPE, INIT, ARRAYLIST_INIT_DESC);
+            // stack: ArrayList
+        } else {
+            // java.util.Collections.EMPTY_LIST
+            mi.getStatic(COLLECTIONS_TYPE, COLLECTIONS_EMPTY_LIST, LIST_DESC);
+            // stack List
+        }
     }
 
     static void emitStaticInitSuffix(final MethodGenerator mi, final String className) {
-        // stack: PropertyMap
-        mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
+        // stack: Collection
+        // pmap = PropertyMap.newMap(Collection<Property>);
+        mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC);
+        // pmap.setIsShared();
+        mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_SETISSHARED, PROPERTYMAP_SETISSHARED_DESC);
+        // $nasgenmap$ = pmap;
+        mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
         mi.returnVoid();
         mi.computeMaxs();
         mi.visitEnd();
@@ -235,9 +258,9 @@
     }
 
     static void addMapField(final ClassVisitor cv) {
-        // add a MAP static field
-        final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC,
-            MAP_FIELD_NAME, MAP_DESC, null, null);
+        // add a PropertyMap static field
+        final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL,
+            PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC, null, null);
         if (fv != null) {
             fv.visitEnd();
         }
@@ -278,7 +301,11 @@
 
     static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
         final String propertyName = memInfo.getName();
-        // stack: PropertyMap
+        // stack: Collection
+        // dup of Collection instance
+        mi.dup();
+
+        // property = AccessorProperty.create(key, flags, getter, setter);
         mi.loadLiteral(propertyName);
         // setup flags
         mi.push(memInfo.getAttributes());
@@ -292,13 +319,21 @@
             javaName = SETTER_PREFIX + memInfo.getJavaName();
             mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo)));
         }
-        mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
-        // stack: PropertyMap
+        mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
+        // boolean Collection.add(property)
+        mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC);
+        // pop return value of Collection.add
+        mi.pop();
+        // stack: Collection
     }
 
     static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) {
         final String propertyName = getter.getName();
-        // stack: PropertyMap
+        // stack: Collection
+        // dup of Collection instance
+        mi.dup();
+
+        // property = AccessorProperty.create(key, flags, getter, setter);
         mi.loadLiteral(propertyName);
         // setup flags
         mi.push(getter.getAttributes());
@@ -312,8 +347,12 @@
             mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
                     setter.getJavaName(), setter.getJavaDesc()));
         }
-        mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
-        // stack: PropertyMap
+        mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
+        // boolean Collection.add(property)
+        mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC);
+        // pop return value of Collection.add
+        mi.pop();
+        // stack: Collection
     }
 
     static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException {
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -32,11 +32,11 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
@@ -129,7 +129,7 @@
 
     private void emitStaticInitializer() {
         final MethodGenerator mi = makeStaticInitializer();
-        emitStaticInitPrefix(mi, className);
+        emitStaticInitPrefix(mi, className, memberCount);
 
         for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
             if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) {
@@ -170,10 +170,10 @@
 
     private void loadMap(final MethodGenerator mi) {
         if (memberCount > 0) {
-            mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+            mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
             // make sure we use duplicated PropertyMap so that original map
-            // stays intact and so can be used for many globals in same context
-            mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+            // stays intact and so can be used for many globals.
+            mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
         }
     }
 
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -57,6 +57,7 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
 import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
@@ -347,6 +348,10 @@
     }
 
     // invokes, field get/sets
+    void invokeInterface(final String owner, final String method, final String desc) {
+        super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc);
+    }
+
     void invokeVirtual(final String owner, final String method, final String desc) {
         super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc);
     }
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -30,11 +30,11 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
@@ -67,6 +67,7 @@
             // add <clinit>
             emitStaticInitializer();
         }
+
         // add <init>
         emitConstructor();
 
@@ -106,7 +107,7 @@
 
     private void emitStaticInitializer() {
         final MethodGenerator mi = makeStaticInitializer();
-        emitStaticInitPrefix(mi, className);
+        emitStaticInitPrefix(mi, className, memberCount);
         for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
             if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) {
                 linkerAddGetterSetter(mi, className, memInfo);
@@ -124,10 +125,10 @@
         mi.loadThis();
         if (memberCount > 0) {
             // call "super(map$)"
-            mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+            mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
             // make sure we use duplicated PropertyMap so that original map
-            // stays intact and so can be used for many globals in same context
-            mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+            // stays intact and so can be used for many global.
+            mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
             mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
             // initialize Function type fields
             initFunctionFields(mi);
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Mon Jul 08 18:43:41 2013 +0530
@@ -37,10 +37,7 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
 
 import java.io.BufferedInputStream;
@@ -159,14 +156,7 @@
             public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
                 if (isConstructor && opcode == INVOKESPECIAL &&
                         INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
-
-                    // replace call to empty super-constructor with one passing PropertyMap argument
-                    if (DEFAULT_INIT_DESC.equals(desc)) {
-                        super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), MAP_FIELD_NAME, MAP_DESC);
-                        super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
-                    } else {
-                        super.visitMethodInsn(opcode, owner, name, desc);
-                    }
+                    super.visitMethodInsn(opcode, owner, name, desc);
 
                     if (memberCount > 0) {
                         // initialize @Property fields if needed
@@ -256,7 +246,7 @@
         }
         // Now generate $clinit$
         final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$);
-        ClassGenerator.emitStaticInitPrefix(mi, className);
+        ClassGenerator.emitStaticInitPrefix(mi, className, memberCount);
         if (memberCount > 0) {
             for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
                 if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) {
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Mon Jul 08 18:43:41 2013 +0530
@@ -27,10 +27,14 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import jdk.internal.org.objectweb.asm.Type;
-import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.objects.PrototypeObject;
 import jdk.nashorn.internal.objects.ScriptFunctionImpl;
+import jdk.nashorn.internal.runtime.AccessorProperty;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -40,15 +44,41 @@
  */
 @SuppressWarnings("javadoc")
 public interface StringConstants {
+    // standard jdk types, methods
     static final Type TYPE_METHOD             = Type.getType(Method.class);
     static final Type TYPE_METHODHANDLE       = Type.getType(MethodHandle.class);
     static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
     static final Type TYPE_OBJECT             = Type.getType(Object.class);
     static final Type TYPE_CLASS              = Type.getType(Class.class);
     static final Type TYPE_STRING             = Type.getType(String.class);
+    static final Type TYPE_COLLECTION         = Type.getType(Collection.class);
+    static final Type TYPE_COLLECTIONS        = Type.getType(Collections.class);
+    static final Type TYPE_ARRAYLIST          = Type.getType(ArrayList.class);
+    static final Type TYPE_LIST               = Type.getType(List.class);
 
-    // Nashorn types
-    static final Type TYPE_LOOKUP             = Type.getType(Lookup.class);
+    static final String CLINIT = "<clinit>";
+    static final String INIT = "<init>";
+    static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
+
+    static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+    static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
+    static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
+    static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
+    static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName();
+    static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName();
+    static final String COLLECTIONS_TYPE = TYPE_COLLECTIONS.getInternalName();
+
+    // java.util.Collection.add(Object)
+    static final String COLLECTION_ADD = "add";
+    static final String COLLECTION_ADD_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, TYPE_OBJECT);
+    // java.util.ArrayList.<init>(int)
+    static final String ARRAYLIST_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+    // java.util.Collections.EMPTY_LIST
+    static final String COLLECTIONS_EMPTY_LIST = "EMPTY_LIST";
+    static final String LIST_DESC = TYPE_LIST.getDescriptor();
+
+    // Nashorn types, methods
+    static final Type TYPE_ACCESSORPROPERTY   = Type.getType(AccessorProperty.class);
     static final Type TYPE_PROPERTYMAP        = Type.getType(PropertyMap.class);
     static final Type TYPE_PROTOTYPEOBJECT    = Type.getType(PrototypeObject.class);
     static final Type TYPE_SCRIPTFUNCTION     = Type.getType(ScriptFunction.class);
@@ -57,54 +87,56 @@
 
     static final String PROTOTYPE_SUFFIX = "$Prototype";
     static final String CONSTRUCTOR_SUFFIX = "$Constructor";
+
     // This field name is known to Nashorn runtime (Context).
     // Synchronize the name change, if needed at all.
-    static final String MAP_FIELD_NAME = "$nasgenmap$";
+    static final String PROPERTYMAP_FIELD_NAME = "$nasgenmap$";
     static final String $CLINIT$ = "$clinit$";
-    static final String CLINIT = "<clinit>";
-    static final String INIT = "<init>";
-    static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
 
-    static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
+    // AccessorProperty
+    static final String ACCESSORPROPERTY_TYPE = TYPE_ACCESSORPROPERTY.getInternalName();
+    static final String ACCESSORPROPERTY_CREATE = "create";
+    static final String ACCESSORPROPERTY_CREATE_DESC =
+        Type.getMethodDescriptor(TYPE_ACCESSORPROPERTY, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE);
 
-    static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+    // PropertyMap
+    static final String PROPERTYMAP_TYPE = TYPE_PROPERTYMAP.getInternalName();
+    static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
+    static final String PROPERTYMAP_NEWMAP = "newMap";
+    static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION);
+    static final String PROPERTYMAP_DUPLICATE = "duplicate";
+    static final String PROPERTYMAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
+    static final String PROPERTYMAP_SETISSHARED = "setIsShared";
+    static final String PROPERTYMAP_SETISSHARED_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
 
-    static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
-    static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
-    static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
+    // PrototypeObject
+    static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
+    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor";
+    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT);
 
+    // ScriptFunction
     static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
+    static final String SCRIPTFUNCTION_SETARITY = "setArity";
+    static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+    static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
+    static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
+
+    // ScriptFunctionImpl
     static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName();
     static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction";
     static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
         Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
     static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
         Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
-
     static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
         Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
     static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
         Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY);
-    static final String SCRIPTFUNCTION_SETARITY = "setArity";
-    static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
-    static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
-    static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
-    static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
-    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor";
-    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT);
+
+    // ScriptObject
     static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
-    static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName();
-    static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
-    static final String MAP_NEWMAP = "newMap";
-    static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_CLASS);
-    static final String MAP_DUPLICATE = "duplicate";
-    static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
-    static final String MAP_SETFLAGS = "setFlags";
-    static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName();
-    static final String LOOKUP_GETMETHOD = "getMethod";
-    static final String LOOKUP_NEWPROPERTY = "newProperty";
-    static final String LOOKUP_NEWPROPERTY_DESC =
-        Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE);
+    static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
+
     static final String GETTER_PREFIX = "G$";
     static final String SETTER_PREFIX = "S$";
 
--- a/docs/JavaScriptingProgrammersGuide.html	Fri Jul 05 11:05:50 2013 -0700
+++ b/docs/JavaScriptingProgrammersGuide.html	Mon Jul 08 18:43:41 2013 +0530
@@ -501,14 +501,19 @@
  var anArrayListWithSize = new ArrayList(16)
 </code></pre> 
 
-In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name:
+In the special case of inner classes, you can either use the JVM fully qualified name, meaning using the dollar sign in the class name, or you can use the dot:
 
 <pre><code>
  var ftype = Java.type("java.awt.geom.Arc2D$Float")
 </code></pre> 
  
+and
+ 
+<pre><code>
+ var ftype = Java.type("java.awt.geom.Arc2D.Float")
+</code></pre> 
 
-However, once you retrieved the outer class, you can access the inner class as a property on it:
+both work. Note however that using the dollar sign is faster, as Java.type first tries to resolve the class name as it is originally specified, and the internal JVM names for inner classes use the dollar sign. If you use the dot, Java.type will internally get a ClassNotFoundException and subsequently retry by changing the last dot to dollar sign. As a matter of fact, it'll keep replacing dots with dollar signs until it either successfully loads the class or runs out of all dots in the name. This way it can correctly resolve and load even multiply nested inner classes with the dot notation. Again, this will be slower than using the dollar signs in the name. An alternative way to access the inner class is as a property of the outer class:
 
 <pre><code>
  var arctype = Java.type("java.awt.geom.Arc2D")
--- a/make/build-nasgen.xml	Fri Jul 05 11:05:50 2013 -0700
+++ b/make/build-nasgen.xml	Mon Jul 08 18:43:41 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/make/build.xml	Fri Jul 05 11:05:50 2013 -0700
+++ b/make/build.xml	Mon Jul 08 18:43:41 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"/>
@@ -235,44 +236,31 @@
   </target>
 
   <target name="generate-policy-file" depends="prepare">
-    <!-- Generating nashorn.policy file -->
+    <echo file="${build.dir}/nashorn.policy">
 
-    <!-- nashorn internal tests jar requires AllPermission -->
-    <echo message="grant codeBase &quot;file:/${basedir}/${nashorn.internal.tests.jar}&quot; {" file="${build.dir}/nashorn.policy"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+grant codeBase "file:/${basedir}/${nashorn.internal.tests.jar}" {
+    permission java.security.AllPermission;
+};
 
-    <!-- TestNG framework jar needs AllPermission -->
-    <echo message="grant codeBase &quot;file:/${basedir}/${file.reference.testng.jar}&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+grant codeBase "file:/${basedir}/${file.reference.testng.jar}" {
+    permission java.security.AllPermission;
+};
 
-    <!-- AllPermission to test/script/trusted tests -->
-    <echo message="grant codeBase &quot;file:/${basedir}/test/script/trusted/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+grant codeBase "file:/${basedir}/test/script/trusted/*" {
+    permission java.security.AllPermission;
+};
 
-    <echo message="grant codeBase &quot;file:/${basedir}/test/script/basic/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <!-- test/script/basic .js scripts load other script tests -->
-    <echo message="    permission java.io.FilePermission &quot;${basedir}/test/script/-&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.io.FilePermission &quot;user.dir&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.util.PropertyPermission &quot;user.dir&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <!-- test/script/basic .js scripts can read nashorn.test.* properties -->
-    <echo message="    permission java.util.PropertyPermission &quot;nashorn.test.*&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+grant codeBase "file:/${basedir}/test/script/basic/*" {
+    permission java.io.FilePermission "${basedir}/test/script/-", "read";
+    permission java.io.FilePermission "$${user.dir}", "read";
+    permission java.util.PropertyPermission "user.dir", "read";
+    permission java.util.PropertyPermission "nashorn.test.*", "read";
+};
+
+grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" {
+    permission java.util.PropertyPermission "java.security.policy", "read";
+};
+    </echo>
 
     <replace file="${build.dir}/nashorn.policy"><replacetoken>\</replacetoken><replacevalue>/</replacevalue></replace>    <!--hack for Windows - to make URLs with normal path separators -->
     <replace file="${build.dir}/nashorn.policy"><replacetoken>//</replacetoken><replacevalue>/</replacevalue></replace>   <!--hack for Unix - to avoid leading // in URLs -->
--- a/make/code_coverage.xml	Fri Jul 05 11:05:50 2013 -0700
+++ b/make/code_coverage.xml	Mon Jul 08 18:43:41 2013 +0530
@@ -60,16 +60,8 @@
     <copy todir="${build.dir}/to_be_instrumented">
       <fileset dir="${build.classes.dir}">
         <include name="**/*.class"/>
-        <include name="**/*.clazz"/>
       </fileset>
     </copy>
-
-    <move todir="${build.dir}/to_be_instrumented/jdk/nashorn/internal/objects">
-      <fileset dir="${build.dir}/to_be_instrumented/jdk/nashorn/internal/objects">
-        <include name="**/*.clazz"/>
-      </fileset>
-      <mapper type="glob" from="*.clazz" to="*.class"/>
-    </move>
   </target>
 
   <target name="generate-cc-template" depends="prepare-to-be-instrumented" description="Generates code coverage template for dynamic CC" if="cc.generate.template">
--- a/make/project.properties	Fri Jul 05 11:05:50 2013 -0700
+++ b/make/project.properties	Mon Jul 08 18:43:41 2013 +0530
@@ -200,6 +200,9 @@
 
 # test262 test frameworks
 test262-test-sys-prop.test.js.framework=\
+    --class-cache-size=0 \
+    --no-java \
+    --no-typed-arrays \
     -timezone=PST \
     ${test.script.dir}/test262.js \
     ${test262.dir}/test/harness/framework.js \
--- a/makefiles/BuildNashorn.gmk	Fri Jul 05 11:05:50 2013 -0700
+++ b/makefiles/BuildNashorn.gmk	Mon Jul 08 18:43:41 2013 +0530
@@ -71,7 +71,6 @@
 $(BUILD_NASGEN): $(BUILD_NASHORN)
 
 # Copy classes to final classes dir and run nasgen to modify classes in jdk.nashorn.internal.objects package
-# Finally rename classes in jdk.nashorn.internal.objects package
 $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN)
 	$(ECHO) Running nasgen
 	$(MKDIR) -p $(@D)
@@ -80,9 +79,6 @@
 	$(FIXPATH) $(JAVA) \
 		-cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
 		jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
-	for f in `$(FIND) $(@D)/jdk/nashorn/internal/objects/ -name "*.class"`; do \
-	  mv "$$f" `$(ECHO) "$$f" | $(SED) "s/\.class$$/\.clazz/"`; \
-        done
 	$(TOUCH) $@
 
 # Version file needs to be processed with version numbers
@@ -104,7 +100,7 @@
     $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run \
     $(VERSION_FILE),\
     SRCS:=$(NASHORN_OUTPUTDIR)/classes,\
-    SUFFIXES:=.class .clazz .js .properties Factory,\
+    SUFFIXES:=.class .js .properties Factory,\
     MANIFEST:=$(NASHORN_TOPDIR)/src/META-INF/MANIFEST.MF,\
     EXTRA_MANIFEST_ATTR:=$(MANIFEST_ATTRIBUTES),\
     SKIP_METAINF:=true,\
--- a/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Mon Jul 08 18:43:41 2013 +0530
@@ -86,7 +86,10 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.HashMap;
@@ -109,10 +112,11 @@
  * @author Attila Szegedi
  */
 abstract class AbstractJavaLinker implements GuardingDynamicLinker {
+
     final Class<?> clazz;
     private final MethodHandle classGuard;
     private final MethodHandle assignableGuard;
-    private final Map<String, AnnotatedMethodHandle> propertyGetters = new HashMap<>();
+    private final Map<String, AnnotatedDynamicMethod> propertyGetters = new HashMap<>();
     private final Map<String, DynamicMethod> propertySetters = new HashMap<>();
     private final Map<String, DynamicMethod> methods = new HashMap<>();
 
@@ -129,22 +133,19 @@
         // Add methods and properties
         for(Method method: introspector.getMethods()) {
             final String name = method.getName();
-            final MethodHandle methodHandle = introspector.unreflect(method);
             // Add method
-            addMember(name, methodHandle, methods);
+            addMember(name, method, methods);
             // Add the method as a property getter and/or setter
             if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
                 // Property getter
-                setPropertyGetter(decapitalize(name.substring(3)), introspector.unreflect(
-                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
+                setPropertyGetter(method, 3);
             } else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 &&
                     method.getReturnType() == boolean.class) {
                 // Boolean property getter
-                setPropertyGetter(decapitalize(name.substring(2)), introspector.unreflect(
-                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
+                setPropertyGetter(method, 2);
             } else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) {
                 // Property setter
-                addMember(decapitalize(name.substring(3)), methodHandle, propertySetters);
+                addMember(decapitalize(name.substring(3)), method, propertySetters);
             }
         }
 
@@ -156,7 +157,8 @@
                 setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS);
             }
             if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) {
-                addMember(name, introspector.unreflectSetter(field), propertySetters);
+                addMember(name, new SimpleDynamicMethod(introspector.unreflectSetter(field), clazz, name),
+                        propertySetters);
             }
         }
 
@@ -192,38 +194,119 @@
 
     abstract FacetIntrospector createFacetIntrospector();
 
-    void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) {
-        propertyGetters.put(name, new AnnotatedMethodHandle(handle, validationType));
+    /**
+     * Sets the specified dynamic method to be the property getter for the specified property. Note that you can only
+     * use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties
+     * that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)}
+     * instead.
+     * @param name name of the property
+     * @param handle the method handle that implements the property getter
+     * @param validationType the validation type for the property
+     */
+    private void setPropertyGetter(String name, SingleDynamicMethod handle, ValidationType validationType) {
+        propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType));
     }
 
-    private void addMember(String name, MethodHandle mh, Map<String, DynamicMethod> methodMap) {
+    /**
+     * Sets the specified reflective method to be the property getter for the specified property.
+     * @param getter the getter method
+     * @param prefixLen the getter prefix in the method name; should be 3 for getter names starting with "get" and 2 for
+     * names starting with "is".
+     */
+    private void setPropertyGetter(Method getter, int prefixLen) {
+        setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod(
+                getMostGenericGetter(getter)), ValidationType.INSTANCE_OF);
+    }
+
+    /**
+     * Sets the specified method handle to be the property getter for the specified property. Note that you can only
+     * use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties
+     * that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)}
+     * instead.
+     * @param name name of the property
+     * @param handle the method handle that implements the property getter
+     * @param validationType the validation type for the property
+     */
+    void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) {
+        setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
+    }
+
+    private void addMember(String name, AccessibleObject ao, Map<String, DynamicMethod> methodMap) {
+        addMember(name, createDynamicMethod(ao), methodMap);
+    }
+
+    private void addMember(String name, SingleDynamicMethod method, Map<String, DynamicMethod> methodMap) {
         final DynamicMethod existingMethod = methodMap.get(name);
-        final DynamicMethod newMethod = addMember(mh, existingMethod, clazz, name);
+        final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name);
         if(newMethod != existingMethod) {
             methodMap.put(name, newMethod);
         }
     }
 
-    static DynamicMethod createDynamicMethod(Iterable<MethodHandle> methodHandles, Class<?> clazz, String name) {
+    /**
+     * Given one or more reflective methods or constructors, creates a dynamic method that represents them all. The
+     * methods should represent all overloads of the same name (or all constructors of the class).
+     * @param members the reflective members
+     * @param clazz the class declaring the reflective members
+     * @param name the common name of the reflective members.
+     * @return a dynamic method representing all the specified reflective members.
+     */
+    static DynamicMethod createDynamicMethod(Iterable<? extends AccessibleObject> members, Class<?> clazz, String name) {
         DynamicMethod dynMethod = null;
-        for(MethodHandle methodHandle: methodHandles) {
-            dynMethod = addMember(methodHandle, dynMethod, clazz, name);
+        for(AccessibleObject method: members) {
+            dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
         }
         return dynMethod;
     }
 
-    private static DynamicMethod addMember(MethodHandle mh, DynamicMethod existing, Class<?> clazz, String name) {
+    /**
+     * Given a reflective method or a constructor, creates a dynamic method that represents it. This method will
+     * distinguish between caller sensitive and ordinary methods/constructors, and create appropriate caller sensitive
+     * dynamic method when needed.
+     * @param m the reflective member
+     * @return the single dynamic method representing the reflective member
+     */
+    private static SingleDynamicMethod createDynamicMethod(AccessibleObject m) {
+        if(CallerSensitiveDetector.isCallerSensitive(m)) {
+            return new CallerSensitiveDynamicMethod(m);
+        }
+        final Member member = (Member)m;
+        return new SimpleDynamicMethod(unreflectSafely(m), member.getDeclaringClass(), member.getName());
+    }
+
+    /**
+     * Unreflects a method handle from a Method or a Constructor using safe (zero-privilege) unreflection. Should be
+     * only used for methods and constructors that are not caller sensitive. If a caller sensitive method were
+     * unreflected through this mechanism, it would not be a security issue, but would be bound to the zero-privilege
+     * unreflector as its caller, and thus completely useless.
+     * @param m the method or constructor
+     * @return the method handle
+     */
+    private static MethodHandle unreflectSafely(AccessibleObject m) {
+        if(m instanceof Method) {
+            final Method reflMethod = (Method)m;
+            final MethodHandle handle = SafeUnreflector.unreflect(reflMethod);
+            if(Modifier.isStatic(reflMethod.getModifiers())) {
+                return StaticClassIntrospector.editStaticMethodHandle(handle);
+            }
+            return handle;
+        }
+        return StaticClassIntrospector.editConstructorMethodHandle(SafeUnreflector.unreflectConstructor(
+                (Constructor<?>)m));
+    }
+
+    private static DynamicMethod mergeMethods(SingleDynamicMethod method, DynamicMethod existing, Class<?> clazz, String name) {
         if(existing == null) {
-            return new SimpleDynamicMethod(mh, clazz, name);
-        } else if(existing.contains(mh)) {
+            return method;
+        } else if(existing.contains(method)) {
             return existing;
-        } else if(existing instanceof SimpleDynamicMethod) {
+        } else if(existing instanceof SingleDynamicMethod) {
             final OverloadedDynamicMethod odm = new OverloadedDynamicMethod(clazz, name);
-            odm.addMethod(((SimpleDynamicMethod)existing));
-            odm.addMethod(mh);
+            odm.addMethod(((SingleDynamicMethod)existing));
+            odm.addMethod(method);
             return odm;
         } else if(existing instanceof OverloadedDynamicMethod) {
-            ((OverloadedDynamicMethod)existing).addMethod(mh);
+            ((OverloadedDynamicMethod)existing).addMethod(method);
             return existing;
         }
         throw new AssertionError();
@@ -296,7 +379,7 @@
     private GuardedInvocation getCallPropWithThis(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
         switch(callSiteDescriptor.getNameTokenCount()) {
             case 3: {
-                return createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(), linkerServices,
+                return createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                         callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), methods);
             }
             default: {
@@ -305,16 +388,16 @@
         }
     }
 
-    private GuardedInvocation createGuardedDynamicMethodInvocation(MethodType callSiteType,
+    private GuardedInvocation createGuardedDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor,
             LinkerServices linkerServices, String methodName, Map<String, DynamicMethod> methodMap){
-        final MethodHandle inv = getDynamicMethodInvocation(callSiteType, linkerServices, methodName, methodMap);
-        return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteType));
+        final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap);
+        return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType()));
     }
 
-    private static MethodHandle getDynamicMethodInvocation(MethodType callSiteType, LinkerServices linkerServices,
-            String methodName, Map<String, DynamicMethod> methodMap) {
+    private static MethodHandle getDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, String methodName, Map<String, DynamicMethod> methodMap) {
         final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap);
-        return dynaMethod != null ? dynaMethod.getInvocation(callSiteType, linkerServices) : null;
+        return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null;
     }
 
     private static DynamicMethod getDynamicMethod(String methodName, Map<String, DynamicMethod> methodMap) {
@@ -322,13 +405,13 @@
         return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap);
     }
 
-    private static SimpleDynamicMethod getExplicitSignatureDynamicMethod(String methodName,
+    private static SingleDynamicMethod getExplicitSignatureDynamicMethod(String methodName,
             Map<String, DynamicMethod> methodsMap) {
         // What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name
         // to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method
         // resolution works correctly in almost every situation. However, in presence of many language-specific
         // conversions with a radically dynamic language, most overloaded methods will end up being constantly selected
-        // at invocation time, so a programmer knowledgable of the situation might choose to pin down an exact overload
+        // at invocation time, so a programmer knowledgeable of the situation might choose to pin down an exact overload
         // for performance reasons.
 
         // Is the method name lexically of the form "name(types)"?
@@ -377,8 +460,8 @@
                 final MethodType setterType = type.dropParameterTypes(1, 2);
                 // Bind property setter handle to the expected setter type and linker services. Type is
                 // MethodHandle(Object, String, Object)
-                final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, setterType,
-                        linkerServices);
+                final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0,
+                        CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices);
 
                 // Cast getter to MethodHandle(O, N, V)
                 final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
@@ -415,9 +498,8 @@
             case 3: {
                 // Must have two arguments: target object and property value
                 assertParameterCount(callSiteDescriptor, 2);
-                final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(),
-                        linkerServices, callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND),
-                        propertySetters);
+                final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
+                        callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
                 // If we have a property setter with this name, this composite operation will always stop here
                 if(gi != null) {
                     return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
@@ -435,14 +517,13 @@
 
     private static final Lookup privateLookup = new Lookup(MethodHandles.lookup());
 
-    private static final MethodHandle IS_ANNOTATED_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType(
-            boolean.class, AnnotatedMethodHandle.class));
-    private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_HANDLE = MethodHandles.dropArguments(
-            MethodHandles.constant(Object.class, null), 0, AnnotatedMethodHandle.class);
-    private static final MethodHandle GET_ANNOTATED_HANDLE = privateLookup.findGetter(AnnotatedMethodHandle.class,
-            "handle", MethodHandle.class);
-    private static final MethodHandle GENERIC_PROPERTY_GETTER_HANDLER_INVOKER = MethodHandles.filterArguments(
-            MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)), 0, GET_ANNOTATED_HANDLE);
+    private static final MethodHandle IS_ANNOTATED_METHOD_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType(
+            boolean.class, AnnotatedDynamicMethod.class));
+    private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_METHOD = MethodHandles.dropArguments(
+            MethodHandles.constant(Object.class, null), 0, AnnotatedDynamicMethod.class);
+    private static final MethodHandle GET_ANNOTATED_METHOD = privateLookup.findVirtual(AnnotatedDynamicMethod.class,
+            "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class));
+    private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class));
 
     private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor,
             LinkerServices linkerServices, List<String> ops) throws Exception {
@@ -455,16 +536,20 @@
                 // What's below is basically:
                 //   foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle)
                 // only with a bunch of method signature adjustments. Basically, retrieve method getter
-                // AnnotatedMethodHandle; if it is non-null, invoke its "handle" field, otherwise either return null,
+                // AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null,
                 // or delegate to next component's invocation.
 
                 final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
-                        AnnotatedMethodHandle.class));
-                // Object(AnnotatedMethodHandle, Object)->R(AnnotatedMethodHandle, T0)
-                final MethodHandle invokeHandleTyped = linkerServices.asType(GENERIC_PROPERTY_GETTER_HANDLER_INVOKER,
-                        MethodType.methodType(type.returnType(), AnnotatedMethodHandle.class, type.parameterType(0)));
+                        AnnotatedDynamicMethod.class));
+                final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
+                        GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup());
+                final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
+                        callSiteBoundMethodGetter);
+                // Object(AnnotatedDynamicMethod, Object)->R(AnnotatedDynamicMethod, T0)
+                final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker,
+                        MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0)));
                 // Since it's in the target of a fold, drop the unnecessary second argument
-                // R(AnnotatedMethodHandle, T0)->R(AnnotatedMethodHandle, T0, T1)
+                // R(AnnotatedDynamicMethod, T0)->R(AnnotatedDynamicMethod, T0, T1)
                 final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
                         type.parameterType(1));
                 final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
@@ -472,19 +557,19 @@
 
                 final MethodHandle fallbackFolded;
                 if(nextComponent == null) {
-                    // Object(AnnotatedMethodHandle)->R(AnnotatedMethodHandle, T0, T1); returns constant null
-                    fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_HANDLE, 1,
-                            type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedMethodHandle.class));
+                    // Object(AnnotatedDynamicMethod)->R(AnnotatedDynamicMethod, T0, T1); returns constant null
+                    fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1,
+                            type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class));
                 } else {
-                    // R(T0, T1)->R(AnnotatedMethodHAndle, T0, T1); adapts the next component's invocation to drop the
+                    // R(T0, T1)->R(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to drop the
                     // extra argument resulting from fold
                     fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
-                            0, AnnotatedMethodHandle.class);
+                            0, AnnotatedDynamicMethod.class);
                 }
 
-                // fold(R(AnnotatedMethodHandle, T0, T1), AnnotatedMethodHandle(T0, T1))
+                // fold(R(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
                 final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
-                            IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
+                            IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
                 if(nextComponent == null) {
                     return getClassGuardedInvocationComponent(compositeGetter, type);
                 }
@@ -494,13 +579,13 @@
                 // Must have exactly one argument: receiver
                 assertParameterCount(callSiteDescriptor, 1);
                 // Fixed name
-                final AnnotatedMethodHandle annGetter = propertyGetters.get(callSiteDescriptor.getNameToken(
+                final AnnotatedDynamicMethod annGetter = propertyGetters.get(callSiteDescriptor.getNameToken(
                         CallSiteDescriptor.NAME_OPERAND));
                 if(annGetter == null) {
                     // We have no such property, always delegate to the next component operation
                     return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops);
                 }
-                final MethodHandle getter = annGetter.handle;
+                final MethodHandle getter = annGetter.getInvocation(callSiteDescriptor, linkerServices);
                 // NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being
                 // overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the
                 // method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If
@@ -508,6 +593,7 @@
                 // NOTE: No delegation to the next component operation if we have a property with this name, even if its
                 // value is null.
                 final ValidationType validationType = annGetter.validationType;
+                // TODO: we aren't using the type that declares the most generic getter here!
                 return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType,
                         type), clazz, validationType);
             }
@@ -623,14 +709,15 @@
     // args are dropped; this makes handles with first three args conform to "Object, String, Object" though, which is
     // a typical property setter with variable name signature (target, name, value).
     private static final MethodHandle GET_PROPERTY_SETTER_HANDLE = MethodHandles.dropArguments(MethodHandles.dropArguments(
-            privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, MethodType.class,
+            privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, CallSiteDescriptor.class,
                     LinkerServices.class, Object.class), 3, Object.class), 5, Object.class);
     // Type is MethodHandle(MethodType, LinkerServices, Object, String, Object)
     private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this);
 
     @SuppressWarnings("unused")
-    private MethodHandle getPropertySetterHandle(MethodType setterType, LinkerServices linkerServices, Object id) {
-        return getDynamicMethodInvocation(setterType, linkerServices, String.valueOf(id), propertySetters);
+    private MethodHandle getPropertySetterHandle(CallSiteDescriptor setterDescriptor, LinkerServices linkerServices,
+            Object id) {
+        return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
     }
 
     private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
@@ -689,13 +776,24 @@
         return null;
     }
 
-    private static final class AnnotatedMethodHandle {
-        final MethodHandle handle;
+    private static final class AnnotatedDynamicMethod {
+        private final SingleDynamicMethod method;
         /*private*/ final ValidationType validationType;
 
-        AnnotatedMethodHandle(MethodHandle handle, ValidationType validationType) {
-            this.handle = handle;
+        AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) {
+            this.method = method;
             this.validationType = validationType;
         }
+
+        MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
+            return method.getInvocation(callSiteDescriptor, linkerServices);
+        }
+
+        @SuppressWarnings("unused")
+        MethodHandle getTarget(MethodHandles.Lookup lookup) {
+            MethodHandle inv = method.getTarget(lookup);
+            assert inv != null;
+            return inv;
+        }
     }
 }
--- a/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java	Mon Jul 08 18:43:41 2013 +0530
@@ -83,7 +83,6 @@
 
 package jdk.internal.dynalink.beans;
 
-import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
 import java.util.LinkedList;
 import java.util.List;
@@ -95,7 +94,7 @@
  * @author Attila Szegedi
  */
 class ApplicableOverloadedMethods {
-    private final List<MethodHandle> methods;
+    private final List<SingleDynamicMethod> methods;
     private final boolean varArgs;
 
     /**
@@ -106,10 +105,10 @@
      * @param test applicability test. One of {@link #APPLICABLE_BY_SUBTYPING},
      * {@link #APPLICABLE_BY_METHOD_INVOCATION_CONVERSION}, or {@link #APPLICABLE_BY_VARIABLE_ARITY}.
      */
-    ApplicableOverloadedMethods(final List<MethodHandle> methods, final MethodType callSiteType,
+    ApplicableOverloadedMethods(final List<SingleDynamicMethod> methods, final MethodType callSiteType,
             final ApplicabilityTest test) {
         this.methods = new LinkedList<>();
-        for(MethodHandle m: methods) {
+        for(SingleDynamicMethod m: methods) {
             if(test.isApplicable(callSiteType, m)) {
                 this.methods.add(m);
             }
@@ -122,7 +121,7 @@
      *
      * @return list of all methods.
      */
-    List<MethodHandle> getMethods() {
+    List<SingleDynamicMethod> getMethods() {
         return methods;
     }
 
@@ -131,12 +130,12 @@
      *
      * @return a list of maximally specific methods.
      */
-    List<MethodHandle> findMaximallySpecificMethods() {
+    List<SingleDynamicMethod> findMaximallySpecificMethods() {
         return MaximallySpecific.getMaximallySpecificMethods(methods, varArgs);
     }
 
     abstract static class ApplicabilityTest {
-        abstract boolean isApplicable(MethodType callSiteType, MethodHandle method);
+        abstract boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method);
     }
 
     /**
@@ -144,8 +143,8 @@
      */
     static final ApplicabilityTest APPLICABLE_BY_SUBTYPING = new ApplicabilityTest() {
         @Override
-        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
-            final MethodType methodType = method.type();
+        boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
+            final MethodType methodType = method.getMethodType();
             final int methodArity = methodType.parameterCount();
             if(methodArity != callSiteType.parameterCount()) {
                 return false;
@@ -166,8 +165,8 @@
      */
     static final ApplicabilityTest APPLICABLE_BY_METHOD_INVOCATION_CONVERSION = new ApplicabilityTest() {
         @Override
-        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
-            final MethodType methodType = method.type();
+        boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
+            final MethodType methodType = method.getMethodType();
             final int methodArity = methodType.parameterCount();
             if(methodArity != callSiteType.parameterCount()) {
                 return false;
@@ -189,11 +188,11 @@
      */
     static final ApplicabilityTest APPLICABLE_BY_VARIABLE_ARITY = new ApplicabilityTest() {
         @Override
-        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
-            if(!method.isVarargsCollector()) {
+        boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
+            if(!method.isVarArgs()) {
                 return false;
             }
-            final MethodType methodType = method.type();
+            final MethodType methodType = method.getMethodType();
             final int methodArity = methodType.parameterCount();
             final int fixArity = methodArity - 1;
             final int callSiteArity = callSiteType.parameterCount();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer in the
+         documentation and/or other materials provided with the distribution.
+       * Neither the name of the copyright holder nor the names of
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+       IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+       PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import sun.reflect.CallerSensitive;
+
+/**
+ * Utility class that determines if a method or constructor is caller sensitive. It actually encapsulates two different
+ * strategies for determining caller sensitivity; a more robust one that works if Dynalink runs as code with access
+ * to {@code sun.reflect} package, and an unprivileged one that is used when Dynalink doesn't have access to that
+ * package. Note that even the unprivileged strategy is ordinarily robust, but it relies on the {@code toString} method
+ * of the annotation. If an attacker were to use a different annotation to spoof the string representation of the
+ * {@code CallerSensitive} annotation, they could designate their own methods as caller sensitive. This however does not
+ * escalate privileges, only causes Dynalink to never cache method handles for such methods, so all it would do would
+ * decrease the performance in linking such methods. In the opposite case when an attacker could trick Dynalink into not
+ * recognizing genuine {@code CallerSensitive} annotations, Dynalink would treat caller sensitive methods as ordinary
+ * methods, and would cache them bound to a zero-privilege delegate as the caller (just what Dynalink did before it
+ * could handle caller-sensitive methods). That would practically render caller-sensitive methods exposed through
+ * Dynalink unusable, but again, can not lead to any privilege escalations. Therefore, even the less robust unprivileged
+ * strategy is safe; the worst thing a successful attack against it can achieve is slight reduction in Dynalink-exposed
+ * functionality or performance.
+ */
+public class CallerSensitiveDetector {
+
+    private static final DetectionStrategy DETECTION_STRATEGY = getDetectionStrategy();
+
+    static boolean isCallerSensitive(AccessibleObject ao) {
+        return DETECTION_STRATEGY.isCallerSensitive(ao);
+    }
+
+    private static DetectionStrategy getDetectionStrategy() {
+        try {
+            return new PrivilegedDetectionStrategy();
+        } catch(Throwable t) {
+            return new UnprivilegedDetectionStrategy();
+        }
+    }
+
+    private abstract static class DetectionStrategy {
+        abstract boolean isCallerSensitive(AccessibleObject ao);
+    }
+
+    private static class PrivilegedDetectionStrategy extends DetectionStrategy {
+        private static final Class<? extends Annotation> CALLER_SENSITIVE_ANNOTATION_CLASS = CallerSensitive.class;
+
+        @Override
+        boolean isCallerSensitive(AccessibleObject ao) {
+            return ao.getAnnotation(CALLER_SENSITIVE_ANNOTATION_CLASS) != null;
+        }
+    }
+
+    private static class UnprivilegedDetectionStrategy extends DetectionStrategy {
+        private static final String CALLER_SENSITIVE_ANNOTATION_STRING = "@sun.reflect.CallerSensitive()";
+
+        @Override
+        boolean isCallerSensitive(AccessibleObject o) {
+            for(Annotation a: o.getAnnotations()) {
+                if(String.valueOf(a).equals(CALLER_SENSITIVE_ANNOTATION_STRING)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer in the
+         documentation and/or other materials provided with the distribution.
+       * Neither the name of the copyright holder nor the names of
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+       IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+       PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import jdk.internal.dynalink.support.Lookup;
+
+/**
+ * A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is
+ * caller sensitive, it doesn't cache a method handle but rather uses the passed lookup object in
+ * {@link #getTarget(java.lang.invoke.MethodHandles.Lookup)} to unreflect a method handle from the reflective member on
+ * every request.
+ *
+ * @author Attila Szegedi
+ */
+class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
+    // Typed as "AccessibleObject" as it can be either a method or a constructor.
+    // If we were Java8-only, we could use java.lang.reflect.Executable
+    private final AccessibleObject target;
+    private final MethodType type;
+
+    public CallerSensitiveDynamicMethod(AccessibleObject target) {
+        super(getName(target));
+        this.target = target;
+        this.type = getMethodType(target);
+    }
+
+    private static String getName(AccessibleObject target) {
+        final Member m = (Member)target;
+        return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(),
+                m.getName()));
+    }
+
+    @Override
+    MethodType getMethodType() {
+        return type;
+    }
+
+    private static MethodType getMethodType(AccessibleObject ao) {
+        final boolean isMethod = ao instanceof Method;
+        final Class<?> rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor<?>)ao).getDeclaringClass();
+        final Class<?>[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor<?>)ao).getParameterTypes();
+        final MethodType type = MethodType.methodType(rtype, ptypes);
+        final Member m = (Member)ao;
+        return type.insertParameterTypes(0,
+                isMethod ?
+                        Modifier.isStatic(m.getModifiers()) ?
+                                Object.class :
+                                m.getDeclaringClass() :
+                        StaticClass.class);
+    }
+
+    @Override
+    boolean isVarArgs() {
+        return target instanceof Method ? ((Method)target).isVarArgs() : ((Constructor<?>)target).isVarArgs();
+    }
+
+    @Override
+    MethodHandle getTarget(MethodHandles.Lookup lookup) {
+        if(target instanceof Method) {
+            final MethodHandle mh = Lookup.unreflect(lookup, (Method)target);
+            if(Modifier.isStatic(((Member)target).getModifiers())) {
+                return StaticClassIntrospector.editStaticMethodHandle(mh);
+            }
+            return mh;
+        }
+        return StaticClassIntrospector.editConstructorMethodHandle(Lookup.unreflectConstructor(lookup,
+                (Constructor<?>)target));
+    }
+}
--- a/src/jdk/internal/dynalink/beans/ClassString.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/ClassString.java	Mon Jul 08 18:43:41 2013 +0530
@@ -155,8 +155,8 @@
     }
 
     List<MethodHandle> getMaximallySpecifics(List<MethodHandle> methods, LinkerServices linkerServices, boolean varArg) {
-        return MaximallySpecific.getMaximallySpecificMethods(getApplicables(methods, linkerServices, varArg), varArg,
-                classes, linkerServices);
+        return MaximallySpecific.getMaximallySpecificMethodHandles(getApplicables(methods, linkerServices, varArg),
+                varArg, classes, linkerServices);
     }
 
     /**
--- a/src/jdk/internal/dynalink/beans/DynamicMethod.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/DynamicMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -84,8 +84,7 @@
 package jdk.internal.dynalink.beans;
 
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.util.StringTokenizer;
+import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.LinkerServices;
 
 /**
@@ -116,45 +115,28 @@
      * is a variable arguments (vararg) method, it will pack the extra arguments in an array before the invocation of
      * the underlying method if it is not already done.
      *
-     * @param callSiteType the method type at a call site
+     * @param callSiteDescriptor the descriptor of the call site
      * @param linkerServices linker services. Used for language-specific type conversions.
      * @return an invocation suitable for calling the method from the specified call site.
      */
-    abstract MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices);
+    abstract MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices);
 
     /**
-     * Returns a simple dynamic method representing a single underlying Java method (possibly selected among several
+     * Returns a single dynamic method representing a single underlying Java method (possibly selected among several
      * overloads) with formal parameter types exactly matching the passed signature.
      * @param paramTypes the comma-separated list of requested parameter type names. The names will match both
      * qualified and unqualified type names.
-     * @return a simple dynamic method representing a single underlying Java method, or null if none of the Java methods
+     * @return a single dynamic method representing a single underlying Java method, or null if none of the Java methods
      * behind this dynamic method exactly match the requested parameter types.
      */
-    abstract SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes);
+    abstract SingleDynamicMethod getMethodForExactParamTypes(String paramTypes);
 
     /**
-     * True if this dynamic method already contains a method handle with an identical signature as the passed in method
-     * handle.
-     * @param mh the method handle to check
-     * @return true if it already contains an equivalent method handle.
+     * True if this dynamic method already contains a method with an identical signature as the passed in method.
+     * @param method the method to check
+     * @return true if it already contains an equivalent method.
      */
-    abstract boolean contains(MethodHandle mh);
-
-    static boolean typeMatchesDescription(String paramTypes, MethodType type) {
-        final StringTokenizer tok = new StringTokenizer(paramTypes, ", ");
-        for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver
-            if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) {
-                return false;
-            }
-        }
-        return !tok.hasMoreTokens();
-    }
-
-    private static boolean typeNameMatches(String typeName, Class<?> type) {
-        final int lastDot = typeName.lastIndexOf('.');
-        final String fullTypeName = type.getCanonicalName();
-        return lastDot != -1 && fullTypeName.endsWith(typeName.substring(lastDot)) || typeName.equals(fullTypeName);
-    }
+    abstract boolean contains(SingleDynamicMethod method);
 
     static String getClassAndMethodName(Class<?> clazz, String name) {
         final String clazzName = clazz.getCanonicalName();
--- a/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java	Mon Jul 08 18:43:41 2013 +0530
@@ -85,12 +85,12 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
 import jdk.internal.dynalink.support.Guards;
 
 /**
@@ -110,19 +110,18 @@
             return null;
         }
         final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
-        if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn")  {
+        if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
             return null;
         }
         final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
         if(operator == "call") {
-            final MethodType type = desc.getMethodType();
-            final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation(type.dropParameterTypes(0, 1),
-                    linkerServices);
+            final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation(
+                    CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
             if(invocation == null) {
                 return null;
             }
-            return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0, type.parameterType(0)),
-                    Guards.getIdentityGuard(receiver));
+            return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
+                    desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
         }
         return null;
     }
--- a/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Mon Jul 08 18:43:41 2013 +0530
@@ -167,10 +167,6 @@
         return editMethodHandle(SafeUnreflector.unreflectSetter(field));
     }
 
-    MethodHandle unreflect(Method method) {
-        return editMethodHandle(SafeUnreflector.unreflect(method));
-    }
-
     /**
      * Returns an edited method handle. A facet might need to edit an unreflected method handle before it is usable with
      * the facet. By default, returns the passed method handle unchanged. The class' static facet will introduce a
--- a/src/jdk/internal/dynalink/beans/MaximallySpecific.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/MaximallySpecific.java	Mon Jul 08 18:43:41 2013 +0530
@@ -105,10 +105,58 @@
      * @param varArgs whether to assume the methods are varargs
      * @return the list of maximally specific methods.
      */
-    static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs) {
-        return getMaximallySpecificMethods(methods, varArgs, null, null);
+    static List<SingleDynamicMethod> getMaximallySpecificMethods(List<SingleDynamicMethod> methods, boolean varArgs) {
+        return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null);
     }
 
+    private abstract static class MethodTypeGetter<T> {
+        abstract MethodType getMethodType(T t);
+    }
+
+    private static final MethodTypeGetter<MethodHandle> METHOD_HANDLE_TYPE_GETTER =
+            new MethodTypeGetter<MethodHandle>() {
+        @Override
+        MethodType getMethodType(MethodHandle t) {
+            return t.type();
+        }
+    };
+
+    private static final MethodTypeGetter<SingleDynamicMethod> DYNAMIC_METHOD_TYPE_GETTER =
+            new MethodTypeGetter<SingleDynamicMethod>() {
+        @Override
+        MethodType getMethodType(SingleDynamicMethod t) {
+            return t.getMethodType();
+        }
+    };
+
+     /**
+      * Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime
+      * specific conversion preferences.
+      *
+      * @param methods the list of method handles
+      * @param varArgs whether to assume the method handles are varargs
+      * @param argTypes concrete argument types for the invocation
+      * @return the list of maximally specific method handles.
+      */
+     static List<MethodHandle> getMaximallySpecificMethodHandles(List<MethodHandle> methods, boolean varArgs,
+             Class<?>[] argTypes, LinkerServices ls) {
+         return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER);
+     }
+
+     /**
+      * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific
+      * conversion preferences.
+      *
+      * @param methods the list of methods
+      * @param varArgs whether to assume the methods are varargs
+      * @param argTypes concrete argument types for the invocation
+      * @return the list of maximally specific methods.
+      */
+     static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(List<SingleDynamicMethod> methods,
+             boolean varArgs, Class<?>[] argTypes, LinkerServices ls) {
+         return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER);
+     }
+
     /**
      * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific
      * conversion preferences.
@@ -118,18 +166,18 @@
      * @param argTypes concrete argument types for the invocation
      * @return the list of maximally specific methods.
      */
-    static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs,
-            Class<?>[] argTypes, LinkerServices ls) {
+    private static <T> List<T> getMaximallySpecificMethods(List<T> methods, boolean varArgs,
+            Class<?>[] argTypes, LinkerServices ls, MethodTypeGetter<T> methodTypeGetter) {
         if(methods.size() < 2) {
             return methods;
         }
-        final LinkedList<MethodHandle> maximals = new LinkedList<>();
-        for(MethodHandle m: methods) {
-            final MethodType methodType = m.type();
+        final LinkedList<T> maximals = new LinkedList<>();
+        for(T m: methods) {
+            final MethodType methodType = methodTypeGetter.getMethodType(m);
             boolean lessSpecific = false;
-            for(Iterator<MethodHandle> maximal = maximals.iterator(); maximal.hasNext();) {
-                final MethodHandle max = maximal.next();
-                switch(isMoreSpecific(methodType, max.type(), varArgs, argTypes, ls)) {
+            for(Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) {
+                final T max = maximal.next();
+                switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) {
                     case TYPE_1_BETTER: {
                         maximal.remove();
                         break;
--- a/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -84,16 +84,21 @@
 package jdk.internal.dynalink.beans;
 
 import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest;
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.support.TypeUtilities;
 
 /**
- * Represents an overloaded method.
+ * Represents a group of {@link SingleDynamicMethod} objects that represents all overloads of a particular name (or all
+ * constructors) for a particular class. Correctly handles overload resolution, variable arity methods, and caller
+ * sensitive methods within the overloads.
  *
  * @author Attila Szegedi
  */
@@ -101,7 +106,7 @@
     /**
      * Holds a list of all methods.
      */
-    private final LinkedList<MethodHandle> methods;
+    private final LinkedList<SingleDynamicMethod> methods;
     private final ClassLoader classLoader;
 
     /**
@@ -111,21 +116,22 @@
      * @param name the name of the method
      */
     OverloadedDynamicMethod(Class<?> clazz, String name) {
-        this(new LinkedList<MethodHandle>(), clazz.getClassLoader(), getClassAndMethodName(clazz, name));
+        this(new LinkedList<SingleDynamicMethod>(), clazz.getClassLoader(), getClassAndMethodName(clazz, name));
     }
 
-    private OverloadedDynamicMethod(LinkedList<MethodHandle> methods, ClassLoader classLoader, String name) {
+    private OverloadedDynamicMethod(LinkedList<SingleDynamicMethod> methods, ClassLoader classLoader, String name) {
         super(name);
         this.methods = methods;
         this.classLoader = classLoader;
     }
 
     @Override
-    SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
-        final LinkedList<MethodHandle> matchingMethods = new LinkedList<>();
-        for(MethodHandle method: methods) {
-            if(typeMatchesDescription(paramTypes, method.type())) {
-                matchingMethods.add(method);
+    SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
+        final LinkedList<SingleDynamicMethod> matchingMethods = new LinkedList<>();
+        for(SingleDynamicMethod method: methods) {
+            final SingleDynamicMethod matchingMethod = method.getMethodForExactParamTypes(paramTypes);
+            if(matchingMethod != null) {
+                matchingMethods.add(matchingMethod);
             }
         }
         switch(matchingMethods.size()) {
@@ -133,8 +139,7 @@
                 return null;
             }
             case 1: {
-                final MethodHandle target = matchingMethods.get(0);
-                return new SimpleDynamicMethod(target, SimpleDynamicMethod.getMethodNameWithSignature(target, getName()));
+                return matchingMethods.getFirst();
             }
             default: {
                 throw new BootstrapMethodError("Can't choose among " + matchingMethods + " for argument types "
@@ -144,7 +149,8 @@
     }
 
     @Override
-    public MethodHandle getInvocation(final MethodType callSiteType, final LinkerServices linkerServices) {
+    public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+        final MethodType callSiteType = callSiteDescriptor.getMethodType();
         // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2)
         final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType,
                 ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING);
@@ -156,7 +162,7 @@
                 ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY);
 
         // Find the methods that are maximally specific based on the call site signature
-        List<MethodHandle> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods();
+        List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods();
         if(maximallySpecifics.isEmpty()) {
             maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods();
             if(maximallySpecifics.isEmpty()) {
@@ -171,12 +177,12 @@
         // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability
         // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation.
         @SuppressWarnings({ "unchecked", "rawtypes" })
-        final List<MethodHandle> invokables = (List)methods.clone();
+        final List<SingleDynamicMethod> invokables = (List)methods.clone();
         invokables.removeAll(subtypingApplicables.getMethods());
         invokables.removeAll(methodInvocationApplicables.getMethods());
         invokables.removeAll(variableArityApplicables.getMethods());
-        for(final Iterator<MethodHandle> it = invokables.iterator(); it.hasNext();) {
-            final MethodHandle m = it.next();
+        for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) {
+            final SingleDynamicMethod m = it.next();
             if(!isApplicableDynamically(linkerServices, callSiteType, m)) {
                 it.remove();
             }
@@ -199,54 +205,45 @@
             }
             case 1: {
                 // Very lucky, we ended up with a single candidate method handle based on the call site signature; we
-                // can link it very simply by delegating to a SimpleDynamicMethod.
-                final MethodHandle mh = invokables.iterator().next();
-                return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices);
+                // can link it very simply by delegating to the SingleDynamicMethod.
+                invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices);
             }
             default: {
                 // We have more than one candidate. We have no choice but to link to a method that resolves overloads on
                 // every invocation (alternatively, we could opportunistically link the one method that resolves for the
                 // current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd
-                // go back all the way to candidate selection.
-                // TODO: cache per call site type
-                return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
+                // go back all the way to candidate selection. Note that we're resolving any potential caller sensitive
+                // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it
+                // has an already determined Lookup.
+                final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size());
+                final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup();
+                for(SingleDynamicMethod method: invokables) {
+                    methodHandles.add(method.getTarget(lookup));
+                }
+                return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker();
             }
         }
 
     }
 
     @Override
-    public boolean contains(MethodHandle mh) {
-        final MethodType type = mh.type();
-        for(MethodHandle method: methods) {
-            if(typesEqualNoReceiver(type, method.type())) {
+    public boolean contains(SingleDynamicMethod m) {
+        for(SingleDynamicMethod method: methods) {
+            if(method.contains(m)) {
                 return true;
             }
         }
         return false;
     }
 
-    private static boolean typesEqualNoReceiver(MethodType type1, MethodType type2) {
-        final int pc = type1.parameterCount();
-        if(pc != type2.parameterCount()) {
-            return false;
-        }
-        for(int i = 1; i < pc; ++i) { // i = 1: ignore receiver
-            if(type1.parameterType(i) != type2.parameterType(i)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     ClassLoader getClassLoader() {
         return classLoader;
     }
 
     private static boolean isApplicableDynamically(LinkerServices linkerServices, MethodType callSiteType,
-            MethodHandle m) {
-        final MethodType methodType = m.type();
-        final boolean varArgs = m.isVarargsCollector();
+            SingleDynamicMethod m) {
+        final MethodType methodType = m.getMethodType();
+        final boolean varArgs = m.isVarArgs();
         final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
         final int callSiteArgLen = callSiteType.parameterCount();
 
@@ -301,20 +298,11 @@
     }
 
     /**
-     * Add a method identified by a {@link SimpleDynamicMethod} to this overloaded method's set.
-     *
-     * @param method the method to add.
-     */
-    void addMethod(SimpleDynamicMethod method) {
-        addMethod(method.getTarget());
-    }
-
-    /**
      * Add a method to this overloaded method's set.
      *
      * @param method a method to add
      */
-    public void addMethod(MethodHandle method) {
+    public void addMethod(SingleDynamicMethod method) {
         methods.add(method);
     }
 }
--- a/src/jdk/internal/dynalink/beans/OverloadedMethod.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/OverloadedMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -135,7 +135,7 @@
         varArgMethods.trimToSize();
 
         final MethodHandle bound = SELECT_METHOD.bindTo(this);
-        final MethodHandle collecting = SimpleDynamicMethod.collectArguments(bound, argNum).asType(
+        final MethodHandle collecting = SingleDynamicMethod.collectArguments(bound, argNum).asType(
                 callSiteType.changeReturnType(MethodHandle.class));
         invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(callSiteType), collecting);
     }
@@ -167,7 +167,7 @@
                     break;
                 }
                 case 1: {
-                    method = new SimpleDynamicMethod(methods.get(0)).getInvocation(callSiteType, linkerServices);
+                    method = SingleDynamicMethod.getInvocation(methods.get(0), callSiteType, linkerServices);
                     break;
                 }
                 default: {
--- a/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -84,29 +84,22 @@
 package jdk.internal.dynalink.beans;
 
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
-import java.lang.reflect.Array;
-import jdk.internal.dynalink.linker.LinkerServices;
-import jdk.internal.dynalink.support.Guards;
 
 /**
- * A dynamic method bound to exactly one, non-overloaded Java method. Handles varargs.
+ * A dynamic method bound to exactly one Java method or constructor that is not caller sensitive. Since its target is
+ * not caller sensitive, this class pre-caches its method handle and always returns it from the call to
+ * {@link #getTarget(Lookup)}. Can be used in general to represents dynamic methods bound to a single method handle,
+ * even if that handle is not mapped to a Java method, i.e. as a wrapper around field getters/setters, array element
+ * getters/setters, etc.
  *
  * @author Attila Szegedi
  */
-class SimpleDynamicMethod extends DynamicMethod {
+class SimpleDynamicMethod extends SingleDynamicMethod {
     private final MethodHandle target;
 
     /**
-     * Creates a simple dynamic method with no name.
-     * @param target the target method handle
-     */
-    SimpleDynamicMethod(MethodHandle target) {
-        this(target, null);
-    }
-
-    /**
      * Creates a new simple dynamic method, with a name constructed from the class name, method name, and handle
      * signature.
      *
@@ -115,125 +108,26 @@
      * @param name the simple name of the method
      */
     SimpleDynamicMethod(MethodHandle target, Class<?> clazz, String name) {
-        this(target, getName(target, clazz, name));
-    }
-
-    SimpleDynamicMethod(MethodHandle target, String name) {
-        super(name);
+        super(getName(target, clazz, name));
         this.target = target;
     }
 
     private static String getName(MethodHandle target, Class<?> clazz, String name) {
-        return getMethodNameWithSignature(target, getClassAndMethodName(clazz, name));
-    }
-
-    static String getMethodNameWithSignature(MethodHandle target, String methodName) {
-        final String typeStr = target.type().toString();
-        final int retTypeIndex = typeStr.lastIndexOf(')') + 1;
-        int secondParamIndex = typeStr.indexOf(',') + 1;
-        if(secondParamIndex == 0) {
-            secondParamIndex = retTypeIndex - 1;
-        }
-        return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex);
-    }
-
-    /**
-     * Returns the target of this dynamic method
-     *
-     * @return the target of this dynamic method
-     */
-    MethodHandle getTarget() {
-        return target;
+        return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name));
     }
 
     @Override
-    SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
-        return typeMatchesDescription(paramTypes, target.type()) ? this : null;
+    boolean isVarArgs() {
+        return target.isVarargsCollector();
     }
 
     @Override
-    MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices) {
-        final MethodType methodType = target.type();
-        final int paramsLen = methodType.parameterCount();
-        final boolean varArgs = target.isVarargsCollector();
-        final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target;
-        final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen;
-        final int argsLen = callSiteType.parameterCount();
-        if(argsLen < fixParamsLen) {
-            // Less actual arguments than number of fixed declared arguments; can't invoke.
-            return null;
-        }
-        // Method handle has the same number of fixed arguments as the call site type
-        if(argsLen == fixParamsLen) {
-            // Method handle that matches the number of actual arguments as the number of fixed arguments
-            final MethodHandle matchedMethod;
-            if(varArgs) {
-                // If vararg, add a zero-length array of the expected type as the last argument to signify no variable
-                // arguments.
-                matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance(
-                        methodType.parameterType(fixParamsLen).getComponentType(), 0));
-            } else {
-                // Otherwise, just use the method
-                matchedMethod = fixTarget;
-            }
-            return createConvertingInvocation(matchedMethod, linkerServices, callSiteType);
-        }
-
-        // What's below only works for varargs
-        if(!varArgs) {
-            return null;
-        }
-
-        final Class<?> varArgType = methodType.parameterType(fixParamsLen);
-        // Handle a somewhat sinister corner case: caller passes exactly one argument in the vararg position, and we
-        // must handle both a prepacked vararg array as well as a genuine 1-long vararg sequence.
-        if(argsLen == paramsLen) {
-            final Class<?> callSiteLastArgType = callSiteType.parameterType(fixParamsLen);
-            if(varArgType.isAssignableFrom(callSiteLastArgType)) {
-                // Call site signature guarantees we'll always be passed a single compatible array; just link directly
-                // to the method.
-                return createConvertingInvocation(fixTarget, linkerServices, callSiteType);
-            }
-            if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
-                // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
-                // link immediately to a vararg-packing method handle.
-                return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
-            }
-            // Call site signature makes no guarantees that the single argument in the vararg position will be
-            // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg
-            // method when it is not.
-            return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
-                    createConvertingInvocation(fixTarget, linkerServices, callSiteType),
-                    createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
-        }
-
-        // Remaining case: more than one vararg.
-        return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
+    MethodType getMethodType() {
+        return target.type();
     }
 
     @Override
-    public boolean contains(MethodHandle mh) {
-        return target.type().parameterList().equals(mh.type().parameterList());
-    }
-
-    /**
-     * Creates a method handle out of the original target that will collect the varargs for the exact component type of
-     * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs
-     * for which it is necessary when later passed to linkerServices.convertArguments().
-     *
-     * @param target the original method handle
-     * @param parameterCount the total number of arguments in the new method handle
-     * @return a collecting method handle
-     */
-    static MethodHandle collectArguments(MethodHandle target, final int parameterCount) {
-        final MethodType methodType = target.type();
-        final int fixParamsLen = methodType.parameterCount() - 1;
-        final Class<?> arrayType = methodType.parameterType(fixParamsLen);
-        return target.asCollector(arrayType, parameterCount - fixParamsLen);
-    }
-
-    private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod,
-            final LinkerServices linkerServices, final MethodType callSiteType) {
-        return linkerServices.asType(sizedMethod, callSiteType);
+    MethodHandle getTarget(Lookup lookup) {
+        return target;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer in the
+         documentation and/or other materials provided with the distribution.
+       * Neither the name of the copyright holder nor the names of
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+       IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+       PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Array;
+import java.util.StringTokenizer;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * Base class for dynamic methods that dispatch to a single target Java method or constructor. Handles adaptation of the
+ * target method to a call site type (including mapping variable arity methods to a call site signature with different
+ * arity).
+ * @author Attila Szegedi
+ * @version $Id: $
+ */
+abstract class SingleDynamicMethod extends DynamicMethod {
+    SingleDynamicMethod(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns true if this method is variable arity.
+     * @return true if this method is variable arity.
+     */
+    abstract boolean isVarArgs();
+
+    /**
+     * Returns this method's native type.
+     * @return this method's native type.
+     */
+    abstract MethodType getMethodType();
+
+    /**
+     * Given a specified lookup, returns a method handle to this method's target.
+     * @param lookup the lookup to use.
+     * @return the handle to this method's target method.
+     */
+    abstract MethodHandle getTarget(MethodHandles.Lookup lookup);
+
+    @Override
+    MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
+        return getInvocation(getTarget(callSiteDescriptor.getLookup()), callSiteDescriptor.getMethodType(),
+                linkerServices);
+    }
+
+    @Override
+    SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
+        return typeMatchesDescription(paramTypes, getMethodType()) ? this : null;
+    }
+
+    @Override
+    boolean contains(SingleDynamicMethod method) {
+        return getMethodType().parameterList().equals(method.getMethodType().parameterList());
+    }
+
+    static String getMethodNameWithSignature(MethodType type, String methodName) {
+        final String typeStr = type.toString();
+        final int retTypeIndex = typeStr.lastIndexOf(')') + 1;
+        int secondParamIndex = typeStr.indexOf(',') + 1;
+        if(secondParamIndex == 0) {
+            secondParamIndex = retTypeIndex - 1;
+        }
+        return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex);
+    }
+
+    /**
+     * Given a method handle and a call site type, adapts the method handle to the call site type. Performs type
+     * conversions as needed using the specified linker services, and in case that the method handle is a vararg
+     * collector, matches it to the arity of the call site.
+     * @param target the method handle to adapt
+     * @param callSiteType the type of the call site
+     * @param linkerServices the linker services used for type conversions
+     * @return the adapted method handle.
+     */
+    static MethodHandle getInvocation(MethodHandle target, MethodType callSiteType, LinkerServices linkerServices) {
+        final MethodType methodType = target.type();
+        final int paramsLen = methodType.parameterCount();
+        final boolean varArgs = target.isVarargsCollector();
+        final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target;
+        final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen;
+        final int argsLen = callSiteType.parameterCount();
+        if(argsLen < fixParamsLen) {
+            // Less actual arguments than number of fixed declared arguments; can't invoke.
+            return null;
+        }
+        // Method handle has the same number of fixed arguments as the call site type
+        if(argsLen == fixParamsLen) {
+            // Method handle that matches the number of actual arguments as the number of fixed arguments
+            final MethodHandle matchedMethod;
+            if(varArgs) {
+                // If vararg, add a zero-length array of the expected type as the last argument to signify no variable
+                // arguments.
+                matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance(
+                        methodType.parameterType(fixParamsLen).getComponentType(), 0));
+            } else {
+                // Otherwise, just use the method
+                matchedMethod = fixTarget;
+            }
+            return createConvertingInvocation(matchedMethod, linkerServices, callSiteType);
+        }
+
+        // What's below only works for varargs
+        if(!varArgs) {
+            return null;
+        }
+
+        final Class<?> varArgType = methodType.parameterType(fixParamsLen);
+        // Handle a somewhat sinister corner case: caller passes exactly one argument in the vararg position, and we
+        // must handle both a prepacked vararg array as well as a genuine 1-long vararg sequence.
+        if(argsLen == paramsLen) {
+            final Class<?> callSiteLastArgType = callSiteType.parameterType(fixParamsLen);
+            if(varArgType.isAssignableFrom(callSiteLastArgType)) {
+                // Call site signature guarantees we'll always be passed a single compatible array; just link directly
+                // to the method, introducing necessary conversions. Also, preserve it being a variable arity method.
+                return createConvertingInvocation(target, linkerServices, callSiteType).asVarargsCollector(
+                        callSiteLastArgType);
+            }
+            if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
+                // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
+                // link immediately to a vararg-packing method handle.
+                return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
+            }
+            // Call site signature makes no guarantees that the single argument in the vararg position will be
+            // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg
+            // method when it is not.
+            return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
+                    createConvertingInvocation(fixTarget, linkerServices, callSiteType),
+                    createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
+        }
+
+        // Remaining case: more than one vararg.
+        return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
+    }
+
+    /**
+     * Creates a method handle out of the original target that will collect the varargs for the exact component type of
+     * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs
+     * for which it is necessary when later passed to linkerServices.convertArguments().
+     *
+     * @param target the original method handle
+     * @param parameterCount the total number of arguments in the new method handle
+     * @return a collecting method handle
+     */
+    static MethodHandle collectArguments(MethodHandle target, final int parameterCount) {
+        final MethodType methodType = target.type();
+        final int fixParamsLen = methodType.parameterCount() - 1;
+        final Class<?> arrayType = methodType.parameterType(fixParamsLen);
+        return target.asCollector(arrayType, parameterCount - fixParamsLen);
+    }
+
+    private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod,
+            final LinkerServices linkerServices, final MethodType callSiteType) {
+        return linkerServices.asType(sizedMethod, callSiteType);
+    }
+
+    private static boolean typeMatchesDescription(String paramTypes, MethodType type) {
+        final StringTokenizer tok = new StringTokenizer(paramTypes, ", ");
+        for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver
+            if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) {
+                return false;
+            }
+        }
+        return !tok.hasMoreTokens();
+    }
+
+    private static boolean typeNameMatches(String typeName, Class<?> type) {
+        return  typeName.equals(typeName.indexOf('.') == -1 ? type.getSimpleName() : type.getCanonicalName());
+    }
+}
--- a/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java	Mon Jul 08 18:43:41 2013 +0530
@@ -106,10 +106,18 @@
 
     @Override
     MethodHandle editMethodHandle(MethodHandle mh) {
+        return editStaticMethodHandle(mh);
+    }
+
+    static MethodHandle editStaticMethodHandle(MethodHandle mh) {
         return dropReceiver(mh, Object.class);
     }
 
-    static MethodHandle dropReceiver(final MethodHandle mh, final Class<?> receiverClass) {
+    static MethodHandle editConstructorMethodHandle(MethodHandle cmh) {
+        return dropReceiver(cmh, StaticClass.class);
+    }
+
+    private static MethodHandle dropReceiver(final MethodHandle mh, final Class<?> receiverClass) {
         MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, receiverClass);
         // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state.
         if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) {
--- a/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Mon Jul 08 18:43:41 2013 +0530
@@ -87,9 +87,7 @@
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
 import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -131,20 +129,11 @@
         private static DynamicMethod createConstructorMethod(Class<?> clazz) {
             if(clazz.isArray()) {
                 final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType());
-                return new SimpleDynamicMethod(drop(boundArrayCtor.asType(boundArrayCtor.type().changeReturnType(
-                        clazz))), clazz, "<init>");
+                return new SimpleDynamicMethod(StaticClassIntrospector.editConstructorMethodHandle(
+                        boundArrayCtor.asType(boundArrayCtor.type().changeReturnType(clazz))), clazz, "<init>");
             }
 
-            final Constructor<?>[] ctrs = clazz.getConstructors();
-            final List<MethodHandle> mhs = new ArrayList<>(ctrs.length);
-            for(int i = 0; i < ctrs.length; ++i) {
-                mhs.add(drop(SafeUnreflector.unreflectConstructor(ctrs[i])));
-            }
-            return createDynamicMethod(mhs, clazz, "<init>");
-        }
-
-        private static MethodHandle drop(MethodHandle mh) {
-            return StaticClassIntrospector.dropReceiver(mh, StaticClass.class);
+            return createDynamicMethod(Arrays.asList(clazz.getConstructors()), clazz, "<init>");
         }
 
         @Override
@@ -161,11 +150,10 @@
             }
             final CallSiteDescriptor desc = request.getCallSiteDescriptor();
             final String op = desc.getNameToken(CallSiteDescriptor.OPERATOR);
-            final MethodType methodType = desc.getMethodType();
             if("new" == op && constructor != null) {
-                final MethodHandle ctorInvocation = constructor.getInvocation(methodType, linkerServices);
+                final MethodHandle ctorInvocation = constructor.getInvocation(desc, linkerServices);
                 if(ctorInvocation != null) {
-                    return new GuardedInvocation(ctorInvocation, getClassGuard(methodType));
+                    return new GuardedInvocation(ctorInvocation, getClassGuard(desc.getMethodType()));
                 }
             }
             return null;
--- a/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java	Mon Jul 08 18:43:41 2013 +0530
@@ -139,8 +139,9 @@
 
     @Override
     public int hashCode() {
+        final MethodHandles.Lookup lookup = getLookup();
+        int h = lookup.lookupClass().hashCode() + 31 * lookup.lookupModes();
         final int c = getNameTokenCount();
-        int h = 0;
         for(int i = 0; i < c; ++i) {
             h = h * 31 + getNameToken(i).hashCode();
         }
--- a/src/jdk/internal/dynalink/support/Lookup.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/internal/dynalink/support/Lookup.java	Mon Jul 08 18:43:41 2013 +0530
@@ -122,6 +122,18 @@
      * @return the unreflected method handle.
      */
     public MethodHandle unreflect(Method m) {
+        return unreflect(lookup, m);
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered
+     * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param lookup the lookup used to unreflect
+     * @param m the method to unreflect
+     * @return the unreflected method handle.
+     */
+    public static MethodHandle unreflect(MethodHandles.Lookup lookup, Method m) {
         try {
             return lookup.unreflect(m);
         } catch(IllegalAccessException e) {
@@ -131,7 +143,6 @@
         }
     }
 
-
     /**
      * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered
      * {@link IllegalAccessException} into an {@link IllegalAccessError}.
@@ -202,6 +213,18 @@
      * @return the unreflected constructor handle.
      */
     public MethodHandle unreflectConstructor(Constructor<?> c) {
+        return unreflectConstructor(lookup, c);
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any
+     * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param lookup the lookup used to unreflect
+     * @param c the constructor to unreflect
+     * @return the unreflected constructor handle.
+     */
+    public static MethodHandle unreflectConstructor(MethodHandles.Lookup lookup, Constructor<?> c) {
         try {
             return lookup.unreflectConstructor(c);
         } catch(IllegalAccessException e) {
--- a/src/jdk/nashorn/api/scripting/NashornException.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/api/scripting/NashornException.java	Mon Jul 08 18:43:41 2013 +0530
@@ -146,7 +146,7 @@
      * @return array of javascript stack frames
      */
     public static StackTraceElement[] getScriptFrames(final Throwable exception) {
-        final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
+        final StackTraceElement[] frames = exception.getStackTrace();
         final List<StackTraceElement> filtered = new ArrayList<>();
         for (final StackTraceElement st : frames) {
             if (ECMAErrors.isScriptFrame(st)) {
@@ -170,7 +170,7 @@
      */
     public static String getScriptStackString(final Throwable exception) {
         final StringBuilder buf = new StringBuilder();
-        final StackTraceElement[] frames = getScriptFrames((Throwable)exception);
+        final StackTraceElement[] frames = getScriptFrames(exception);
         for (final StackTraceElement st : frames) {
             buf.append("\tat ");
             buf.append(st.getMethodName());
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/codegen/Attr.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/Attr.java	Mon Jul 08 18:43:41 2013 +0530
@@ -234,10 +234,25 @@
             @Override
             public boolean enterVarNode(final VarNode varNode) {
                 final String name = varNode.getName().getName();
-                //if this is used the var node symbol needs to be tagged as can be undefined
+                //if this is used before the var node, the var node symbol needs to be tagged as can be undefined
                 if (uses.contains(name)) {
                     canBeUndefined.add(name);
                 }
+
+                // all uses of the declared varnode inside the var node are potentially undefined
+                // however this is a bit conservative as e.g. var x = 17; var x = 1 + x; does work
+                if (!varNode.isFunctionDeclaration() && varNode.getInit() != null) {
+                    varNode.getInit().accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+                       @Override
+                       public boolean enterIdentNode(final IdentNode identNode) {
+                           if (name.equals(identNode.getName())) {
+                              canBeUndefined.add(name);
+                           }
+                           return false;
+                       }
+                    });
+                }
+
                 return true;
             }
 
@@ -257,6 +272,7 @@
                     }
                     return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
                 }
+
                 return varNode;
             }
         });
@@ -326,10 +342,11 @@
         catchNestingLevel++;
 
         // define block-local exception variable
-        final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET | IS_ALWAYS_DEFINED);
+        final String exname = exception.getName();
+        final Symbol def = defineSymbol(block, exname, IS_VAR | IS_LET | IS_ALWAYS_DEFINED);
         newType(def, Type.OBJECT); //we can catch anything, not just ecma exceptions
 
-        addLocalDef(exception.getName());
+        addLocalDef(exname);
 
         return true;
     }
@@ -661,7 +678,7 @@
 
             if (scopeBlock != null) {
                 assert lc.contains(scopeBlock);
-                lc.setFlag(scopeBlock, Block.NEEDS_SCOPE);
+                lc.setBlockNeedsScope(scopeBlock);
             }
         }
     }
@@ -732,6 +749,7 @@
     @Override
     public Node leaveReturnNode(final ReturnNode returnNode) {
         final Node expr = returnNode.getExpression();
+        final Type returnType;
 
         if (expr != null) {
             //we can't do parameter specialization if we return something that hasn't been typed yet
@@ -740,10 +758,12 @@
                 symbol.setType(Type.OBJECT);
             }
 
-            final Type returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType());
-            returnTypes.push(returnType);
-            LOG.info("Returntype is now ", returnType);
+            returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType());
+        } else {
+            returnType = Type.OBJECT; //undefined
         }
+        LOG.info("Returntype is now ", returnType);
+        returnTypes.push(returnType);
 
         end(returnNode);
 
@@ -774,6 +794,9 @@
                 }
 
                 type = Type.widest(type, newCaseNode.getTest().getType());
+                if (type.isBoolean()) {
+                    type = Type.OBJECT; //booleans and integers aren't assignment compatible
+                }
             }
 
             newCases.add(newCaseNode);
@@ -1009,10 +1032,7 @@
 
     @Override
     public Node leaveVOID(final UnaryNode unaryNode) {
-        final RuntimeNode runtimeNode = (RuntimeNode)new RuntimeNode(unaryNode, Request.VOID).accept(this);
-        assert runtimeNode.getSymbol().getSymbolType().isObject();
-        end(unaryNode);
-        return runtimeNode;
+        return end(ensureSymbol(Type.OBJECT, unaryNode));
     }
 
     /**
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Jul 08 18:43:41 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 */
@@ -179,6 +179,8 @@
 
     private static final DebugLogger LOG   = new DebugLogger("codegen", "nashorn.codegen.debug");
 
+    /** From what size should we use spill instead of fields for JavaScript objects? */
+    private static final int OBJECT_SPILL_THRESHOLD = 300;
 
     /**
      * Constructor.
@@ -578,6 +580,7 @@
         final Node         function        = callNode.getFunction();
         final Block        currentBlock    = lc.getCurrentBlock();
         final CodeGeneratorLexicalContext codegenLexicalContext = lc;
+        final Type         callNodeType    = callNode.getType();
 
         function.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
 
@@ -593,7 +596,7 @@
                 }
                 loadArgs(args);
                 final Type[] paramTypes = method.getTypesFromStack(args.size());
-                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
+                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNodeType, paramTypes, scopeCallFlags);
                 return scopeCall.generateInvoke(method);
             }
 
@@ -602,7 +605,7 @@
                 method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
                 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
                 method.loadNull(); //the 'this'
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
             }
 
             private void evalCall(final IdentNode node, final int flags) {
@@ -634,14 +637,14 @@
 
                 // direct call to Global.directEval
                 globalDirectEval();
-                method.convert(callNode.getType());
+                method.convert(callNodeType);
                 method._goto(eval_done);
 
                 method.label(not_eval);
                 // This is some scope 'eval' or global eval replaced by user
                 // but not the built-in ECMAScript 'eval' function call
                 method.loadNull();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
 
                 method.label(eval_done);
             }
@@ -666,7 +669,7 @@
                     } else {
                         sharedScopeCall(node, flags);
                     }
-                    assert method.peekType().equals(callNode.getType()) : method.peekType() + "!=" + callNode.getType();
+                    assert method.peekType().equals(callNodeType) : method.peekType() + "!=" + callNode.getType();
                 } else {
                     enterDefault(node);
                 }
@@ -681,8 +684,8 @@
                 method.dup();
                 method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true);
                 method.swap();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
-                assert method.peekType().equals(callNode.getType());
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
+                assert method.peekType().equals(callNodeType);
 
                 return false;
             }
@@ -707,6 +710,7 @@
                 assert callee.getCompileUnit() != null : "no compile unit for " + callee.getName() + " " + Debug.id(callee) + " " + callNode;
                 method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
                 assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
+                method.convert(callNodeType);
                 return false;
             }
 
@@ -722,7 +726,7 @@
                 }
                 method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
                 method.swap();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
                 assert method.peekType().equals(callNode.getType());
 
                 return false;
@@ -734,7 +738,7 @@
                 load(function);
                 method.convert(Type.OBJECT); //TODO, e.g. booleans can be used as functions
                 method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
                 assert method.peekType().equals(callNode.getType());
 
                 return false;
@@ -877,9 +881,15 @@
 
         final FunctionNode function = lc.getCurrentFunction();
         if (isFunctionBody) {
-            /* Fix the predefined slots so they have numbers >= 0, like varargs. */
-            if (function.needsParentScope()) {
-                initParentScope();
+            if(method.hasScope()) {
+                if (function.needsParentScope()) {
+                    method.loadCompilerConstant(CALLEE);
+                    method.invoke(ScriptFunction.GET_SCOPE);
+                } else {
+                    assert function.hasScopeBlock();
+                    method.loadNull();
+                }
+                method.storeCompilerConstant(SCOPE);
             }
             if (function.needsArguments()) {
                 initArguments(function);
@@ -940,22 +950,12 @@
              * Create a new object based on the symbols and values, generate
              * bootstrap code for object
              */
-            final FieldObjectCreator<Symbol> foc = new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) {
+            new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) {
                 @Override
                 protected void loadValue(final Symbol value) {
                     method.load(value);
                 }
-
-                @Override
-                protected void loadScope(MethodEmitter m) {
-                    if (function.needsParentScope()) {
-                        m.loadCompilerConstant(SCOPE);
-                    } else {
-                        m.loadNull();
-                    }
-                }
-            };
-            foc.makeObject(method);
+            }.makeObject(method);
 
             // runScript(): merge scope into global
             if (isFunctionBody && function.isProgram()) {
@@ -995,12 +995,6 @@
         method.storeCompilerConstant(ARGUMENTS);
     }
 
-    private void initParentScope() {
-        method.loadCompilerConstant(CALLEE);
-        method.invoke(ScriptFunction.GET_SCOPE);
-        method.storeCompilerConstant(SCOPE);
-    }
-
     @Override
     public boolean enterFunctionNode(final FunctionNode functionNode) {
         if (functionNode.isLazy()) {
@@ -1318,7 +1312,6 @@
         return method;
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
     public boolean enterLiteralNode(final LiteralNode literalNode) {
         assert literalNode.getSymbol() != null : literalNode + " has no symbol";
@@ -1350,73 +1343,71 @@
             values.add(value);
         }
 
-        new FieldObjectCreator<Node>(this, keys, symbols, values) {
-            @Override
-            protected void loadValue(final Node node) {
-                load(node);
-            }
-
-            /**
-             * Ensure that the properties start out as object types so that
-             * we can do putfield initializations instead of dynamicSetIndex
-             * which would be the case to determine initial property type
-             * otherwise.
-             *
-             * Use case, it's very expensive to do a million var x = {a:obj, b:obj}
-             * just to have to invalidate them immediately on initialization
-             *
-             * see NASHORN-594
-             */
-            @Override
-            protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
-                return new MapCreator(fieldObjectClass, keys, symbols) {
-                    @Override
-                    protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) {
-                        return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT;
-                    }
-                };
-            }
-
-        }.makeObject(method);
+        if (elements.size() > OBJECT_SPILL_THRESHOLD) {
+            new SpillObjectCreator(this, keys, symbols, values).makeObject(method);
+        } else {
+            new FieldObjectCreator<Node>(this, keys, symbols, values) {
+                @Override
+                protected void loadValue(final Node node) {
+                    load(node);
+                }
+
+                /**
+                 * Ensure that the properties start out as object types so that
+                 * we can do putfield initializations instead of dynamicSetIndex
+                 * which would be the case to determine initial property type
+                 * otherwise.
+                 *
+                 * Use case, it's very expensive to do a million var x = {a:obj, b:obj}
+                 * just to have to invalidate them immediately on initialization
+                 *
+                 * see NASHORN-594
+                 */
+                @Override
+                protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
+                    return new MapCreator(fieldObjectClass, keys, symbols) {
+                        @Override
+                        protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
+                            return super.getPropertyFlags(symbol, hasArguments) | Property.IS_ALWAYS_OBJECT;
+                        }
+                    };
+                }
+
+            }.makeObject(method);
+        }
 
         method.dup();
         globalObjectPrototype();
         method.invoke(ScriptObject.SET_PROTO);
 
-        if (!hasGettersSetters) {
-            method.store(objectNode.getSymbol());
-            return false;
+        if (hasGettersSetters) {
+            for (final PropertyNode propertyNode : elements) {
+                final FunctionNode getter       = propertyNode.getGetter();
+                final FunctionNode setter       = propertyNode.getSetter();
+
+                if (getter == null && setter == null) {
+                    continue;
+                }
+
+                method.dup().loadKey(propertyNode.getKey());
+
+                if (getter == null) {
+                    method.loadNull();
+                } else {
+                    getter.accept(this);
+                }
+
+                if (setter == null) {
+                    method.loadNull();
+                } else {
+                    setter.accept(this);
+                }
+
+                method.invoke(ScriptObject.SET_USER_ACCESSORS);
+            }
         }
 
-        for (final Node element : elements) {
-            final PropertyNode propertyNode = (PropertyNode)element;
-            final Object       key          = propertyNode.getKey();
-            final FunctionNode getter       = propertyNode.getGetter();
-            final FunctionNode setter       = propertyNode.getSetter();
-
-            if (getter == null && setter == null) {
-                continue;
-            }
-
-            method.dup().loadKey(key);
-
-            if (getter == null) {
-                method.loadNull();
-            } else {
-                getter.accept(this);
-            }
-
-            if (setter == null) {
-                method.loadNull();
-            } else {
-                setter.accept(this);
-            }
-
-            method.invoke(ScriptObject.SET_USER_ACCESSORS);
-        }
-
         method.store(objectNode.getSymbol());
-
         return false;
     }
 
@@ -1847,7 +1838,7 @@
             // If expression not int see if we can convert, if not use deflt to trigger default.
             if (!type.isInteger()) {
                 method.load(deflt);
-                final Class exprClass = type.getTypeClass();
+                final Class<?> exprClass = type.getTypeClass();
                 method.invoke(staticCallNoLookup(ScriptRuntime.class, "switchTagAsInt", int.class, exprClass.isPrimitive()? exprClass : Object.class, int.class));
             }
 
@@ -2335,6 +2326,14 @@
         return false;
     }
 
+    @Override
+    public boolean enterVOID(final UnaryNode unaryNode) {
+        load(unaryNode.rhs()).pop();
+        method.loadUndefined(Type.OBJECT);
+
+        return false;
+    }
+
     private Node enterNumericAdd(final Node lhs, final Node rhs, final Type type, final Symbol symbol) {
         assert lhs.getType().equals(rhs.getType()) && lhs.getType().equals(type) : lhs.getType() + " != " + rhs.getType() + " != " + type + " " + new ASTWriter(lhs) + " " + new ASTWriter(rhs);
         load(lhs);
@@ -3173,31 +3172,24 @@
             return;
         }
 
-        final boolean isLazy  = functionNode.isLazy();
-
-        new ObjectCreator(this, new ArrayList<String>(), new ArrayList<Symbol>(), false, false) {
-            @Override
-            protected void makeObject(final MethodEmitter m) {
-                final String className = SCRIPTFUNCTION_IMPL_OBJECT;
-
-                m._new(className).dup();
-                loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), Compiler.binaryName(getClassName()), makeMap()));
-
-                if (isLazy || functionNode.needsParentScope()) {
-                    m.loadCompilerConstant(SCOPE);
-                } else {
-                    m.loadNull();
-                }
-                m.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class));
-            }
-        }.makeObject(method);
+        // Generate the object class and property map in case this function is ever used as constructor
+        final String      className          = SCRIPTFUNCTION_IMPL_OBJECT;
+        final int         fieldCount         = ObjectClassGenerator.getPaddedFieldCount(functionNode.countThisProperties());
+        final String      allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount));
+        final PropertyMap allocatorMap       = PropertyMap.newMap(null, 0, fieldCount, 0);
+
+        method._new(className).dup();
+        loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), allocatorClassName, allocatorMap));
+
+        if (functionNode.isLazy() || functionNode.needsParentScope()) {
+            method.loadCompilerConstant(SCOPE);
+        } else {
+            method.loadNull();
+        }
+        method.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class));
     }
 
-    /*
-     * 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/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Mon Jul 08 18:43:41 2013 +0530
@@ -18,17 +18,15 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
 import jdk.nashorn.internal.codegen.types.Range;
 import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.ir.Block;
 import jdk.nashorn.internal.ir.CallNode;
 import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.ir.LexicalContext;
+import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.ReturnNode;
 import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
-import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.TemporarySymbols;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
@@ -117,7 +115,7 @@
                         final FunctionNode parent = lc.getParentFunction(functionNode);
                         assert parent != null;
                         lc.setFlag(parent, FunctionNode.HAS_LAZY_CHILDREN);
-                        lc.setFlag(parent.getBody(), Block.NEEDS_SCOPE);
+                        lc.setBlockNeedsScope(parent.getBody());
                         lc.setFlag(functionNode, FunctionNode.IS_LAZY);
                         return functionNode;
                     }
--- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -26,15 +26,16 @@
 package jdk.nashorn.internal.codegen;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
-import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
 import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
 import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
 import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
 
 import java.util.Iterator;
 import java.util.List;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
@@ -48,6 +49,13 @@
  * @see jdk.nashorn.internal.ir.Node
  */
 public abstract class FieldObjectCreator<T> extends ObjectCreator {
+
+    private         String        fieldObjectClassName;
+    private         Class<?>      fieldObjectClass;
+    private         int           fieldCount;
+    private         int           paddedFieldCount;
+    private         int           paramCount;
+
     /** array of corresponding values to symbols (null for no values) */
     private final List<T> values;
 
@@ -80,14 +88,9 @@
         super(codegen, keys, symbols, isScope, hasArguments);
         this.values        = values;
         this.callSiteFlags = codegen.getCallSiteFlags();
-    }
 
-    /**
-     * Loads the scope on the stack through the passed method emitter.
-     * @param method the method emitter to use
-     */
-    protected void loadScope(final MethodEmitter method) {
-        method.loadCompilerConstant(SCOPE);
+        countFields();
+        findClass();
     }
 
     /**
@@ -137,6 +140,13 @@
         }
     }
 
+    @Override
+    protected PropertyMap makeMap() {
+        assert propertyMap == null : "property map already initialized";
+        propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), fieldCount, paddedFieldCount);
+        return propertyMap;
+    }
+
     /**
      * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
      *
@@ -173,4 +183,47 @@
         loadValue(value);
         method.dynamicSetIndex(callSiteFlags);
     }
+
+    /**
+     * Locate (or indirectly create) the object container class.
+     */
+    private void findClass() {
+        fieldObjectClassName = isScope() ?
+                ObjectClassGenerator.getClassName(fieldCount, paramCount) :
+                ObjectClassGenerator.getClassName(paddedFieldCount);
+
+        try {
+            this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
+        } catch (final ClassNotFoundException e) {
+            throw new AssertionError("Nashorn has encountered an internal error.  Structure can not be created.");
+        }
+    }
+
+    /**
+     * Get the class name for the object class,
+     * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
+     *
+     * @return script class name
+     */
+    String getClassName() {
+        return fieldObjectClassName;
+    }
+
+    /**
+     * Tally the number of fields and parameters.
+     */
+    private void countFields() {
+        for (final Symbol symbol : this.symbols) {
+            if (symbol != null) {
+                if (hasArguments() && symbol.isParam()) {
+                    symbol.setFieldIndex(paramCount++);
+                } else {
+                    symbol.setFieldIndex(fieldCount++);
+                }
+            }
+        }
+
+        paddedFieldCount = getPaddedFieldCount(fieldCount);
+    }
+
 }
--- a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Mon Jul 08 18:43:41 2013 +0530
@@ -31,7 +31,6 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.AccessNode;
 import jdk.nashorn.internal.ir.Assignment;
@@ -175,6 +174,14 @@
         if (destType == null) {
             destType = specBinaryNode.getType();
         }
+        // Register assignments to this object in case this is used as constructor
+        if (binaryNode.lhs() instanceof AccessNode) {
+            AccessNode accessNode = (AccessNode) binaryNode.lhs();
+
+            if (accessNode.getBase().getSymbol().isThis()) {
+                lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName());
+            }
+        }
         return specBinaryNode.setRHS(convert(specBinaryNode.rhs(), destType));
     }
 
@@ -407,10 +414,10 @@
         if (!functionNode.needsCallee()) {
             functionNode.compilerConstant(CALLEE).setNeedsSlot(false);
         }
-        // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope or its
-        // own scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope earlier than
-        // this phase.
-        if (!(functionNode.getBody().needsScope() || functionNode.needsParentScope())) {
+        // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope and none of
+        // its blocks create a scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope
+        // earlier than this phase.
+        if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) {
             functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
         }
 
--- a/src/jdk/nashorn/internal/codegen/Lower.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/Lower.java	Mon Jul 08 18:43:41 2013 +0530
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.ListIterator;
 import jdk.nashorn.internal.ir.BaseNode;
 import jdk.nashorn.internal.ir.BinaryNode;
 import jdk.nashorn.internal.ir.Block;
@@ -115,6 +116,21 @@
                 }
                 return newStatements;
             }
+
+            @Override
+            protected Block afterSetStatements(final Block block) {
+                final List<Statement> stmts = block.getStatements();
+                for(final ListIterator<Statement> li = stmts.listIterator(stmts.size()); li.hasPrevious();) {
+                    final Statement stmt = li.previous();
+                    // popStatements() guarantees that the only thing after a terminal statement are uninitialized
+                    // VarNodes. We skip past those, and set the terminal state of the block to the value of the
+                    // terminal state of the first statement that is not an uninitialized VarNode.
+                    if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) {
+                        return block.setIsTerminal(this, stmt.isTerminal());
+                    }
+                }
+                return block.setIsTerminal(this, false);
+            }
         });
     }
 
@@ -132,11 +148,11 @@
         //now we have committed the entire statement list to the block, but we need to truncate
         //whatever is after the last terminal. block append won't append past it
 
-        Statement last = lc.getLastStatement();
 
         if (lc.isFunctionBody()) {
             final FunctionNode currentFunction = lc.getCurrentFunction();
             final boolean isProgram = currentFunction.isProgram();
+            final Statement last = lc.getLastStatement();
             final ReturnNode returnNode = new ReturnNode(
                 last == null ? block.getLineNumber() : last.getLineNumber(), //TODO?
                 currentFunction.getToken(),
@@ -145,11 +161,7 @@
                     compilerConstant(RETURN) :
                     LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED));
 
-            last = (Statement)returnNode.accept(this);
-        }
-
-        if (last != null && last.isTerminal()) {
-            return block.setIsTerminal(lc, true);
+            returnNode.accept(this);
         }
 
         return block;
--- a/src/jdk/nashorn/internal/codegen/MapCreator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/MapCreator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -41,10 +41,10 @@
     private final Class<?> structure;
 
     /** key set for object map */
-    private final String[] keys;
+    final List<String> keys;
 
     /** corresponding symbol set for object map */
-    private final Symbol[] symbols;
+    final List<Symbol> symbols;
 
     /**
      * Constructor
@@ -54,11 +54,9 @@
      * @param symbols   list of symbols for map
      */
     MapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
-        final int size   = keys.size();
-
         this.structure = structure;
-        this.keys      = keys.toArray(new String[size]);
-        this.symbols   = symbols.toArray(new Symbol[size]);
+        this.keys      = keys;
+        this.symbols   = symbols;
     }
 
     /**
@@ -70,21 +68,37 @@
      *
      * @return New map populated with accessor properties.
      */
-    PropertyMap makeMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) {
+    PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) {
         final List<Property> properties = new ArrayList<>();
-
         assert keys != null;
 
-        for (int i = 0; i < keys.length; i++) {
-            final String key    = keys[i];
-            final Symbol symbol = symbols[i];
+        for (int i = 0, length = keys.size(); i < length; i++) {
+            final String key    = keys.get(i);
+            final Symbol symbol = symbols.get(i);
 
             if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) {
                 properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
             }
         }
 
-        return PropertyMap.newMap(structure, properties, fieldCount, fieldMaximum);
+        return PropertyMap.newMap(properties, fieldCount, fieldMaximum, 0);
+    }
+
+    PropertyMap makeSpillMap(final boolean hasArguments) {
+        final List<Property> properties = new ArrayList<>();
+        int spillIndex = 0;
+        assert keys != null;
+
+        for (int i = 0, length = keys.size(); i < length; i++) {
+            final String key    = keys.get(i);
+            final Symbol symbol = symbols.get(i);
+
+            if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) {
+                properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), spillIndex++));
+            }
+        }
+
+        return PropertyMap.newMap(properties, 0, 0, spillIndex);
     }
 
     /**
--- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -74,11 +74,6 @@
     static final int FIELD_PADDING  = 4;
 
     /**
-     * Rounding when calculating the number of fields.
-     */
-    static final int FIELD_ROUNDING = 4;
-
-    /**
      * Debug field logger
      * Should we print debugging information for fields when they are generated and getters/setters are called?
      */
@@ -325,7 +320,6 @@
         final List<String> initFields   = addFields(classEmitter, fieldCount);
 
         final MethodEmitter init = newInitMethod(classEmitter);
-        initializeToUndefined(init, className, initFields);
         init.returnVoid();
         init.end();
 
@@ -709,6 +703,15 @@
         }
     }
 
+    /**
+     * Add padding to field count to avoid creating too many classes and have some spare fields
+     * @param count the field count
+     * @return the padded field count
+     */
+    static int getPaddedFieldCount(final int count) {
+        return count / FIELD_PADDING * FIELD_PADDING + FIELD_PADDING;
+    }
+
     //
     // Provide generic getters and setters for undefined types. If a type is undefined, all
     // and marshals the set to the correct setter depending on the type of the value being set.
--- a/src/jdk/nashorn/internal/codegen/ObjectCreator.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/codegen/ObjectCreator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -25,10 +25,10 @@
 
 package jdk.nashorn.internal.codegen;
 
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+
 import java.util.List;
-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.FIELD_PADDING;
 import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.PropertyMap;
 
 /**
@@ -36,9 +36,6 @@
  */
 public abstract class ObjectCreator {
 
-    /** Compile unit for this ObjectCreator, see CompileUnit */
-    //protected final CompileUnit   compileUnit;
-
     /** List of keys to initiate in this ObjectCreator */
     protected final List<String>  keys;
 
@@ -50,12 +47,7 @@
 
     private   final boolean       isScope;
     private   final boolean       hasArguments;
-    private         int           fieldCount;
-    private         int           paddedFieldCount;
-    private         int           paramCount;
-    private         String        fieldObjectClassName;
-    private         Class<?>      fieldObjectClass;
-    private         PropertyMap   propertyMap;
+    protected       PropertyMap   propertyMap;
 
     /**
      * Constructor
@@ -72,41 +64,6 @@
         this.symbols       = symbols;
         this.isScope       = isScope;
         this.hasArguments  = hasArguments;
-
-        countFields();
-        findClass();
-    }
-
-    /**
-     * Tally the number of fields and parameters.
-     */
-    private void countFields() {
-        for (final Symbol symbol : this.symbols) {
-            if (symbol != null) {
-                if (hasArguments() && symbol.isParam()) {
-                    symbol.setFieldIndex(paramCount++);
-                } else {
-                    symbol.setFieldIndex(fieldCount++);
-                }
-            }
-        }
-
-        paddedFieldCount = fieldCount + FIELD_PADDING;
-    }
-
-    /**
-     * Locate (or indirectly create) the object container class.
-     */
-    private void findClass() {
-        fieldObjectClassName = isScope() ?
-            ObjectClassGenerator.getClassName(fieldCount, paramCount) :
-            ObjectClassGenerator.getClassName(paddedFieldCount);
-
-        try {
-            this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
-        } catch (final ClassNotFoundException e) {
-            throw new AssertionError("Nashorn has encountered an internal error.  Structure can not be created.");
-        }
     }
 
     /**
@@ -116,6 +73,12 @@
     protected abstract void makeObject(final MethodEmitter method);
 
     /**
+     * Construct the property map appropriate for the object.
+     * @return the newly created property map
+     */
+    protected abstract PropertyMap makeMap();
+
+    /**
      * Create a new MapCreator
      * @param clazz type of MapCreator
      * @return map creator instantiated by type
@@ -125,12 +88,11 @@
     }
 
     /**
-     * Construct the property map appropriate for the object.
-     * @return the newly created property map
+     * Loads the scope on the stack through the passed method emitter.
+     * @param method the method emitter to use
      */
-    protected PropertyMap makeMap() {
-        propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments(), fieldCount, paddedFieldCount);
-        return propertyMap;
+    protected void loadScope(final MethodEmitter method) {
+        method.loadCompilerConstant(SCOPE);
     }
 
     /**
@@ -144,16 +106,6 @@
     }
 
     /**
-     * Get the class name for the object class,
-     * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
-     *
-     * @return script class name
-     */
-    String getClassName() {
-        return fieldObjectClassName;
-    }
-
-    /**
      * Is this a scope object
      * @return true if scope
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010-2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.codegen;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.scripts.JO;
+
+import java.util.List;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
+
+/**
+ * An object creator that uses spill properties.
+ */
+public class SpillObjectCreator extends ObjectCreator {
+
+    private final List<Node> values;
+
+    /**
+     * Constructor
+     *
+     * @param codegen  code generator
+     * @param keys     keys for fields in object
+     * @param symbols  symbols for fields in object
+     * @param values   list of values corresponding to keys
+     */
+    protected SpillObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<Node> values) {
+        super(codegen, keys, symbols, false, false);
+        this.values = values;
+        makeMap();
+    }
+
+    @Override
+    protected void makeObject(final MethodEmitter method) {
+        assert !isScope() : "spill scope objects are not currently supported";
+
+        final int      length       = keys.size();
+        final Object[] presetValues = new Object[propertyMap.size()];
+        final Class    clazz        = JO.class;
+
+        // Compute constant values
+        for (int i = 0; i < length; i++) {
+            final String key = keys.get(i);
+            final Property property = propertyMap.findProperty(key);
+
+            if (property != null) {
+                presetValues[property.getSlot()] = LiteralNode.objectAsConstant(values.get(i));
+            }
+        }
+
+        method._new(clazz).dup();
+        codegen.loadConstant(propertyMap);
+
+        method.invoke(constructorNoLookup(JO.class, PropertyMap.class));
+
+        method.dup();
+        codegen.loadConstant(presetValues);
+
+        // Create properties with non-constant values
+        for (int i = 0; i < length; i++) {
+            final String key = keys.get(i);
+            final Property property = propertyMap.findProperty(key);
+
+            if (property != null && presetValues[property.getSlot()] == LiteralNode.POSTSET_MARKER) {
+                method.dup();
+                method.load(property.getSlot());
+                codegen.load(values.get(i)).convert(OBJECT);
+                method.arraystore();
+                presetValues[property.getSlot()] = null;
+            }
+        }
+
+        method.putField(Type.typeFor(ScriptObject.class).getInternalName(), "spill", Type.OBJECT_ARRAY.getDescriptor());
+        final int callSiteFlags = codegen.getCallSiteFlags();
+
+        // Assign properties with valid array index keys
+        for (int i = 0; i < length; i++) {
+            final String key = keys.get(i);
+            final Property property = propertyMap.findProperty(key);
+            final Node value = values.get(i);
+
+            if (property == null && value != null) {
+                method.dup();
+                method.load(keys.get(i));
+                codegen.load(value);
+                method.dynamicSetIndex(callSiteFlags);
+            }
+        }
+    }
+
+    @Override
+    protected PropertyMap makeMap() {
+        assert propertyMap == null : "property map already initialized";
+
+        propertyMap = new MapCreator(JO.class, keys, symbols) {
+            @Override
+            protected int getPropertyFlags(Symbol symbol, boolean hasArguments) {
+                return super.getPropertyFlags(symbol, hasArguments) | Property.IS_SPILL | Property.IS_ALWAYS_OBJECT;
+            }
+        }.makeSpillMap(false);
+
+        return propertyMap;
+    }
+}
--- a/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Mon Jul 08 18:43:41 2013 +0530
@@ -29,7 +29,6 @@
 import java.util.ArrayList;
 import java.util.Deque;
 import java.util.List;
-import java.util.ListIterator;
 
 /**
  * This is a subclass of lexical context used for filling
@@ -63,6 +62,16 @@
         return sstack.pop();
     }
 
+    /**
+     * Override this method to perform some additional processing on the block after its statements have been set. By
+     * default does nothing and returns the original block.
+     * @param block the block to operate on
+     * @return a modified block.
+     */
+    protected Block afterSetStatements(Block block) {
+        return block;
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public <T extends LexicalContextNode> T pop(final T node) {
@@ -70,6 +79,7 @@
         if (node instanceof Block) {
             final List<Statement> newStatements = popStatements();
             expected = (T)((Block)node).setStatements(this, newStatements);
+            expected = (T)afterSetStatements((Block)expected);
             if (!sstack.isEmpty()) {
                 lastStatement = lastStatement(sstack.peek());
             }
@@ -107,10 +117,7 @@
     }
 
     private static Statement lastStatement(final List<Statement> statements) {
-        for (final ListIterator<Statement> iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) {
-            final Statement node = iter.previous();
-            return node;
-        }
-        return null;
+        final int s = statements.size();
+        return s == 0 ? null : statements.get(s - 1);
     }
 }
--- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Mon Jul 08 18:43:41 2013 +0530
@@ -131,6 +131,10 @@
     @Ignore
     private final Compiler.Hints hints;
 
+    /** Properties of this object assigned in this function */
+    @Ignore
+    private HashSet<String> thisProperties;
+
     /** Function flags. */
     private final int flags;
 
@@ -156,6 +160,10 @@
     /** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
     public static final int HAS_NESTED_EVAL = 1 << 6;
 
+    /** Does this function have any blocks that create a scope? This is used to determine if the function needs to
+     * have a local variable slot for the scope symbol. */
+    public static final int HAS_SCOPE_BLOCK = 1 << 7;
+
     /**
      * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
      * name. This precludes it from needing to have an Arguments object defined as "arguments" local variable. Note that
@@ -277,6 +285,7 @@
         this.declaredSymbols = functionNode.declaredSymbols;
         this.kind            = functionNode.kind;
         this.firstToken      = functionNode.firstToken;
+        this.thisProperties  = functionNode.thisProperties;
     }
 
     @Override
@@ -572,7 +581,7 @@
         if(this.body == body) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -614,6 +623,33 @@
     }
 
     /**
+     * Register a property assigned to the this object in this function.
+     * @param key the property name
+     */
+    public void addThisProperty(final String key) {
+        if (thisProperties == null) {
+            thisProperties = new HashSet<>();
+        }
+        thisProperties.add(key);
+    }
+
+    /**
+     * Get the number of properties assigned to the this object in this function.
+     * @return number of properties
+     */
+    public int countThisProperties() {
+        return thisProperties == null ? 0 : thisProperties.size();
+    }
+
+    /**
+     * Returns true if any of the blocks in this function create their own scope.
+     * @return true if any of the blocks in this function create their own scope.
+     */
+    public boolean hasScopeBlock() {
+        return getFlag(HAS_SCOPE_BLOCK);
+    }
+
+    /**
      * Return the kind of this function
      * @see FunctionNode.Kind
      * @return the kind
--- a/src/jdk/nashorn/internal/ir/LexicalContext.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/LexicalContext.java	Mon Jul 08 18:43:41 2013 +0530
@@ -54,13 +54,16 @@
 
     /**
      * Set the flags for a lexical context node on the stack. Does not
-     * replace the flags, but rather adds to them
+     * replace the flags, but rather adds to them.
      *
      * @param node  node
      * @param flag  new flag to set
      */
     public void setFlag(final LexicalContextNode node, final int flag) {
         if (flag != 0) {
+            // Use setBlockNeedsScope() instead
+            assert !(flag == Block.NEEDS_SCOPE && node instanceof Block);
+
             for (int i = sp - 1; i >= 0; i--) {
                 if (stack[i] == node) {
                     flags[i] |= flag;
@@ -72,6 +75,29 @@
     }
 
     /**
+     * Marks the block as one that creates a scope. Note that this method must
+     * be used instead of {@link #setFlag(LexicalContextNode, int)} with
+     * {@link Block#NEEDS_SCOPE} because it atomically also sets the
+     * {@link FunctionNode#HAS_SCOPE_BLOCK} flag on the block's containing
+     * function.
+     * @param block the block that needs to be marked as creating a scope.
+     */
+    public void setBlockNeedsScope(final Block block) {
+        for (int i = sp - 1; i >= 0; i--) {
+            if (stack[i] == block) {
+                flags[i] |= Block.NEEDS_SCOPE;
+                for(int j = i - 1; j >=0; j --) {
+                    if(stack[j] instanceof FunctionNode) {
+                        flags[j] |= FunctionNode.HAS_SCOPE_BLOCK;
+                        return;
+                    }
+                }
+            }
+        }
+        assert false;
+    }
+
+    /**
      * Get the flags for a lexical context node on the stack
      * @param node node
      * @return the flags for the node
--- a/src/jdk/nashorn/internal/ir/LiteralNode.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/LiteralNode.java	Mon Jul 08 18:43:41 2013 +0530
@@ -49,6 +49,9 @@
     /** Literal value */
     protected final T value;
 
+    /** Marker for values that must be computed at runtime */
+    public static final Object POSTSET_MARKER = new Object();
+
     /**
      * Constructor
      *
@@ -495,6 +498,30 @@
         return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value);
     }
 
+    /**
+     * Get the constant value for an object, or {@link #POSTSET_MARKER} if the value can't be statically computed.
+     *
+     * @param object a node or value object
+     * @return the constant value or {@code POSTSET_MARKER}
+     */
+    public static Object objectAsConstant(final Object object) {
+        if (object == null) {
+            return null;
+        } else if (object instanceof Number || object instanceof String || object instanceof Boolean) {
+            return object;
+        } else if (object instanceof LiteralNode) {
+            return objectAsConstant(((LiteralNode<?>)object).getValue());
+        } else if (object instanceof UnaryNode) {
+            final UnaryNode unaryNode = (UnaryNode)object;
+
+            if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) {
+                return objectAsConstant(unaryNode.rhs());
+            }
+        }
+
+        return POSTSET_MARKER;
+    }
+
     private static final class NullLiteralNode extends LiteralNode<Object> {
 
         private NullLiteralNode(final long token, final int finish) {
@@ -525,11 +552,6 @@
      * Array literal node class.
      */
     public static final class ArrayLiteralNode extends LiteralNode<Node[]> {
-        private static class PostsetMarker {
-            //empty
-        }
-
-        private static PostsetMarker POSTSET_MARKER = new PostsetMarker();
 
         /** Array element type. */
         private Type elementType;
@@ -740,24 +762,6 @@
             }
         }
 
-        private Object objectAsConstant(final Object object) {
-            if (object == null) {
-                return null;
-            } else if (object instanceof Number || object instanceof String || object instanceof Boolean) {
-                return object;
-            } else if (object instanceof LiteralNode) {
-                return objectAsConstant(((LiteralNode<?>)object).getValue());
-            } else if (object instanceof UnaryNode) {
-                final UnaryNode unaryNode = (UnaryNode)object;
-
-                if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) {
-                    return objectAsConstant(unaryNode.rhs());
-                }
-            }
-
-            return POSTSET_MARKER;
-        }
-
         @Override
         public Node[] getArray() {
             return value;
--- a/src/jdk/nashorn/internal/ir/RuntimeNode.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/RuntimeNode.java	Mon Jul 08 18:43:41 2013 +0530
@@ -53,8 +53,6 @@
         NEW,
         /** Typeof operator */
         TYPEOF,
-        /** void type */
-        VOID,
         /** Reference error type */
         REFERENCE_ERROR,
         /** Delete operator */
--- a/src/jdk/nashorn/internal/ir/Symbol.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/Symbol.java	Mon Jul 08 18:43:41 2013 +0530
@@ -29,7 +29,6 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.StringTokenizer;
-
 import jdk.nashorn.internal.codegen.types.Range;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.Context;
@@ -705,7 +704,7 @@
     public static void setSymbolIsScope(final LexicalContext lc, final Symbol symbol) {
         symbol.setIsScope();
         if (!symbol.isGlobal()) {
-            lc.setFlag(lc.getDefiningBlock(symbol), Block.NEEDS_SCOPE);
+            lc.setBlockNeedsScope(lc.getDefiningBlock(symbol));
         }
     }
 
--- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Mon Jul 08 18:43:41 2013 +0530
@@ -514,7 +514,7 @@
             type("ArrayExpression");
             comma();
 
-            final Node[] value = (Node[])literalNode.getValue();
+            final Node[] value = literalNode.getArray();
             array("elements", Arrays.asList(value));
         } else {
             type("Literal");
--- a/src/jdk/nashorn/internal/lookup/Lookup.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/lookup/Lookup.java	Mon Jul 08 18:43:41 2013 +0530
@@ -125,44 +125,6 @@
     }
 
     /**
-     * Create a new {@link Property}
-     *
-     * @param map             property map
-     * @param key             property key
-     * @param flags           property flags
-     * @param propertyGetter  getter for property if available, null otherwise
-     * @param propertySetter  setter for property if available, null otherwise
-     *
-     * @return new property map, representing {@code PropertyMap} with the new property added to it
-     */
-    @SuppressWarnings("fallthrough")
-    public static PropertyMap newProperty(final PropertyMap map, final String key, final int flags, final MethodHandle propertyGetter, final MethodHandle propertySetter) {
-        MethodHandle getter = propertyGetter;
-        MethodHandle setter = propertySetter;
-
-        // TODO: this is temporary code. This code exists to support reflective
-        // field reader/writer handles generated by "unreflect" lookup.
-
-        switch (getter.type().parameterCount()) {
-        case 0:
-            // A static field reader, so drop the 'self' argument.
-            getter = MH.dropArguments(getter, 0, Object.class);
-            if (setter != null) {
-                setter = MH.dropArguments(setter, 0, Object.class);
-            }
-        // fall through
-        case 1:
-            // standard getter that accepts 'self'.
-            break;
-        default:
-            // Huh!! something wrong..
-            throw new IllegalArgumentException("getter/setter has wrong arguments");
-        }
-
-        return map.newProperty(key, flags, -1, getter, setter);
-    }
-
-    /**
      * This method filters primitive return types using JavaScript semantics. For example,
      * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
      * If you are returning values to JavaScript that have to be of a specific type, this is
--- a/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Mon Jul 08 18:43:41 2013 +0530
@@ -42,10 +42,19 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
+    static PropertyMap getInitialMap() {
+        return $nasgenmap$;
+    }
+
+    private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
+        super(global.getArrayBufferViewMap());
+        checkConstructorArgs(buffer, byteOffset, elementLength);
+        this.setProto(getPrototype(global));
+        this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
+    }
+
     ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
-        checkConstructorArgs(buffer, byteOffset, elementLength);
-        this.setProto(getPrototype());
-        this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
+        this(buffer, byteOffset, elementLength, Global.instance());
     }
 
     private void checkConstructorArgs(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
@@ -282,7 +291,7 @@
 
     protected abstract Factory factory();
 
-    protected abstract ScriptObject getPrototype();
+    protected abstract ScriptObject getPrototype(final Global global);
 
     protected boolean isFloatArray() {
         return false;
--- a/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/Global.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/Global.java	Mon Jul 08 18:43:41 2013 +0530
@@ -43,7 +43,6 @@
 import java.util.Map;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -363,6 +362,36 @@
     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    anonymousFunctionMap;
+    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
     private static PropertyMap $nasgenmap$;
 
@@ -390,14 +417,14 @@
      * @param context the context
      */
     public Global(final Context context) {
-        this.context = context;
-        this.setIsScope();
         /*
          * Duplicate global's map and use it. This way the initial Map filled
          * by nasgen (referenced from static field in this class) is retained
-         * 'as is'. This allows multiple globals to be used within a context.
+         * 'as is' (as that one is process wide singleton.
          */
-        this.setMap(getMap().duplicate());
+        super($nasgenmap$.duplicate());
+        this.setContext(context);
+        this.setIsScope();
 
         final int cacheSize = context.getEnv()._class_cache_size;
         if (cacheSize > 0) {
@@ -424,7 +451,7 @@
      * @return the script environment
      */
     static ScriptEnvironment getEnv() {
-        return instance().context.getEnv();
+        return instance().getContext().getEnv();
     }
 
     /**
@@ -433,7 +460,7 @@
      * @return the context
      */
     static Context getThisContext() {
-        return instance().context;
+        return instance().getContext();
     }
 
     // GlobalObject interface implementation
@@ -456,11 +483,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
@@ -489,7 +516,7 @@
 
     @Override
     public ScriptObject newObject() {
-        return new JO(getObjectPrototype());
+        return new JO(getObjectPrototype(), getObjectMap());
     }
 
     @Override
@@ -566,52 +593,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);
@@ -700,7 +727,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));
     }
 
     /**
@@ -740,7 +767,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);
     }
 
     /**
@@ -760,7 +787,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);
     }
 
     /**
@@ -776,6 +803,7 @@
         return UNDEFINED;
     }
 
+    // builtin prototype accessors
     ScriptObject getFunctionPrototype() {
         return ScriptFunction.getPrototype(builtinFunction);
     }
@@ -884,11 +912,127 @@
         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 getAnonymousFunctionMap() {
+        return anonymousFunctionMap;
+    }
+
+    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
      *
@@ -1394,7 +1538,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(env);
+
         // initialize Function and Object constructor
         initFunctionAndObject();
 
@@ -1440,10 +1588,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.
@@ -1454,12 +1602,16 @@
         initErrorObjects();
 
         // java access
-        initJavaAccess();
+        if (! env._no_java) {
+            initJavaAccess();
+        }
 
-        initTypedArray();
+        if (! env._no_typed_arrays) {
+            initTypedArray();
+        }
 
         if (env._scripting) {
-            initScripting();
+            initScripting(env);
         }
 
         if (Context.DEBUG && System.getSecurityManager() == null) {
@@ -1540,7 +1692,7 @@
         this.builtinJavaApi = initConstructor("Java");
     }
 
-    private void initScripting() {
+    private void initScripting(final ScriptEnvironment scriptEnv) {
         Object value;
         value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
         addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
@@ -1559,7 +1711,6 @@
 
         // Nashorn extension: global.$OPTIONS (scripting-mode-only)
         final ScriptObject options = newObject();
-        final ScriptEnvironment scriptEnv = context.getEnv();
         copyOptions(options, scriptEnv);
         addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
 
@@ -1712,6 +1863,46 @@
         }
     }
 
+    private void copyInitialMaps(final ScriptEnvironment env) {
+        this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
+        this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
+        this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
+        this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
+        this.nativeArrayMap = NativeArray.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.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().duplicate();
+        this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
+        this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
+        this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
+
+        // java
+        if (! env._no_java) {
+            this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
+        }
+
+        // typed arrays
+        if (! env._no_typed_arrays) {
+            this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
+            this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
+        }
+    }
+
     // Function and Object constructors are inter-dependent. Also,
     // Function.prototype
     // functions are not properly initialized. We fix the references here.
@@ -1723,7 +1914,7 @@
         this.builtinFunction = (ScriptFunction)initConstructor("Function");
 
         // create global anonymous function
-        final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
+        final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this);
         // need to copy over members of Function.prototype to anon function
         anon.addBoundProperties(getFunctionPrototype());
 
@@ -1792,13 +1983,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/src/jdk/nashorn/internal/objects/NativeArguments.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Jul 08 18:43:41 2013 +0530
@@ -31,8 +31,10 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
+import jdk.nashorn.internal.runtime.AccessorProperty;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -41,8 +43,6 @@
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * ECMA 10.6 Arguments Object.
@@ -64,10 +64,14 @@
     private static final PropertyMap map$;
 
     static {
-        PropertyMap map = PropertyMap.newMap(NativeArguments.class);
-        map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
-        map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE);
-        map$ = map;
+        final ArrayList<Property> properties = new ArrayList<>(2);
+        properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
+        properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE));
+        map$ = PropertyMap.newMap(properties).setIsShared();
+    }
+
+    static PropertyMap getInitialMap() {
+        return map$;
     }
 
     private Object length;
@@ -76,8 +80,8 @@
     // 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/src/jdk/nashorn/internal/objects/NativeArray.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeBoolean.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeBoolean.java	Mon Jul 08 18:43:41 2013 +0530
@@ -40,7 +40,6 @@
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
 
 /**
@@ -56,15 +55,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 +138,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 +179,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/src/jdk/nashorn/internal/objects/NativeDate.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeDebug.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeDebug.java	Mon Jul 08 18:43:41 2013 +0530
@@ -49,10 +49,12 @@
 public final class NativeDebug extends ScriptObject {
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
-    NativeDebug() {
-        super(Global.objectPrototype(), $nasgenmap$);
+    private NativeDebug() {
+        // don't create me!
+        throw new UnsupportedOperationException();
     }
 
     @Override
@@ -143,7 +145,7 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static Object equals(final Object self, final Object obj1, final Object obj2) {
-        return (obj1 != null) ? obj1.equals(obj2) : false;
+        return Objects.equals(obj1, obj2);
     }
 
     /**
@@ -176,6 +178,15 @@
     }
 
     /**
+     * Returns the property listener count for a script object
+     * @return listener count
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getListenerCount(final Object self, final Object obj) {
+        return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0;
+    }
+
+    /**
      * Dump all Nashorn debug mode counters. Calling this may be better if
      * you want to print all counters. This way you can avoid too many callsites
      * due to counter access itself!!
@@ -196,6 +207,8 @@
         out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
         out.println("PropertyMap count " + PropertyMap.getCount());
         out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
+        out.println("PropertyMap shared " + PropertyMap.getSharedCount());
+        out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
         out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
         out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
         out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit());
--- a/src/jdk/nashorn/internal/objects/NativeError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeError.java	Mon Jul 08 18:43:41 2013 +0530
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import jdk.nashorn.api.scripting.NashornException;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -87,8 +86,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 +99,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";
@@ -119,6 +130,7 @@
      * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
      *
      * @param self self reference
+     * @param errorObj the error object
      * @return undefined
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
@@ -286,9 +298,9 @@
         final Object exception = ECMAException.getException(sobj);
         if (exception instanceof Throwable) {
             return getScriptStackString(sobj, (Throwable)exception);
-        } else {
-            return "";
         }
+
+        return "";
     }
 
     /**
@@ -353,11 +365,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/src/jdk/nashorn/internal/objects/NativeEvalError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeEvalError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -48,6 +48,7 @@
     public static final int BYTES_PER_ELEMENT = 4;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -191,7 +192,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getFloat32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getFloat32ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -48,6 +48,7 @@
     public static final int BYTES_PER_ELEMENT = 8;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -201,7 +202,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getFloat64ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getFloat64ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeFunction.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeFunction.java	Mon Jul 08 18:43:41 2013 +0530
@@ -29,6 +29,7 @@
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
 import java.util.List;
+
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -55,10 +56,12 @@
 public final class NativeFunction {
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     // do *not* create me!
     private NativeFunction() {
+        throw new UnsupportedOperationException();
     }
 
     /**
--- a/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -42,6 +42,7 @@
 public final class NativeInt16Array extends ArrayBufferView {
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     /**
@@ -150,7 +151,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt16ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt16ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -47,6 +47,7 @@
     public static final int BYTES_PER_ELEMENT = 4;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -153,7 +154,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt32ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -47,6 +47,7 @@
     public static final int BYTES_PER_ELEMENT = 1;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -143,7 +144,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getInt8ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getInt8ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Mon Jul 08 18:43:41 2013 +0530
@@ -48,7 +48,7 @@
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 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 +146,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 +163,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 +572,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 +739,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/src/jdk/nashorn/internal/objects/NativeJSON.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJSON.java	Mon Jul 08 18:43:41 2013 +0530
@@ -60,10 +60,12 @@
             ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
-    NativeJSON() {
-        super(Global.objectPrototype(), $nasgenmap$);
+    private NativeJSON() {
+        // don't create me!!
+        throw new UnsupportedOperationException();
     }
 
     /**
--- a/src/jdk/nashorn/internal/objects/NativeJava.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJava.java	Mon Jul 08 18:43:41 2013 +0530
@@ -32,12 +32,14 @@
 import java.util.Collection;
 import java.util.Deque;
 import java.util.List;
+
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.internal.dynalink.support.TypeUtilities;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ListAdapter;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -54,9 +56,12 @@
 public final class NativeJava {
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private NativeJava() {
+        // don't create me
+        throw new UnsupportedOperationException();
     }
 
     /**
@@ -103,12 +108,22 @@
      * var anArrayList = new ArrayList
      * var anArrayListWithSize = new ArrayList(16)
      * </pre>
-     * In the special case of inner classes, you need to use the JVM fully qualified name, meaning using {@code $} sign
-     * in the class name:
+     * In the special case of inner classes, you can either use the JVM fully qualified name, meaning using {@code $}
+     * sign in the class name, or you can use the dot:
      * <pre>
      * var ftype = Java.type("java.awt.geom.Arc2D$Float")
      * </pre>
-     * However, once you retrieved the outer class, you can access the inner class as a property on it:
+     * and
+     * <pre>
+     * var ftype = Java.type("java.awt.geom.Arc2D.Float")
+     * </pre>
+     * both work. Note however that using the dollar sign is faster, as Java.type first tries to resolve the class name
+     * as it is originally specified, and the internal JVM names for inner classes use the dollar sign. If you use the
+     * dot, Java.type will internally get a ClassNotFoundException and subsequently retry by changing the last dot to
+     * dollar sign. As a matter of fact, it'll keep replacing dots with dollar signs until it either successfully loads
+     * the class or runs out of all dots in the name. This way it can correctly resolve and load even multiply nested
+     * inner classes with the dot notation. Again, this will be slower than using the dollar signs in the name. An
+     * alternative way to access the inner class is as a property of the outer class:
      * <pre>
      * var arctype = Java.type("java.awt.geom.Arc2D")
      * var ftype = arctype.Float
@@ -388,7 +403,33 @@
 
     private static Class<?> simpleType(final String typeName) throws ClassNotFoundException {
         final Class<?> primClass = TypeUtilities.getPrimitiveTypeByName(typeName);
-        return primClass != null ? primClass : Global.getThisContext().findClass(typeName);
+        if(primClass != null) {
+            return primClass;
+        }
+        final Context ctx = Global.getThisContext();
+        try {
+            return ctx.findClass(typeName);
+        } catch(ClassNotFoundException e) {
+            // The logic below compensates for a frequent user error - when people use dot notation to separate inner
+            // class names, i.e. "java.lang.Character.UnicodeBlock" vs."java.lang.Character$UnicodeBlock". The logic
+            // below will try alternative class names, replacing dots at the end of the name with dollar signs.
+            final StringBuilder nextName = new StringBuilder(typeName);
+            int lastDot = nextName.length();
+            for(;;) {
+                lastDot = nextName.lastIndexOf(".", lastDot - 1);
+                if(lastDot == -1) {
+                    // Exhausted the search space, class not found - rethrow the original exception.
+                    throw e;
+                }
+                nextName.setCharAt(lastDot, '$');
+                try {
+                    return ctx.findClass(nextName.toString());
+                } catch(ClassNotFoundException cnfe) {
+                    // Intentionally ignored, so the loop retries with the next name
+                }
+            }
+        }
+
     }
 
     private static Class<?> arrayType(final String typeName) throws ClassNotFoundException {
--- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeMath.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeMath.java	Mon Jul 08 18:43:41 2013 +0530
@@ -43,10 +43,12 @@
 public final class NativeMath extends ScriptObject {
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     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/src/jdk/nashorn/internal/objects/NativeNumber.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeNumber.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Mon Jul 08 18:43:41 2013 +0530
@@ -27,7 +27,6 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -55,9 +54,12 @@
     private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private NativeObject() {
+        // don't create me!
+        throw new UnsupportedOperationException();
     }
 
     private static ECMAException notAnObject(final Object obj) {
--- a/src/jdk/nashorn/internal/objects/NativeRangeError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRangeError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeRegExp.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java	Mon Jul 08 18:43:41 2013 +0530
@@ -68,9 +68,20 @@
     private Global globalObject;
 
     // initialized by nasgen
+    @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) {
@@ -80,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
@@ -614,7 +632,7 @@
             return null;
         }
 
-        return new NativeRegExpExecResult(match);
+        return new NativeRegExpExecResult(match, globalObject);
     }
 
     /**
@@ -885,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/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Mon Jul 08 18:43:41 2013 +0530
@@ -30,14 +30,14 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
 import java.util.Arrays;
+import jdk.nashorn.internal.runtime.AccessorProperty;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * ECMA 10.6 Arguments Object.
@@ -54,21 +54,26 @@
     private static final PropertyMap map$;
 
     static {
-        PropertyMap map = PropertyMap.newMap(NativeStrictArguments.class);
-        map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
+        final ArrayList<Property> properties = new ArrayList<>(1);
+        properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
+        PropertyMap map = PropertyMap.newMap(properties);
         // In strict mode, the caller and callee properties should throw TypeError
         // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
         map = map.addProperty(map.newUserAccessors("caller", flags));
         map = map.addProperty(map.newUserAccessors("callee", flags));
-        map$ = map;
+        map$ = map.setIsShared();
+    }
+
+    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 +148,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/src/jdk/nashorn/internal/objects/NativeString.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeString.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeTypeError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeTypeError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeURIError.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeURIError.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -47,6 +47,7 @@
     public static final int BYTES_PER_ELEMENT = 2;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -149,7 +150,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint16ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint16ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -48,6 +48,7 @@
     public static final int BYTES_PER_ELEMENT = 4;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -168,7 +169,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint32ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint32ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Mon Jul 08 18:43:41 2013 +0530
@@ -47,6 +47,7 @@
     public static final int BYTES_PER_ELEMENT = 1;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -142,7 +143,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint8ArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint8ArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Mon Jul 08 18:43:41 2013 +0530
@@ -48,6 +48,7 @@
     public static final int BYTES_PER_ELEMENT = 1;
 
     // initialized by nasgen
+    @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
 
     private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@@ -159,7 +160,7 @@
     }
 
     @Override
-    protected ScriptObject getPrototype() {
-        return Global.instance().getUint8ClampedArrayPrototype();
+    protected ScriptObject getPrototype(final Global global) {
+        return global.getUint8ClampedArrayPrototype();
     }
 }
--- a/src/jdk/nashorn/internal/objects/PrototypeObject.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/PrototypeObject.java	Mon Jul 08 18:43:41 2013 +0530
@@ -30,12 +30,12 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import jdk.nashorn.internal.runtime.AccessorProperty;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * Instances of this class serve as "prototype" object for script functions.
@@ -52,13 +52,22 @@
     private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class);
 
     static {
-        PropertyMap map = PropertyMap.newMap(PrototypeObject.class);
-        map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR);
-        map$ = map;
+        final ArrayList<Property> properties = new ArrayList<>(1);
+        properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR));
+        map$ = PropertyMap.newMap(properties).setIsShared();
+    }
+
+    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/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Jul 08 18:43:41 2013 +0530
@@ -28,6 +28,7 @@
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
 import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
 import jdk.nashorn.internal.runtime.GlobalFunctions;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -36,6 +37,7 @@
 import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.AccessorProperty;
 
 /**
  * Concrete implementation of ScriptFunction. This sets correct map for the
@@ -53,9 +55,30 @@
     // property map for non-strict, non-bound functions.
     private static final PropertyMap map$;
 
+    static PropertyMap getInitialMap() {
+        return map$;
+    }
+
+    static PropertyMap getInitialAnonymousMap() {
+        return AnonymousFunction.getInitialMap();
+    }
+
+    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 +88,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 +106,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 +126,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,27 +141,32 @@
      * @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 {
-        PropertyMap map = PropertyMap.newMap(ScriptFunctionImpl.class);
-        map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE);
-        map = Lookup.newProperty(map, "length",    Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null);
-        map = Lookup.newProperty(map, "name",      Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null);
-        map$ = map;
+        final ArrayList<Property> properties = new ArrayList<>(3);
+        properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
+        properties.add(AccessorProperty.create("length",  Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
+        properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
+        map$ = PropertyMap.newMap(properties);
         strictmodemap$ = createStrictModeMap(map$);
         boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
+        // There are order dependencies between normal map, struct map and bound map
+        // We can make these 'shared' only after initialization of all three.
+        map$.setIsShared();
+        strictmodemap$.setIsShared();
+        boundfunctionmap$.setIsShared();
     }
 
     // function object representing TypeErrorThrower
@@ -149,17 +189,18 @@
         return typeErrorThrower;
     }
 
-    private static PropertyMap createStrictModeMap(PropertyMap map) {
+    private static PropertyMap createStrictModeMap(final PropertyMap map) {
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
+        PropertyMap newMap = map;
         // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
-        map = map.addProperty(map.newUserAccessors("arguments", flags));
-        map = map.addProperty(map.newUserAccessors("caller", flags));
-        return map;
+        newMap = newMap.addProperty(map.newUserAccessors("arguments", flags));
+        newMap = newMap.addProperty(map.newUserAccessors("caller", flags));
+        return newMap;
     }
 
     // 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) {
@@ -171,15 +212,19 @@
     // Instance of this class is used as global anonymous function which
     // serves as Function.prototype object.
     private static class AnonymousFunction extends ScriptFunctionImpl {
-        private static final PropertyMap nasgenmap$$ = PropertyMap.newMap(AnonymousFunction.class);
+        private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
 
-        AnonymousFunction() {
-            super("", GlobalFunctions.ANONYMOUS, nasgenmap$$, null);
+        static PropertyMap getInitialMap() {
+            return map$;
+        }
+
+        AnonymousFunction(final Global global) {
+            super("", GlobalFunctions.ANONYMOUS, global.getAnonymousFunctionMap(), null);
         }
     }
 
-    static ScriptFunctionImpl newAnonymousFunction() {
-        return new AnonymousFunction();
+    static ScriptFunctionImpl newAnonymousFunction(final Global global) {
+        return new AnonymousFunction(global);
     }
 
     /**
@@ -254,8 +299,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/src/jdk/nashorn/internal/parser/Parser.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Mon Jul 08 18:43:41 2013 +0530
@@ -1084,6 +1084,12 @@
             switch (type) {
             case SEMICOLON:
                 // for (init; test; modify)
+
+                // for each (init; test; modify) is invalid
+                if (forNode.isForEach()) {
+                    throw error(AbstractParser.message("for.each.without.in"), token);
+                }
+
                 expect(SEMICOLON);
                 if (type != SEMICOLON) {
                     forNode = forNode.setTest(lc, expression());
@@ -2003,7 +2009,7 @@
                     }
 
                     if (!redefinitionOk) {
-                        throw error(AbstractParser.message("property.redefinition", key.toString()), property.getToken());
+                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
                     }
 
                     PropertyNode newProperty = existingProperty;
@@ -2951,7 +2957,7 @@
             } else {
                 lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL);
             }
-            lc.setFlag(lc.getFunctionBody(fn), Block.NEEDS_SCOPE);
+            lc.setBlockNeedsScope(lc.getFunctionBody(fn));
         }
     }
 
--- a/src/jdk/nashorn/internal/parser/TokenType.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/parser/TokenType.java	Mon Jul 08 18:43:41 2013 +0530
@@ -93,7 +93,7 @@
     ASSIGN_BIT_OR  (BINARY,  "|=",    2, false),
     OR             (BINARY,  "||",    4, true),
     RBRACE         (BRACKET, "}"),
-    BIT_NOT        (BINARY,  "~",    14, false),
+    BIT_NOT        (UNARY,   "~",     14, false),
 
     // ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words.
     // All other Java keywords are commented out.
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Mon Jul 08 18:43:41 2013 +0530
@@ -75,6 +75,8 @@
 
     private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
     private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
+    private static final MethodType ACCESSOR_GETTER_PRIMITIVE_TYPE;
+    private static final MethodType ACCESSOR_SETTER_PRIMITIVE_TYPE;
     private static final MethodHandle SPILL_ELEMENT_GETTER;
     private static final MethodHandle SPILL_ELEMENT_SETTER;
 
@@ -82,17 +84,43 @@
     private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
 
     static {
+        MethodType getterPrimitiveType = null;
+        MethodType setterPrimitiveType = null;
+
         for (int i = 0; i < NOOF_TYPES; i++) {
             final Type type = ACCESSOR_TYPES.get(i);
             ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
             ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
+
+            if (type == PRIMITIVE_TYPE) {
+                getterPrimitiveType = ACCESSOR_GETTER_TYPES[i];
+                setterPrimitiveType = ACCESSOR_SETTER_TYPES[i];
+            }
         }
 
-        final MethodHandle spillGetter = MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class);
+        ACCESSOR_GETTER_PRIMITIVE_TYPE = getterPrimitiveType;
+        ACCESSOR_SETTER_PRIMITIVE_TYPE = setterPrimitiveType;
+
+        final MethodType spillGetterType = MethodType.methodType(Object[].class, Object.class);
+        final MethodHandle spillGetter = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), spillGetterType);
         SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
         SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
     }
 
+    /**
+     * Create a new accessor property. Factory method used by nasgen generated code.
+     *
+     * @param key           {@link Property} key.
+     * @param propertyFlags {@link Property} flags.
+     * @param getter        {@link Property} get accessor method.
+     * @param setter        {@link Property} set accessor method.
+     *
+     * @return  New {@link AccessorProperty} created.
+     */
+    public static AccessorProperty create(final String key, final int propertyFlags, final MethodHandle getter, final MethodHandle setter) {
+        return new AccessorProperty(key, propertyFlags, -1, getter, setter);
+    }
+
     /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
     private MethodHandle primitiveGetter;
 
@@ -126,8 +154,8 @@
 
         this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
         this.primitiveSetter = bindTo(property.primitiveSetter, delegate);
-        this.objectGetter    = bindTo(property.objectGetter, delegate);
-        this.objectSetter    = bindTo(property.objectSetter, delegate);
+        this.objectGetter    = bindTo(property.ensureObjectGetter(), delegate);
+        this.objectSetter    = bindTo(property.ensureObjectSetter(), delegate);
 
         setCurrentType(property.getCurrentType());
     }
@@ -177,9 +205,8 @@
                     ACCESSOR_GETTER_TYPES[i]);
             }
         } else {
-            //this will work as the object setter and getter will be converted appropriately
-            objectGetter = getter;
-            objectSetter = setter;
+            objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
+            objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
         }
 
         setCurrentType(getterType);
@@ -195,8 +222,8 @@
             setters = new MethodHandle[fieldCount];
             for(int i = 0; i < fieldCount; ++i) {
                 final String fieldName = ObjectClassGenerator.getFieldName(i, Type.OBJECT);
-                getters[i] = MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
-                setters[i] = MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
+                getters[i] = MH.asType(MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.GET_OBJECT_TYPE);
+                setters[i] = MH.asType(MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.SET_OBJECT_TYPE);
             }
         }
     }
@@ -224,17 +251,18 @@
             final MethodHandle arguments   = MH.getter(lookup, structure, "arguments", Object.class);
             final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class));
 
-            objectGetter = MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
-            objectSetter = MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
+            objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.GET_OBJECT_TYPE);
+            objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.SET_OBJECT_TYPE);
         } else {
             final GettersSetters gs = GETTERS_SETTERS.get(structure);
             objectGetter = gs.getters[slot];
             objectSetter = gs.setters[slot];
 
             if (!OBJECT_FIELDS_ONLY) {
-                final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, ObjectClassGenerator.PRIMITIVE_TYPE);
-                primitiveGetter = MH.getter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
-                primitiveSetter = MH.setter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
+                final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, PRIMITIVE_TYPE);
+                final Class<?> typeClass = PRIMITIVE_TYPE.getTypeClass();
+                primitiveGetter = MH.asType(MH.getter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_GETTER_PRIMITIVE_TYPE);
+                primitiveSetter = MH.asType(MH.setter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_SETTER_PRIMITIVE_TYPE);
             }
         }
 
@@ -317,24 +345,30 @@
         }
     }
 
-    @Override
-    public MethodHandle getGetter(final Class<?> type) {
+    // Spill getters and setters are lazily initialized, see JDK-8011630
+    private MethodHandle ensureObjectGetter() {
         if (isSpill() && objectGetter == null) {
             objectGetter = getSpillGetter();
         }
+        return objectGetter;
+    }
+
+    private MethodHandle ensureObjectSetter() {
+        if (isSpill() && objectSetter == null) {
+            objectSetter = getSpillSetter();
+        }
+        return objectSetter;
+    }
+
+    @Override
+    public MethodHandle getGetter(final Class<?> type) {
         final int i = getAccessorTypeIndex(type);
+        ensureObjectGetter();
+
         if (getters[i] == null) {
             getters[i] = debug(
-                MH.asType(
-                    createGetter(
-                        currentType,
-                        type,
-                        primitiveGetter,
-                        objectGetter),
-                    ACCESSOR_GETTER_TYPES[i]),
-                currentType,
-                type,
-                "get");
+                createGetter(currentType, type, primitiveGetter, objectGetter),
+                currentType, type, "get");
         }
 
         return getters[i];
@@ -366,11 +400,8 @@
     }
 
     private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
-        if (isSpill() && objectSetter == null) {
-            objectSetter = getSpillSetter();
-        }
+        ensureObjectSetter();
         MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
-        mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
         mh = debug(mh, currentType, type, "set");
         return mh;
     }
@@ -423,9 +454,9 @@
         final int slot = getSlot();
         MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
         if (getter == null) {
-            getter = MH.asType(MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot), Lookup.GET_OBJECT_TYPE);
+            getter = MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot);
             if (slot < SPILL_CACHE_SIZE) {
-                SPILL_ACCESSORS[slot * 2] = getter;
+                SPILL_ACCESSORS[slot * 2 + 0] = getter;
             }
         }
         return getter;
@@ -435,7 +466,7 @@
         final int slot = getSlot();
         MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
         if (setter == null) {
-            setter = MH.asType(MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot), Lookup.SET_OBJECT_TYPE);
+            setter = MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot);
             if (slot < SPILL_CACHE_SIZE) {
                 SPILL_ACCESSORS[slot * 2 + 1] = setter;
             }
--- a/src/jdk/nashorn/internal/runtime/Context.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Mon Jul 08 18:43:41 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);
@@ -253,14 +253,7 @@
         this.env       = new ScriptEnvironment(options, out, err);
         this._strict   = env._strict;
         this.appLoader = appLoader;
-        this.scriptLoader = (ScriptLoader)AccessController.doPrivileged(
-             new PrivilegedAction<ClassLoader>() {
-                @Override
-                public ClassLoader run() {
-                    final StructureLoader structureLoader = new StructureLoader(sharedLoader, Context.this);
-                    return new ScriptLoader(structureLoader, Context.this);
-                }
-             });
+        this.scriptLoader = env._loader_per_compile? null : createNewLoader();
         this.errors    = errors;
 
         // if user passed -classpath option, make a class loader with that and set it as
@@ -817,25 +810,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/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/runtime/GlobalObject.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/GlobalObject.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/runtime/JSType.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/JSType.java	Mon Jul 08 18:43:41 2013 +0530
@@ -29,7 +29,9 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
 import java.util.Locale;
+import jdk.internal.dynalink.beans.BeansLinker;
 import jdk.internal.dynalink.beans.StaticClass;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.parser.Lexer;
 
@@ -151,6 +153,14 @@
             return JSType.FUNCTION;
         }
 
+        if (BeansLinker.isDynamicMethod(obj)) {
+            return JSType.FUNCTION;
+        }
+
+        if (obj instanceof ScriptObjectMirror) {
+            return ((ScriptObjectMirror)obj).isFunction()? JSType.FUNCTION : JSType.OBJECT;
+        }
+
         return JSType.OBJECT;
     }
 
--- a/src/jdk/nashorn/internal/runtime/ListAdapter.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java	Mon Jul 08 18:43:41 2013 +0530
@@ -1,3 +1,28 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
 package jdk.nashorn.internal.runtime;
 
 import java.util.AbstractList;
--- a/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java	Mon Jul 08 18:43:41 2013 +0530
@@ -41,6 +41,7 @@
     private static int listenersRemoved;
 
     /**
+     * Return aggregate listeners added to all PropertyListenerManagers
      * @return the listenersAdded
      */
     public static int getListenersAdded() {
@@ -48,12 +49,21 @@
     }
 
     /**
+     * Return aggregate listeners removed from all PropertyListenerManagers
      * @return the listenersRemoved
      */
     public static int getListenersRemoved() {
         return listenersRemoved;
     }
 
+    /**
+     * Return listeners added to this PropertyListenerManager.
+     * @return the listener count
+     */
+    public final int getListenerCount() {
+        return listeners != null? listeners.size() : 0;
+    }
+
     // Property listener management methods
 
     /**
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java	Mon Jul 08 18:43:41 2013 +0530
@@ -25,11 +25,8 @@
 
 package jdk.nashorn.internal.runtime;
 
-import jdk.nashorn.internal.scripts.JO;
-
 import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
 
-import java.lang.invoke.MethodHandle;
 import java.lang.invoke.SwitchPoint;
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
@@ -57,9 +54,8 @@
     private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111;
     /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
     public static final int IS_LISTENER_ADDED     = 0b0001_0000;
-
-    /** Empty map used for seed map for JO$ objects */
-    private static final PropertyMap EMPTY_MAP = new PropertyMap(EMPTY_HASHMAP);
+    /** Is this process wide "shared" map?. This flag is not copied when cloning a map */
+    public static final int IS_SHARED             = 0b0010_0000;
 
     /** Map status flags. */
     private int flags;
@@ -91,14 +87,16 @@
     /**
      * Constructor.
      *
-     * @param properties    A {@link PropertyHashMap} with initial contents.
-     * @param fieldCount    Number of fields in use.
+     * @param properties   A {@link PropertyHashMap} with initial contents.
+     * @param fieldCount   Number of fields in use.
      * @param fieldMaximum Number of fields available.
+     * @param spillLength  Number of spill slots used.
      */
-    private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum) {
+    private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength) {
         this.properties   = properties;
         this.fieldCount   = fieldCount;
         this.fieldMaximum = fieldMaximum;
+        this.spillLength  = spillLength;
 
         if (Context.DEBUG) {
             count++;
@@ -111,7 +109,7 @@
      * @param properties A {@link PropertyHashMap} with initial contents.
      */
     private PropertyMap(final PropertyHashMap properties) {
-        this(properties, 0, 0);
+        this(properties, 0, 0, 0);
     }
 
     /**
@@ -143,58 +141,49 @@
     }
 
     /**
-     * Duplicates this PropertyMap instance. This is used by nasgen generated
-     * prototype and constructor classes. {@link PropertyMap} used for singletons
-     * like these (and global instance) are duplicated using this method and used.
-     * The original filled map referenced by static fields of prototype and
-     * constructor classes are not touched. This allows multiple independent global
-     * instances to be used within a single context instance.
+     * Duplicates this PropertyMap instance. This is used to duplicate 'shared'
+     * maps {@link PropertyMap} used as process wide singletons. Shared maps are
+     * duplicated for every global scope object. That way listeners, proto and property
+     * histories are scoped within a global scope.
      *
      * @return Duplicated {@link PropertyMap}.
      */
     public PropertyMap duplicate() {
+        if (Context.DEBUG) {
+            duplicatedCount++;
+        }
         return new PropertyMap(this.properties);
     }
 
     /**
      * Public property map allocator.
      *
-     * @param structure  Class the map's {@link AccessorProperty}s apply to.
-     * @param properties Collection of initial properties.
-     * @param fieldCount    Number of fields in use.
+     * @param properties   Collection of initial properties.
+     * @param fieldCount   Number of fields in use.
      * @param fieldMaximum Number of fields available.
-     *
+     * @param spillLength  Number of used spill slots.
      * @return New {@link PropertyMap}.
      */
-    public static PropertyMap newMap(final Class<?> structure, final Collection<Property> properties, final int fieldCount, final int fieldMaximum) {
-        // Reduce the number of empty maps in the context.
-        if (structure == JO.class) {
-            return EMPTY_MAP;
-        }
-
+    public static PropertyMap newMap(final Collection<Property> properties, final int fieldCount, final int fieldMaximum,  final int spillLength) {
         PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
-
-        return new PropertyMap(newProperties, fieldCount, fieldMaximum);
+        return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength);
     }
 
     /**
-     * Public property map factory allocator
-     *
-     * @param structure  Class the map's {@link AccessorProperty}s apply to.
-     *
+     * Public property map allocator. Used by nasgen generated code.
+     * @param properties Collection of initial properties.
      * @return New {@link PropertyMap}.
      */
-    public static PropertyMap newMap(final Class<?> structure) {
-        return newMap(structure, null, 0, 0);
+    public static PropertyMap newMap(final Collection<Property> properties) {
+        return (properties == null || properties.isEmpty())? newMap() : newMap(properties, 0, 0, 0);
     }
 
     /**
      * Return a sharable empty map.
      *
-     * @param  context the context
      * @return New empty {@link PropertyMap}.
      */
-    public static PropertyMap newEmptyMap(final Context context) {
+    public static PropertyMap newMap() {
         return new PropertyMap(EMPTY_HASHMAP);
     }
 
@@ -216,6 +205,8 @@
      * @return A shared {@link SwitchPoint} for the property.
      */
     public SwitchPoint getProtoGetSwitchPoint(final ScriptObject proto, final String key) {
+        assert !isShared() : "proto SwitchPoint from a shared PropertyMap";
+
         if (proto == null) {
             return null;
         }
@@ -244,6 +235,8 @@
      * @param property {@link Property} to invalidate.
      */
     private void invalidateProtoGetSwitchPoint(final Property property) {
+        assert !isShared() : "proto invalidation on a shared PropertyMap";
+
         if (protoGetSwitches != null) {
             final String key = property.getKey();
             final SwitchPoint sp = protoGetSwitches.get(key);
@@ -258,17 +251,6 @@
     }
 
     /**
-     * Add a property to the map.
-     *
-     * @param property {@link Property} being added.
-     *
-     * @return New {@link PropertyMap} with {@link Property} added.
-     */
-    public PropertyMap newProperty(final Property property) {
-        return addProperty(property);
-    }
-
-    /**
      * Add a property to the map, re-binding its getters and setters,
      * if available, to a given receiver. This is typically the global scope. See
      * {@link ScriptObject#addBoundProperties(ScriptObject)}
@@ -278,23 +260,8 @@
      *
      * @return New {@link PropertyMap} with {@link Property} added.
      */
-    PropertyMap newPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
-        return newProperty(new AccessorProperty(property, bindTo));
-    }
-
-    /**
-     * Add a new accessor property to the map.
-     *
-     * @param key           {@link Property} key.
-     * @param propertyFlags {@link Property} flags.
-     * @param slot          {@link Property} slot.
-     * @param getter        {@link Property} get accessor method.
-     * @param setter        {@link Property} set accessor method.
-     *
-     * @return  New {@link PropertyMap} with {@link AccessorProperty} added.
-     */
-    public PropertyMap newProperty(final String key, final int propertyFlags, final int slot, final MethodHandle getter, final MethodHandle setter) {
-        return newProperty(new AccessorProperty(key, propertyFlags, slot, getter, setter));
+    PropertyMap addPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
+        return addProperty(new AccessorProperty(property, bindTo));
     }
 
     /**
@@ -496,6 +463,28 @@
     }
 
     /**
+     * Make this property map 'shared' one. Shared property map instances are
+     * process wide singleton objects. A shaped map should never be added as a listener
+     * to a proto object. Nor it should have history or proto history. A shared map
+     * is just a template that is meant to be duplicated before use. All nasgen initialized
+     * property maps are shared.
+     *
+     * @return this map after making it as shared
+     */
+    public PropertyMap setIsShared() {
+        assert !isListenerAdded() : "making PropertyMap shared after listener added";
+        assert protoHistory == null : "making PropertyMap shared after associating a proto with it";
+        if (Context.DEBUG) {
+            sharedCount++;
+        }
+
+        flags |= IS_SHARED;
+        // clear any history on this PropertyMap, won't be used.
+        history = null;
+        return this;
+    }
+
+    /**
      * Check for any configurable properties.
      *
      * @return {@code true} if any configurable.
@@ -561,6 +550,8 @@
      * @param newMap   {@link PropertyMap} associated with prototype.
      */
     private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
+        assert !isShared() : "proto history modified on a shared PropertyMap";
+
         if (protoHistory == null) {
             protoHistory = new WeakHashMap<>();
         }
@@ -575,6 +566,8 @@
      * @param newMap   Modified {@link PropertyMap}.
      */
     private void addToHistory(final Property property, final PropertyMap newMap) {
+        assert !isShared() : "history modified on a shared PropertyMap";
+
         if (!properties.isEmpty()) {
             if (history == null) {
                 history = new LinkedHashMap<>();
@@ -700,6 +693,15 @@
     }
 
     /**
+     * Check if this map shared or not.
+     *
+     * @return true if this map is shared.
+     */
+    public boolean isShared() {
+        return (flags & IS_SHARED) != 0;
+    }
+
+    /**
      * Test to see if {@link PropertyMap} is extensible.
      *
      * @return {@code true} if {@link PropertyMap} can be added to.
@@ -762,6 +764,8 @@
      * @return New {@link PropertyMap} with prototype changed.
      */
     PropertyMap changeProto(final ScriptObject oldProto, final ScriptObject newProto) {
+        assert !isShared() : "proto associated with a shared PropertyMap";
+
         if (oldProto == newProto) {
             return this;
         }
@@ -877,6 +881,8 @@
     // counters updated only in debug mode
     private static int count;
     private static int clonedCount;
+    private static int sharedCount;
+    private static int duplicatedCount;
     private static int historyHit;
     private static int protoInvalidations;
     private static int protoHistoryHit;
@@ -897,6 +903,20 @@
     }
 
     /**
+     * @return The number of maps that are shared.
+     */
+    public static int getSharedCount() {
+        return sharedCount;
+    }
+
+    /**
+     * @return The number of maps that are duplicated.
+     */
+    public static int getDuplicatedCount() {
+        return duplicatedCount;
+    }
+
+    /**
      * @return The number of times history was successfully used.
      */
     public static int getHistoryHit() {
--- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Mon Jul 08 18:43:41 2013 +0530
@@ -119,9 +119,15 @@
     /** Create a new class loaded for each compilation */
     public final boolean _loader_per_compile;
 
+    /** Do not support Java support extensions. */
+    public final boolean _no_java;
+
     /** Do not support non-standard syntax extensions. */
     public final boolean _no_syntax_extensions;
 
+    /** Do not support typed arrays. */
+    public final boolean _no_typed_arrays;
+
     /** Package to which generated class files are added */
     public final String  _package;
 
@@ -207,7 +213,9 @@
         _fx                   = options.getBoolean("fx");
         _lazy_compilation     = options.getBoolean("lazy.compilation");
         _loader_per_compile   = options.getBoolean("loader.per.compile");
+        _no_java              = options.getBoolean("no.java");
         _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
+        _no_typed_arrays      = options.getBoolean("no.typed.arrays");
         _package              = options.getString("package");
         _parse_only           = options.getBoolean("parse.only");
         _print_ast            = options.getBoolean("print.ast");
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Jul 08 18:43:41 2013 +0530
@@ -170,7 +170,7 @@
         }
 
         this.arrayData = ArrayData.EMPTY_ARRAY;
-        this.setMap(map == null ? PropertyMap.newMap(getClass()) : map);
+        this.setMap(map == null ? PropertyMap.newMap() : map);
     }
 
     /**
@@ -188,7 +188,7 @@
         }
 
         this.arrayData = ArrayData.EMPTY_ARRAY;
-        this.setMap(map == null ? PropertyMap.newMap(getClass()) : map);
+        this.setMap(map == null ? PropertyMap.newMap() : map);
         this.proto = proto;
 
         if (proto != null) {
@@ -213,7 +213,7 @@
                     final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
                     newMap = newMap.addProperty(prop);
                 } else {
-                    newMap = newMap.newPropertyBind((AccessorProperty)property, source);
+                    newMap = newMap.addPropertyBind((AccessorProperty)property, source);
                 }
             }
         }
@@ -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/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Mon Jul 08 18:43:41 2013 +0530
@@ -592,6 +592,8 @@
                 throw typeError("cant.get.property", safeToString(property), "null");
             } else if (JSType.isPrimitive(obj)) {
                 obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property);
+            } else if (obj instanceof ScriptObjectMirror) {
+                obj = ((ScriptObjectMirror)obj).getMember(property.toString());
             } else {
                 obj = UNDEFINED;
             }
@@ -601,23 +603,6 @@
     }
 
     /**
-     * ECMA 11.4.2 - void operator
-     *
-     * @param object object to evaluate
-     *
-     * @return Undefined as the object type
-     */
-    public static Object VOID(final Object object) {
-        if (object instanceof Number) {
-            if (Double.isNaN(((Number)object).doubleValue())) {
-                return Double.NaN;
-            }
-        }
-
-        return UNDEFINED;
-    }
-
-    /**
      * Throw ReferenceError when LHS of assignment or increment/decrement
      * operator is not an assignable node (say a literal)
      *
--- a/src/jdk/nashorn/internal/runtime/StructureLoader.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/StructureLoader.java	Mon Jul 08 18:43:41 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/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java	Mon Jul 08 18:43:41 2013 +0530
@@ -146,7 +146,7 @@
 
     @Override
     public ArrayData setEmpty(final long lo, final long hi) {
-        Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, (long)Integer.MAX_VALUE), ScriptRuntime.EMPTY);
+        Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, Integer.MAX_VALUE), ScriptRuntime.EMPTY);
         return this;
     }
 
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Mon Jul 08 18:43:41 2013 +0530
@@ -78,7 +78,7 @@
      * @return CallSite with MethodHandle to appropriate method or null if not found.
      */
     public static CallSite bootstrap(final Lookup lookup, final String opDesc, final MethodType type, final int flags) {
-        return dynamicLinker.link(LinkerCallSite.newLinkerCallSite(opDesc, type, flags));
+        return dynamicLinker.link(LinkerCallSite.newLinkerCallSite(lookup, opDesc, type, flags));
     }
 
     /**
@@ -94,12 +94,12 @@
         return new RuntimeCallSite(type, initialName);
     }
 
-
     /**
-     * Returns a dynamic invoker for a specified dynamic operation. You can use this method to create a method handle
-     * that when invoked acts completely as if it were a Nashorn-linked call site. An overview of available dynamic
-     * operations can be found in the <a href="https://github.com/szegedi/dynalink/wiki/User-Guide-0.4">Dynalink User Guide</a>,
-     * but we'll show few examples here:
+     * Returns a dynamic invoker for a specified dynamic operation using the public lookup. You can use this method to
+     * create a method handle that when invoked acts completely as if it were a Nashorn-linked call site. An overview of
+     * available dynamic operations can be found in the
+     * <a href="https://github.com/szegedi/dynalink/wiki/User-Guide-0.6">Dynalink User Guide</a>, but we'll show few
+     * examples here:
      * <ul>
      *   <li>Get a named property with fixed name:
      *     <pre>
@@ -196,7 +196,7 @@
     }
 
     /**
-     * Returns a dynamic invoker for a specified dynamic operation. Similar to
+     * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to
      * {@link #createDynamicInvoker(String, Class, Class...)} but with return and parameter types composed into a
      * method type in the signature. See the discussion of that method for details.
      * @param opDesc Dynalink dynamic operation descriptor.
@@ -204,7 +204,7 @@
      * @return MethodHandle for invoking the operation.
      */
     public static MethodHandle createDynamicInvoker(final String opDesc, final MethodType type) {
-        return bootstrap(null, opDesc, type, 0).dynamicInvoker();
+        return bootstrap(MethodHandles.publicLookup(), opDesc, type, 0).dynamicInvoker();
     }
 
     /**
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Mon Jul 08 18:43:41 2013 +0530
@@ -28,6 +28,7 @@
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
@@ -39,7 +40,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.internal.dynalink.support.LinkRequestImpl;
 import jdk.nashorn.internal.objects.NativeJava;
@@ -119,9 +119,12 @@
         return AccessController.doPrivileged(new PrivilegedExceptionAction<MethodHandle>() {
             @Override
             public MethodHandle run() throws Exception {
-                return  MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get(
-                    "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
-                    adapterClass, null)).getInvocation(), adapterClass);
+                // NOTE: we use publicLookup(), but none of our adapter constructors are caller sensitive, so this is
+                // okay, we won't artificially limit access.
+                return  MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
+                        NashornCallSiteDescriptor.get(MethodHandles.publicLookup(),  "dyn:new",
+                                MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
+                                adapterClass, null)).getInvocation(), adapterClass);
             }
         });
     }
--- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Mon Jul 08 18:43:41 2013 +0530
@@ -25,7 +25,6 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.io.FileNotFoundException;
@@ -47,6 +46,7 @@
 import jdk.internal.dynalink.ChainedCallSite;
 import jdk.internal.dynalink.DynamicLinker;
 import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.Debug;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -79,8 +79,9 @@
      * @param flags    Call site specific flags.
      * @return New LinkerCallSite.
      */
-    static LinkerCallSite newLinkerCallSite(final String name, final MethodType type, final int flags) {
-        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(name, type, flags);
+    static LinkerCallSite newLinkerCallSite(final MethodHandles.Lookup lookup, final String name, final MethodType type,
+            final int flags) {
+        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(lookup, name, type, flags);
 
         if (desc.isProfile()) {
             return ProfilingLinkerCallSite.newProfilingLinkerCallSite(desc);
--- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Mon Jul 08 18:43:41 2013 +0530
@@ -25,9 +25,12 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
-import java.lang.ref.WeakReference;
-import java.util.WeakHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
@@ -70,9 +73,15 @@
      * set. */
     public static final int CALLSITE_TRACE_SCOPE      = 0x200;
 
-    private static final WeakHashMap<NashornCallSiteDescriptor, WeakReference<NashornCallSiteDescriptor>> canonicals =
-            new WeakHashMap<>();
+    private static final ClassValue<ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor>> canonicals =
+            new ClassValue<ConcurrentMap<NashornCallSiteDescriptor,NashornCallSiteDescriptor>>() {
+        @Override
+        protected ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> computeValue(Class<?> type) {
+            return new ConcurrentHashMap<>();
+        }
+    };
 
+    private final MethodHandles.Lookup lookup;
     private final String operator;
     private final String operand;
     private final MethodType methodType;
@@ -81,39 +90,35 @@
     /**
      * Retrieves a Nashorn call site descriptor with the specified values. Since call site descriptors are immutable
      * this method is at liberty to retrieve canonicalized instances (although it is not guaranteed it will do so).
+     * @param lookup the lookup describing the script
      * @param name the name at the call site, e.g. {@code "dyn:getProp|getElem|getMethod:color"}.
      * @param methodType the method type at the call site
      * @param flags Nashorn-specific call site flags
      * @return a call site descriptor with the specified values.
      */
-    public static NashornCallSiteDescriptor get(final String name, final MethodType methodType, final int flags) {
+    public static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String name,
+            final MethodType methodType, final int flags) {
         final String[] tokenizedName = CallSiteDescriptorFactory.tokenizeName(name);
         assert tokenizedName.length == 2 || tokenizedName.length == 3;
         assert "dyn".equals(tokenizedName[0]);
         assert tokenizedName[1] != null;
         // TODO: see if we can move mangling/unmangling into Dynalink
-        return get(tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
+        return get(lookup, tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
                 methodType, flags);
     }
 
-    private static NashornCallSiteDescriptor get(final String operator, final String operand, final MethodType methodType, final int flags) {
-        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(operator, operand, methodType, flags);
+    private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String operator, final String operand, final MethodType methodType, final int flags) {
+        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operator, operand, methodType, flags);
         // Many of these call site descriptors are identical (e.g. every getter for a property color will be
-        // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them in a weak map
-        synchronized(canonicals) {
-            final WeakReference<NashornCallSiteDescriptor> ref = canonicals.get(csd);
-            if(ref != null) {
-                final NashornCallSiteDescriptor canonical = ref.get();
-                if(canonical != null) {
-                    return canonical;
-                }
-            }
-            canonicals.put(csd, new WeakReference<>(csd));
-        }
-        return csd;
+        // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them.
+        final Map<NashornCallSiteDescriptor, NashornCallSiteDescriptor> classCanonicals = canonicals.get(lookup.lookupClass());
+        final NashornCallSiteDescriptor canonical = classCanonicals.putIfAbsent(csd, csd);
+        return canonical != null ? canonical : csd;
     }
 
-    private NashornCallSiteDescriptor(final String operator, final String operand, final MethodType methodType, final int flags) {
+    private NashornCallSiteDescriptor(final MethodHandles.Lookup lookup, final String operator, final String operand,
+            final MethodType methodType, final int flags) {
+        this.lookup = lookup;
         this.operator = operator;
         this.operand = operand;
         this.methodType = methodType;
@@ -142,6 +147,11 @@
     }
 
     @Override
+    public Lookup getLookup() {
+        return lookup;
+    }
+
+    @Override
     public boolean equals(final CallSiteDescriptor csd) {
         return super.equals(csd) && flags == getFlags(csd);
     }
@@ -279,6 +289,6 @@
 
     @Override
     public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
-        return get(operator, operand, newMethodType, flags);
+        return get(getLookup(), operator, operand, newMethodType, flags);
     }
 }
--- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Mon Jul 08 18:43:41 2013 +0530
@@ -50,6 +50,7 @@
 parser.error.no.func.decl.here.warn=Function declarations should only occur at program or function body level. Function declaration in nested block was converted to a function expression.
 parser.error.property.redefinition=Property "{0}" already defined
 parser.error.unexpected.token=Unexpected token: {0}
+parser.error.for.each.without.in=for each can only be used with for..in
 parser.error.many.vars.in.for.in.loop=Only one variable allowed in for..in loop
 parser.error.not.lvalue.for.in.loop=Invalid left side value of for..in loop
 parser.error.missing.catch.or.finally=Missing catch or finally after try
--- a/src/jdk/nashorn/internal/runtime/resources/Options.properties	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties	Mon Jul 08 18:43:41 2013 +0530
@@ -192,6 +192,14 @@
     default=true                                   \
 }
 
+nashorn.option.no.java = {                         \
+    name="--no-java",                              \
+    short_name="-nj",                              \
+    is_undocumented=true,                          \
+    desc="No Java support",                        \
+    default=false                                  \
+}
+
 nashorn.option.no.syntax.extensions = {            \
     name="--no-syntax-extensions",                 \
     short_name="-nse",                             \
@@ -200,6 +208,14 @@
     default=false                                  \
 }
 
+nashorn.option.no.typed.arrays = {                 \
+    name="--no-typed-arrays",                      \
+    short_name="-nta",                             \
+    is_undocumented=true,                          \
+    desc="No Typed arrays support",                \
+    default=false                                  \
+}
+
 nashorn.option.package = {                                     \
     name="--package",                                          \
     is_undocumented=true,                                      \
--- a/src/jdk/nashorn/internal/scripts/JO.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/internal/scripts/JO.java	Mon Jul 08 18:43:41 2013 +0530
@@ -33,13 +33,14 @@
  */
 public class JO extends ScriptObject {
 
-    private static final PropertyMap map$ = PropertyMap.newMap(JO.class);
+    private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
 
     /**
-     * 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/src/jdk/nashorn/tools/Shell.java	Fri Jul 05 11:05:50 2013 -0700
+++ b/src/jdk/nashorn/tools/Shell.java	Mon Jul 08 18:43:41 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;
@@ -434,6 +435,10 @@
                     break;
                 }
 
+                if (source.isEmpty()) {
+                    continue;
+                }
+
                 Object res;
                 try {
                     res = context.eval(global, source, global, "<shell>", env._strict);
@@ -446,7 +451,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/test/script/basic/JDK-8010946-2.js	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,38 @@
+/*
+ * 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-8010946: AccessController.doPrivileged() doesn't work as expected.
+ * This is actually a broader issue of having Dynalink correctly handle
+ * caller-sensitive methods.
+ *
+ * @test
+ * @run
+ */
+
+// Ensure these are CallerSensitiveDynamicMethods
+print(java.security.AccessController["doPrivileged(PrivilegedAction)"])
+print(java.lang.Class["forName(String)"])
+
+// Ensure this is not
+print(java.lang.String["valueOf(char)"])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8010946-2.js.EXPECTED	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,3 @@
+[jdk.internal.dynalink.beans.CallerSensitiveDynamicMethod Object java.security.AccessController.doPrivileged(PrivilegedAction)]
+[jdk.internal.dynalink.beans.CallerSensitiveDynamicMethod Class java.lang.Class.forName(String)]
+[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.valueOf(char)]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8010946-privileged.js	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,47 @@
+/*
+ * 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-8010946: AccessController.doPrivileged() doesn't work as expected.
+ * This is actually a broader issue of having Dynalink correctly handle
+ * caller-sensitive methods.
+ * 
+ * NOTE: This is not a standalone test file, it is loaded by JDK-801946.js
+ * @subtest
+ */
+
+(function() {
+    var getProperty = java.lang.System.getProperty
+    var doPrivileged = java.security.AccessController["doPrivileged(PrivilegedAction)"]
+
+    this.executeUnprivileged = function() {
+        var x = getProperty("java.security.policy")
+        if(x != null) {
+            print("Successfully retrieved restricted system property.")
+        }
+    }
+
+    this.executePrivileged = function() {
+        doPrivileged(executeUnprivileged)
+    }
+})();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8010946.js	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,51 @@
+/*
+ * 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-8010946: AccessController.doPrivileged() doesn't work as expected.
+ * This is actually a broader issue of having Dynalink correctly handle
+ * caller-sensitive methods.
+ *
+ * @test
+ * @run
+ */
+
+// This is unprivileged code that loads privileged code.
+load(__DIR__ + "JDK-8010946-privileged.js")
+
+try {
+    // This should fail, even though the code itself resides in the 
+    // privileged script, as we're invoking it without going through
+    // doPrivileged()
+    print("Attempting unprivileged execution...")
+    executeUnprivileged()
+    print("FAIL: Unprivileged execution succeeded!")
+} catch(e) {
+    print("Unprivileged execution failed with " + e)
+}
+
+print()
+
+// This should succeed, as it's going through doPrivileged().
+print("Attempting privileged execution...")
+executePrivileged()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8010946.js.EXPECTED	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,5 @@
+Attempting unprivileged execution...
+Unprivileged execution failed with java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.security.policy" "read")
+
+Attempting privileged execution...
+Successfully retrieved restricted system property.
--- a/test/script/basic/JDK-8016667.js	Fri Jul 05 11:05:50 2013 -0700
+++ b/test/script/basic/JDK-8016667.js	Mon Jul 08 18:43:41 2013 +0530
@@ -32,3 +32,23 @@
     var friends = 1;
     (joe = friends) == null;
 } 
+
+//JDK-8019476 duplicate case of this
+Function("with(\nnull == (this % {}))( /x/g );"); 
+
+function f() {
+    with(null == (this % {}))(/x/g);
+}
+
+Function("return (null != [,,] <= this);"); 
+
+function f2() {
+    return (null != [,,] <= this);
+}
+
+Function("/*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }"); 
+
+function f3() {
+    /*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8017084.js	Mon Jul 08 18:43:41 2013 +0530
@@ -0,0 +1,17625 @@
+/*
+ * 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-8017084: Use spill properties for large object literals
+ *
+ * @test
+ * @run
+ */
+
+var x = {
+    a: 1,
+    b: 2,
+    c: 3,
+    d: 4,
+    e: 5,
+    f: 6,
+    g: 7,
+    h: 8,
+    i: 9,
+    j: 10,
+    k: 11,
+    l: 12,
+    m: 13,
+    n: 14,
+    o: 15,
+    p: 16,
+    q: 17,
+    r: 18,
+    s: 19,
+    t: 20,
+    u: 21,
+    v: 22,
+    w: 23,
+    x: 24,
+    y: 25,
+    az: 26,
+    aa: 27,
+    ab: 28,
+    ac: 29,
+    ad: 30,
+    ae: 31,
+    af: 32,
+    ag: 33,
+    ah: 34,
+    ai: 35,
+    aj: 36,
+    ak: 37,
+    al: 38,
+    am: 39,
+    an: 40,
+    ao: 41,
+    ap: 42,
+    aq: 43,
+    ar: 44,
+    as: 45,
+    at: 46,
+    au: 47,
+    av: 48,
+    aw: 49,
+    ax: 50,
+    ay: 51,
+    bz: 52,
+    ba: 53,
+    bb: 54,
+    bc: 55,
+    bd: 56,
+    be: 57,
+    bf: 58,
+    bg: 59,
+    bh: 60,
+    bi: 61,
+    bj: 62,
+    bk: 63,
+    bl: 64,
+    bm: 65,
+    bn: 66,
+    bo: 67,
+    bp: 68,
+    bq: 69,
+    br: 70,
+    bs: 71,
+    bt: 72,
+    bu: 73,
+    bv: 74,
+    bw: 75,
+    bx: 76,
+    by: 77,
+    cz: 78,
+    ca: 79,
+    cb: 80,
+    cc: 81,
+    cd: 82,
+    ce: 83,
+    cf: 84,
+    cg: 85,
+    ch: 86,
+    ci: 87,
+    cj: 88,
+    ck: 89,
+    cl: 90,
+    cm: 91,
+    cn: 92,
+    co: 93,
+    cp: 94,
+    cq: 95,
+    cr: 96,
+    cs: 97,
+    ct: 98,
+    cu: 99,
+    cv: 100,
+    cw: 101,
+    cx: 102,
+    cy: 103,
+    dz: 104,
+    da: 105,
+    db: 106,
+    dc: 107,
+    dd: 108,
+    de: 109,
+    df: 110,
+    dg: 111,
+    dh: 112,
+    di: 113,
+    dj: 114,
+    dk: 115,
+    dl: 116,
+    dm: 117,
+    dn: 118,
+    do: 119,
+    dp: 120,
+    dq: 121,
+    dr: 122,
+    ds: 123,
+    dt: 124,
+    du: 125,
+    dv: 126,
+    dw: 127,
+    dx: 128,
+    dy: 129,
+    ez: 130,
+    ea: 131,
+    eb: 132,
+    ec: 133,
+    ed: 134,
+    ee: 135,
+    ef: 136,
+    eg: 137,
+    eh: 138,
+    ei: 139,
+    ej: 140,
+    ek: 141,
+    el: 142,
+    em: 143,
+    en: 144,
+    eo: 145,
+    ep: 146,
+    eq: 147,
+    er: 148,
+    es: 149,
+    et: 150,
+    eu: 151,
+    ev: 152,
+    ew: 153,
+    ex: 154,
+    ey: 155,
+    fz: 156,
+    fa: 157,
+    fb: 158,
+    fc: 159,
+    fd: 160,
+    fe: 161,
+    ff: 162,
+    fg: 163,
+    fh: 164,
+    fi: 165,
+    fj: 166,
+    fk: 167,
+    fl: 168,
+    fm: 169,
+    fn: 170,
+    fo: 171,
+    fp: 172,
+    fq: 173,
+    fr: 174,
+    fs: 175,
+    ft: 176,
+    fu: 177,
+    fv: 178,
+    fw: 179,
+    fx: 180,
+    fy: 181,
+    gz: 182,
+    ga: 183,
+    gb: 184,
+    gc: 185,
+    gd: 186,
+    ge: 187,
+    gf: 188,
+    gg: 189,
+    gh: 190,
+    gi: 191,
+    gj: 192,
+    gk: 193,
+    gl: 194,
+    gm: 195,
+    gn: 196,
+    go: 197,
+    gp: 198,
+    gq: 199,
+    gr: 200,
+    gs: 201,
+    gt: 202,
+    gu: 203,
+    gv: 204,
+    gw: 205,
+    gx: 206,
+    gy: 207,
+    hz: 208,
+    ha: 209,
+    hb: 210,
+    hc: 211,
+    hd: 212,
+    he: 213,
+    hf: 214,
+    hg: 215,
+    hh: 216,
+    hi: 217,
+    hj: 218,
+    hk: 219,
+    hl: 220,
+    hm: 221,
+    hn: 222,
+    ho: 223,
+    hp: 224,
+    hq: 225,
+    hr: 226,
+    hs: 227,
+    ht: 228,
+    hu: 229,
+    hv: 230,
+    hw: 231,
+    hx: 232,
+    hy: 233,
+    iz: 234,
+    ia: 235,
+    ib: 236,
+    ic: 237,
+    id: 238,
+    ie: 239,
+    if: 240,
+    ig: 241,
+    ih: 242,
+    ii: 243,
+    ij: 244,
+    ik: 245,
+    il: 246,
+    im: 247,
+    in: 248,
+    io: 249,
+    ip: 250,
+    iq: 251,
+    ir: 252,
+    is: 253,
+    it: 254,
+    iu: 255,
+    iv: 256,
+    iw: 257,
+    ix: 258,
+    iy: 259,
+    jz: 260,
+    ja: 261,
+    jb: 262,
+    jc: 263,
+    jd: 264,
+    je: 265,
+    jf: 266,
+    jg: 267,
+    jh: 268,
+    ji: 269,
+    jj: 270,
+    jk: 271,
+    jl: 272,
+    jm: 273,
+    jn: 274,
+    jo: 275,
+    jp: 276,
+    jq: 277,
+    jr: 278,
+    js: 279,
+    jt: 280,
+    ju: 281,
+    jv: 282,
+    jw: 283,
+    jx: 284,
+    jy: 285,
+    kz: 286,
+    ka: 287,
+    kb: 288,
+    kc: 289,
+    kd: 290,
+    ke: 291,
+    kf: 292,
+    kg: 293,
+    kh: 294,
+    ki: 295,
+    kj: 296,
+    kk: 297,
+    kl: 298,
+    km: 299,
+    kn: 300,
+    ko: 301,
+    kp: 302,
+    kq: 303,
+    kr: 304,
+    ks: 305,
+    kt: 306,
+    ku: 307,
+    kv: 308,
+    kw: 309,
+    kx: 310,
+    ky: 311,
+    lz: 312,
+    la: 313,
+    lb: 314,
+    lc: 315,
+    ld: 316,
+    le: 317,
+    lf: 318,
+    lg: 319,
+    lh: 320,
+    li: 321,
+    lj: 322,
+    lk: 323,
+    ll: 324,
+    lm: 325,
+    ln: 326,
+    lo: 327,
+    lp: 328,
+    lq: 329,
+    lr: 330,
+    ls: 331,
+    lt: 332,
+    lu: 333,
+    lv: 334,
+    lw: 335,
+    lx: 336,
+    ly: 337,
+    mz: 338,
+    ma: 339,
+    mb: 340,
+    mc: 341,
+    md: 342,
+    me: 343,
+    mf: 344,
+    mg: 345,
+    mh: 346,
+    mi: 347,
+    mj: 348,
+    mk: 349,
+    ml: 350,
+    mm: 351,
+    mn: 352,
+    mo: 353,
+    mp: 354,
+    mq: 355,
+    mr: 356,
+    ms: 357,
+    mt: 358,
+    mu: 359,
+    mv: 360,
+    mw: 361,
+    mx: 362,
+    my: 363,
+    nz: 364,
+    na: 365,
+    nb: 366,
+    nc: 367,
+    nd: 368,
+    ne: 369,
+    nf: 370,
+    ng: 371,
+    nh: 372,
+    ni: 373,
+    nj: 374,
+    nk: 375,
+    nl: 376,
+    nm: 377,
+    nn: 378,
+    no: 379,
+    np: 380,
+    nq: 381,
+    nr: 382,
+    ns: 383,
+    nt: 384,
+    nu: 385,
+    nv: 386,
+    nw: 387,
+    nx: 388,
+    ny: 389,
+    oz: 390,
+    oa: 391,
+    ob: 392,
+    oc: 393,
+    od: 394,
+    oe: 395,
+    of: 396,
+    og: 397,
+    oh: 398,
+    oi: 399,
+    oj: 400,
+    ok: 401,
+    ol: 402,
+    om: 403,
+    on: 404,
+    oo: 405,
+    op: 406,
+    oq: 407,
+    or: 408,
+    os: 409,
+    ot: 410,
+    ou: 411,
+    ov: 412,
+    ow: 413,
+    ox: 414,
+    oy: 415,
+    pz: 416,
+    pa: 417,
+    pb: 418,
+    pc: 419,
+    pd: 420,
+    pe: 421,
+    pf: 422,
+    pg: 423,
+    ph: 424,
+    pi: 425,
+    pj: 426,
+    pk: 427,
+    pl: 428,
+    pm: 429,
+    pn: 430,
+    po: 431,
+    pp: 432,
+    pq: 433,
+    pr: 434,
+    ps: 435,
+    pt: 436,
+    pu: 437,
+    pv: 438,
+    pw: 439,
+    px: 440,
+    py: 441,
+    qz: 442,
+    qa: 443,
+    qb: 444,
+    qc: 445,
+    qd: 446,
+    qe: 447,
+    qf: 448,
+    qg: 449,
+    qh: 450,
+    qi: 451,
+    qj: 452,
+    qk: 453,
+    ql: 454,
+    qm: 455,
+    qn: 456,
+    qo: 457,
+    qp: 458,
+    qq: 459,
+    qr: 460,
+    qs: 461,
+    qt: 462,
+    qu: 463,
+    qv: 464,
+    qw: 465,
+    qx: 466,
+    qy: 467,
+    rz: 468,
+    ra: 469,
+    rb: 470,
+    rc: 471,
+    rd: 472,
+    re: 473,
+    rf: 474,
+    rg: 475,
+    rh: 476,
+    ri: 477,
+    rj: 478,
+    rk: 479,
+    rl: 480,
+    rm: 481,
+    rn: 482,
+    ro: 483,
+    rp: 484,
+    rq: 485,
+    rr: 486,
+    rs: 487,
+    rt: 488,
+    ru: 489,
+    rv: 490,
+    rw: 491,
+    rx: 492,
+    ry: 493,
+    sz: 494,
+    sa: 495,
+    sb: 496,
+    sc: 497,
+    sd: 498,
+    se: 499,
+    sf: 500,
+    sg: 501,
+    sh: 502,
+    si: 503,
+    sj: 504,
+    sk: 505,
+    sl: 506,
+    sm: 507,
+    sn: 508,
+    so: 509,
+    sp: 510,
+    sq: 511,
+    sr: 512,
+    ss: 513,
+    st: 514,
+    su: 515,
+    sv: 516,
+    sw: 517,
+    sx: 518,
+    sy: 519,
+    tz: 520,
+    ta: 521,
+    tb: 522,
+    tc: 523,
+    td: 524,
+    te: 525,
+    tf: 526,
+    tg: 527,
+    th: 528,
+    ti: 529,
+    tj: 530,
+    tk: 531,
+    tl: 532,
+    tm: 533,
+    tn: 534,
+    to: 535,
+    tp: 536,
+    tq: 537,
+    tr: 538,
+    ts: 539,
+    tt: 540,
+    tu: 541,
+    tv: 542,
+    tw: 543,
+    tx: 544,
+    ty: 545,
+    uz: 546,
+    ua: 547,
+    ub: 548,
+    uc: 549,
+    ud: 550,
+    ue: 551,
+    uf: 552,
+    ug: 553,
+    uh: 554,
+    ui: 555,
+    uj: 556,
+    uk: 557,
+    ul: 558,
+    um: 559,
+    un: 560,
+    uo: 561,
+    up: 562,
+    uq: 563,
+    ur: 564,
+    us: 565,
+    ut: 566,
+    uu: 567,
+    uv: 568,
+    uw: 569,
+    ux: 570,
+    uy: 571,
+    vz: 572,
+    va: 573,
+    vb: 574,
+    vc: 575,
+    vd: 576,
+    ve: 577,
+    vf: 578,
+    vg: 579,
+    vh: 580,
+    vi: 581,
+    vj: 582,
+    vk: 583,
+    vl: 584,
+    vm: 585,
+    vn: 586,
+    vo: 587,
+    vp: 588,
+    vq: 589,
+    vr: 590,
+    vs: 591,
+    vt: 592,
+    vu: 593,
+    vv: 594,
+    vw: 595,
+    vx: 596,
+    vy: 597,
+    wz: 598,
+    wa: 599,
+    wb: 600,
+    wc: 601,
+    wd: 602,
+    we: 603,
+    wf: 604,
+    wg: 605,
+    wh: 606,
+    wi: 607,
+    wj: 608,
+    wk: 609,
+    wl: 610,
+    wm: 611,
+    wn: 612,
+    wo: 613,
+    wp: 614,
+    wq: 615,
+    wr: 616,
+    ws: 617,
+    wt: 618,
+    wu: 619,
+    wv: 620,
+    ww: 621,
+    wx: 622,
+    wy: 623,
+    xz: 624,
+    xa: 625,
+    xb: 626,
+    xc: 627,
+    xd: 628,
+    xe: 629,
+    xf: 630,
+    xg: 631,
+    xh: 632,
+    xi: 633,
+    xj: 634,
+    xk: 635,
+    xl: 636,
+    xm: 637,
+    xn: 638,
+    xo: 639,
+    xp: 640,
+    xq: 641,
+    xr: 642,
+    xs: 643,
+    xt: 644,
+    xu: 645,
+    xv: 646,
+    xw: 647,
+    xx: 648,
+    xy: 649,
+    yz: 650,
+    ya: 651,
+    yb: 652,
+    yc: 653,
+    yd: 654,
+    ye: 655,
+    yf: 656,
+    yg: 657,
+    yh: 658,
+    yi: 659,
+    yj: 660,
+    yk: 661,
+    yl: 662,
+    ym: 663,
+    yn: 664,
+    yo: 665,
+    yp: 666,
+    yq: 667,
+    yr: 668,
+    ys: 669,
+    yt: 670,
+    yu: 671,
+    yv: 672,
+    yw: 673,
+    yx: 674,
+    yy: 675,
+    azz: 676,
+    aza: 677,
+    azb: 678,
+    azc: 679,
+    azd: 680,
+    aze: 681,
+    azf: 682,
+    azg: 683,
+    azh: 684,
+    azi: 685,
+    azj: 686,
+    azk: 687,
+    azl: 688,
+    azm: 689,
+    azn: 690,
+    azo: 691,
+    azp: 692,
+    azq: 693,
+    azr: 694,
+    azs: 695,
+    azt: 696,
+    azu: 697,
+    azv: 698,
+    azw: 699,
+    azx: 700,
+    azy: 701,
+    aaz: 702,
+    aaa: 703,
+    aab: 704,
+    aac: 705,
+    aad: 706,
+    aae: 707,
+    aaf: 708,
+    aag: 709,
+    aah: 710,
+    aai: 711,
+    aaj: 712,
+    aak: 713,
+    aal: 714,
+    aam: 715,
+    aan: 716,
+    aao: 717,
+    aap: 718,
+    aaq: 719,
+    aar: 720,
+    aas: 721,
+    aat: 722,
+    aau: 723,
+    aav: 724,
+    aaw: 725,
+    aax: 726,
+    aay: 727,
+    abz: 728,
+    aba: 729,
+    abb: 730,
+    abc: 731,
+    abd: 732,
+    abe: 733,
+    abf: 734,
+    abg: 735,
+    abh: 736,
+    abi: 737,
+    abj: 738,
+    abk: 739,
+    abl: 740,
+    abm: 741,
+    abn: 742,
+    abo: 743,
+    abp: 744,
+    abq: 745,
+    abr: 746,
+    abs: 747,
+    abt: 748,
+    abu: 749,
+    abv: 750,
+    abw: 751,
+    abx: 752,
+    aby: 753,
+    acz: 754,
+    aca: 755,
+    acb: 756,
+    acc: 757,
+    acd: 758,
+    ace: 759,
+    acf: 760,
+    acg: 761,
+    ach: 762,
+    aci: 763,
+    acj: 764,
+    ack: 765,
+    acl: 766,
+    acm: 767,
+    acn: 768,
+    aco: 769,
+    acp: 770,
+    acq: 771,
+    acr: 772,
+    acs: 773,
+    act: 774,
+    acu: 775,
+    acv: 776,
+    acw: 777,
+    acx: 778,
+    acy: 779,
+    adz: 780,
+    ada: 781,
+    adb: 782,
+    adc: 783,
+    add: 784,
+    ade: 785,
+    adf: 786,
+    adg: 787,
+    adh: 788,
+    adi: 789,
+    adj: 790,
+    adk: 791,
+    adl: 792,
+    adm: 793,
+    adn: 794,
+    ado: 795,
+    adp: 796,
+    adq: 797,
+    adr: 798,
+    ads: 799,
+    adt: 800,
+    adu: 801,
+    adv: 802,
+    adw: 803,
+    adx: 804,
+    ady: 805,
+    aez: 806,
+    aea: 807,
+    aeb: 808,
+    aec: 809,
+    aed: 810,
+    aee: 811,
+    aef: 812,
+    aeg: 813,
+    aeh: 814,
+    aei: 815,
+    aej: 816,
+    aek: 817,
+    ael: 818,
+    aem: 819,
+    aen: 820,
+    aeo: 821,
+    aep: 822,
+    aeq: 823,
+    aer: 824,
+    aes: 825,
+    aet: 826,
+    aeu: 827,
+    aev: 828,
+    aew: 829,
+    aex: 830,
+    aey: 831,
+    afz: 832,
+    afa: 833,
+    afb: 834,
+    afc: 835,
+    afd: 836,
+    afe: 837,
+    aff: 838,
+    afg: 839,
+    afh: 840,
+    afi: 841,
+    afj: 842,
+    afk: 843,
+    afl: 844,
+    afm: 845,
+    afn: 846,
+    afo: 847,
+    afp: 848,
+    afq: 849,
+    afr: 850,
+    afs: 851,
+    aft: 852,
+    afu: 853,
+    afv: 854,
+    afw: 855,
+    afx: 856,
+    afy: 857,
+    agz: 858,
+    aga: 859,
+    agb: 860,
+    agc: 861,
+    agd: 862,
+    age: 863,
+    agf: 864,
+    agg: 865,
+    agh: 866,
+    agi: 867,
+    agj: 868,
+    agk: 869,
+    agl: 870,
+    agm: 871,
+    agn: 872,
+    ago: 873,
+    agp: 874,
+    agq: 875,
+    agr: 876,
+    ags: 877,
+    agt: 878,
+    agu: 879,
+    agv: 880,
+    agw: 881,
+    agx: 882,
+    agy: 883,
+    ahz: 884,
+    aha: 885,
+    ahb: 886,
+    ahc: 887,
+    ahd: 888,
+    ahe: 889,
+    ahf: 890,
+    ahg: 891,
+    ahh: 892,
+    ahi: 893,
+    ahj: 894,
+    ahk: 895,
+    ahl: 896,
+    ahm: 897,
+    ahn: 898,
+    aho: 899,
+    ahp: 900,
+    ahq: 901,
+    ahr: 902,
+    ahs: 903,
+    aht: 904,
+    ahu: 905,
+    ahv: 906,
+    ahw: 907,
+    ahx: 908,
+    ahy: 909,
+    aiz: 910,
+    aia: 911,
+    aib: 912,
+    aic: 913,
+    aid: 914,
+    aie: 915,
+    aif: 916,
+    aig: 917,
+    aih: 918,
+    aii: 919,
+    aij: 920,
+    aik: 921,
+    ail: 922,
+    aim: 923,
+    ain: 924,
+    aio: 925,
+    aip: 926,
+    aiq: 927,
+    air: 928,
+    ais: 929,
+    ait: 930,
+    aiu: 931,
+    aiv: 932,
+    aiw: 933,
+    aix: 934,
+    aiy: 935,
+    ajz: 936,
+    aja: 937,
+    ajb: 938,
+    ajc: 939,
+    ajd: 940,
+    aje: 941,
+    ajf: 942,
+    ajg: 943,
+    ajh: 944,
+    aji: 945,
+    ajj: 946,
+    ajk: 947,
+    ajl: 948,
+    ajm: 949,
+    ajn: 950,
+    ajo: 951,
+    ajp: 952,
+    ajq: 953,
+    ajr: 954,
+    ajs: 955,
+    ajt: 956,
+    aju: 957,
+    ajv: 958,
+    ajw: 959,
+    ajx: 960,
+    ajy: 961,
+    akz: 962,
+    aka: 963,
+    akb: 964,
+    akc: 965,
+    akd: 966,
+    ake: 967,
+    akf: 968,
+    akg: 969,
+    akh: 970,
+    aki: 971,
+    akj: 972,
+    akk: 973,
+    akl: 974,
+    akm: 975,
+    akn: 976,
+    ako: 977,
+    akp: 978,
+    akq: 979,
+    akr: 980,
+    aks: 981,
+    akt: 982,
+    aku: 983,
+    akv: 984,
+    akw: 985,
+    akx: 986,
+    aky: 987,
+    alz: 988,
+    ala: 989,
+    alb: 990,
+    alc: 991,
+    ald: 992,
+    ale: 993,
+    alf: 994,
+    alg: 995,
+    alh: 996,
+    ali: 997,
+    alj: 998,
+    alk: 999,
+    all: 1000,
+    alm: 1001,
+    aln: 1002,
+    alo: 1003,
+    alp: 1004,
+    alq: 1005,
+    alr: 1006,
+    als: 1007,
+    alt: 1008,
+    alu: 1009,
+    alv: 1010,
+    alw: 1011,
+    alx: 1012,
+    aly: 1013,
+    amz: 1014,
+    ama: 1015,
+    amb: 1016,
+    amc: 1017,
+    amd: 1018,
+    ame: 1019,
+    amf: 1020,
+    amg: 1021,
+    amh: 1022,
+    ami: 1023,
+    amj: 1024,
+    amk: 1025,
+    aml: 1026,
+    amm: 1027,
+    amn: 1028,
+    amo: 1029,
+    amp: 1030,
+    amq: 1031,
+    amr: 1032,
+    ams: 1033,
+    amt: 1034,
+    amu: 1035,
+    amv: 1036,
+    amw: 1037,
+    amx: 1038,
+    amy: 1039,
+    anz: 1040,
+    ana: 1041,
+    anb: 1042,
+    anc: 1043,
+    and: 1044,
+    ane: 1045,
+    anf: 1046,
+    ang: 1047,
+    anh: 1048,
+    ani: 1049,
+    anj: 1050,
+    ank: 1051,
+    anl: 1052,
+    anm: 1053,
+    ann: 1054,
+    ano: 1055,
+    anp: 1056,
+    anq: 1057,
+    anr: 1058,
+    ans: 1059,
+    ant: 1060,
+    anu: 1061,
+    anv: 1062,
+    anw: 1063,
+    anx: 1064,
+    any: 1065,
+    aoz: 1066,
+    aoa: 1067,
+    aob: 1068,
+    aoc: 1069,
+    aod: 1070,
+    aoe: 1071,
+    aof: 1072,
+    aog: 1073,
+    aoh: 1074,
+    aoi: 1075,
+    aoj: 1076,
+    aok: 1077,
+    aol: 1078,
+    aom: 1079,
+    aon: 1080,
+    aoo: 1081,
+    aop: 1082,
+    aoq: 1083,
+    aor: 1084,
+    aos: 1085,
+    aot: 1086,
+    aou: 1087,
+    aov: 1088,
+    aow: 1089,
+    aox: 1090,
+    aoy: 1091,
+    apz: 1092,
+    apa: 1093,
+    apb: 1094,
+    apc: 1095,
+    apd: 1096,
+    ape: 1097,
+    apf: 1098,
+    apg: 1099,
+    aph: 1100,
+    api: 1101,
+    apj: 1102,
+    apk: 1103,
+    apl: 1104,
+    apm: 1105,
+    apn: 1106,
+    apo: 1107,
+    app: 1108,
+    apq: 1109,
+    apr: 1110,
+    aps: 1111,
+    apt: 1112,
+    apu: 1113,
+    apv: 1114,
+    apw: 1115,
+    apx: 1116,
+    apy: 1117,
+    aqz: 1118,
+    aqa: 1119,
+    aqb: 1120,
+    aqc: 1121,
+    aqd: 1122,
+    aqe: 1123,
+    aqf: 1124,
+    aqg: 1125,
+    aqh: 1126,
+    aqi: 1127,
+    aqj: 1128,
+    aqk: 1129,
+    aql: 1130,
+    aqm: 1131,
+    aqn: 1132,
+    aqo: 1133,
+    aqp: 1134,
+    aqq: 1135,
+    aqr: 1136,
+    aqs: 1137,
+    aqt: 1138,
+    aqu: 1139,
+    aqv: 1140,
+    aqw: 1141,
+    aqx: 1142,
+    aqy: 1143,
+    arz: 1144,
+    ara: 1145,
+    arb: 1146,
+    arc: 1147,
+    ard: 1148,
+    are: 1149,
+    arf: 1150,
+    arg: 1151,
+    arh: 1152,
+    ari: 1153,
+    arj: 1154,
+    ark: 1155,
+    arl: 1156,
+    arm: 1157,
+    arn: 1158,
+    aro: 1159,
+    arp: 1160,
+    arq: 1161,
+    arr: 1162,
+    ars: 1163,
+    art: 1164,
+    aru: 1165,
+    arv: 1166,
+    arw: 1167,
+    arx: 1168,
+    ary: 1169,
+    asz: 1170,
+    asa: 1171,
+    asb: 1172,
+    asc: 1173,
+    asd: 1174,
+    ase: 1175,
+    asf: 1176,
+    asg: 1177,
+    ash: 1178,
+    asi: 1179,
+    asj: 1180,
+    ask: 1181,
+    asl: 1182,
+    asm: 1183,
+    asn: 1184,
+    aso: 1185,
+    asp: 1186,
+    asq: 1187,
+    asr: 1188,
+    ass: 1189,
+    ast: 1190,
+    asu: 1191,
+    asv: 1192,
+    asw: 1193,
+    asx: 1194,
+    asy: 1195,
+    atz: 1196,
+    ata: 1197,
+    atb: 1198,
+    atc: 1199,
+    atd: 1200,
+    ate: 1201,
+    atf: 1202,
+    atg: 1203,
+    ath: 1204,
+    ati: 1205,
+    atj: 1206,
+    atk: 1207,
+    atl: 1208,
+    atm: 1209,
+    atn: 1210,
+    ato: 1211,
+    atp: 1212,
+    atq: 1213,
+    atr: 1214,
+    ats: 1215,
+    att: 1216,
+    atu: 1217,
+    atv: 1218,
+    atw: 1219,
+    atx: 1220,
+    aty: 1221,
+    auz: 1222,
+    aua: 1223,
+    aub: 1224,
+    auc: 1225,
+    aud: 1226,
+    aue: 1227,
+    auf: 1228,
+    aug: 1229,
+    auh: 1230,
+    aui: 1231,
+    auj: 1232,
+    auk: 1233,
+    aul: 1234,
+    aum: 1235,
+    aun: 1236,
+    auo: 1237,
+    aup: 1238,
+    auq: 1239,
+    aur: 1240,
+    aus: 1241,
+    aut: 1242,
+    auu: 1243,
+    auv: 1244,
+    auw: 1245,
+    aux: 1246,
+    auy: 1247,
+    avz: 1248,
+    ava: 1249,
+    avb: 1250,
+    avc: 1251,
+    avd: 1252,
+    ave: 1253,
+    avf: 1254,
+    avg: 1255,
+    avh: 1256,
+    avi: 1257,
+    avj: 1258,
+    avk: 1259,
+    avl: 1260,
+    avm: 1261,
+    avn: 1262,
+    avo: 1263,
+    avp: 1264,
+    avq: 1265,
+    avr: 1266,
+    avs: 1267,
+    avt: 1268,
+    avu: 1269,
+    avv: 1270,
+    avw: 1271,
+    avx: 1272,
+    avy: 1273,
+    awz: 1274,
+    awa: 1275,
+    awb: 1276,
+    awc: 1277,
+    awd: 1278,
+    awe: 1279,
+    awf: 1280,
+    awg: 1281,
+    awh: 1282,
+    awi: 1283,
+    awj: 1284,
+    awk: 1285,
+    awl: 1286,
+    awm: 1287,
+    awn: 1288,
+    awo: 1289,
+    awp: 1290,
+    awq: 1291,
+    awr: 1292,
+    aws: 1293,
+    awt: 1294,
+    awu: 1295,
+    awv: 1296,
+    aww: 1297,
+    awx: 1298,
+    awy: 1299,
+    axz: 1300,
+    axa: 1301,
+    axb: 1302,
+    axc: 1303,
+    axd: 1304,
+    axe: 1305,
+    axf: 1306,
+    axg: 1307,
+    axh: 1308,
+    axi: 1309,
+    axj: 1310,
+    axk: 1311,
+    axl: 1312,
+    axm: 1313,
+    axn: 1314,
+    axo: 1315,
+    axp: 1316,
+    axq: 1317,
+    axr: 1318,
+    axs: 1319,
+    axt: 1320,
+    axu: 1321,
+    axv: 1322,
+    axw: 1323,
+    axx: 1324,
+    axy: 1325,
+    ayz: 1326,
+    aya: 1327,
+    ayb: 1328,
+    ayc: 1329,
+    ayd: 1330,
+    aye: 1331,
+    ayf: 1332,
+    ayg: 1333,
+    ayh: 1334,
+    ayi: 1335,
+    ayj: 1336,
+    ayk: 1337,
+    ayl: 1338,
+    aym: 1339,
+    ayn: 1340,
+    ayo: 1341,
+    ayp: 1342,
+    ayq: 1343,
+    ayr: 1344,
+    ays: 1345,
+    ayt: 1346,
+    ayu: 1347,
+    ayv: 1348,
+    ayw: 1349,
+    ayx: 1350,
+    ayy: 1351,
+    bzz: 1352,
+    bza: 1353,
+    bzb: 1354,
+    bzc: 1355,
+    bzd: 1356,
+    bze: 1357,
+    bzf: 1358,
+    bzg: 1359,
+    bzh: 1360,
+    bzi: 1361,
+    bzj: 1362,
+    bzk: 1363,
+    bzl: 1364,
+    bzm: 1365,
+    bzn: 1366,
+    bzo: 1367,
+    bzp: 1368,
+    bzq: 1369,
+    bzr: 1370,
+    bzs: 1371,
+    bzt: 1372,
+    bzu: 1373,
+    bzv: 1374,
+    bzw: 1375,
+    bzx: 1376,
+    bzy: 1377,
+    baz: 1378,
+    baa: 1379,
+    bab: 1380,
+    bac: 1381,
+    bad: 1382,
+    bae: 1383,
+    baf: 1384,
+    bag: 1385,
+    bah: 1386,
+    bai: 1387,
+    baj: 1388,
+    bak: 1389,
+    bal: 1390,
+    bam: 1391,
+    ban: 1392,
+    bao: 1393,
+    bap: 1394,
+    baq: 1395,
+    bar: 1396,
+    bas: 1397,
+    bat: 1398,
+    bau: 1399,
+    bav: 1400,
+    baw: 1401,
+    bax: 1402,
+    bay: 1403,
+    bbz: 1404,
+    bba: 1405,
+    bbb: 1406,
+    bbc: 1407,
+    bbd: 1408,
+    bbe: 1409,
+    bbf: 1410,
+    bbg: 1411,
+    bbh: 1412,
+    bbi: 1413,
+    bbj: 1414,
+    bbk: 1415,
+    bbl: 1416,
+    bbm: 1417,
+    bbn: 1418,
+    bbo: 1419,
+    bbp: 1420,
+    bbq: 1421,
+    bbr: 1422,
+    bbs: 1423,
+    bbt: 1424,
+    bbu: 1425,
+    bbv: 1426,
+    bbw: 1427,
+    bbx: 1428,
+    bby: 1429,
+    bcz: 1430,
+    bca: 1431,
+    bcb: 1432,
+    bcc: 1433,
+    bcd: 1434,
+    bce: 1435,
+    bcf: 1436,
+    bcg: 1437,
+    bch: 1438,
+    bci: 1439,
+    bcj: 1440,
+    bck: 1441,
+    bcl: 1442,
+    bcm: 1443,
+    bcn: 1444,
+    bco: 1445,
+    bcp: 1446,
+    bcq: 1447,
+    bcr: 1448,
+    bcs: 1449,
+    bct: 1450,
+    bcu: 1451,
+    bcv: 1452,
+    bcw: 1453,
+    bcx: 1454,
+    bcy: 1455,
+    bdz: 1456,
+    bda: 1457,
+    bdb: 1458,
+    bdc: 1459,
+    bdd: 1460,
+    bde: 1461,
+    bdf: 1462,
+    bdg: 1463,
+    bdh: 1464,
+    bdi: 1465,
+    bdj: 1466,
+    bdk: 1467,
+    bdl: 1468,
+    bdm: 1469,
+    bdn: 1470,
+    bdo: 1471,
+    bdp: 1472,
+    bdq: 1473,
+    bdr: 1474,
+    bds: 1475,
+    bdt: 1476,
+    bdu: 1477,
+    bdv: 1478,
+    bdw: 1479,
+    bdx: 1480,
+    bdy: 1481,
+    bez: 1482,
+    bea: 1483,
+    beb: 1484,
+    bec: 1485,
+    bed: 1486,
+    bee: 1487,
+    bef: 1488,
+    beg: 1489,
+    beh: 1490,
+    bei: 1491,
+    bej: 1492,
+    bek: 1493,
+    bel: 1494,
+    bem: 1495,
+    ben: 1496,
+    beo: 1497,
+    bep: 1498,
+    beq: 1499,
+    ber: 1500,
+    bes: 1501,
+    bet: 1502,
+    beu: 1503,
+    bev: 1504,
+    bew: 1505,
+    bex: 1506,
+    bey: 1507,
+    bfz: 1508,
+    bfa: 1509,
+    bfb: 1510,
+    bfc: 1511,
+    bfd: 1512,
+    bfe: 1513,
+    bff: 1514,
+    bfg: 1515,
+    bfh: 1516,
+    bfi: 1517,
+    bfj: 1518,
+    bfk: 1519,
+    bfl: 1520,
+    bfm: 1521,
+    bfn: 1522,
+    bfo: 1523,
+    bfp: 1524,
+    bfq: 1525,
+    bfr: 1526,
+    bfs: 1527,
+    bft: 1528,
+    bfu: 1529,
+    bfv: 1530,
+    bfw: 1531,
+    bfx: 1532,
+    bfy: 1533,
+    bgz: 1534,
+    bga: 1535,
+    bgb: 1536,
+    bgc: 1537,
+    bgd: 1538,
+    bge: 1539,
+    bgf: 1540,
+    bgg: 1541,
+    bgh: 1542,
+    bgi: 1543,
+    bgj: 1544,
+    bgk: 1545,
+    bgl: 1546,
+    bgm: 1547,
+    bgn: 1548,
+    bgo: 1549,
+    bgp: 1550,
+    bgq: 1551,
+    bgr: 1552,
+    bgs: 1553,
+    bgt: 1554,
+    bgu: 1555,
+    bgv: 1556,
+    bgw: 1557,
+    bgx: 1558,
+    bgy: 1559,
+    bhz: 1560,
+    bha: 1561,
+    bhb: 1562,
+    bhc: 1563,
+    bhd: 1564,
+    bhe: 1565,
+    bhf: 1566,
+    bhg: 1567,
+    bhh: 1568,
+    bhi: 1569,
+    bhj: 1570,
+    bhk: 1571,
+    bhl: 1572,
+    bhm: 1573,
+    bhn: 1574,
+    bho: 1575,
+    bhp: 1576,
+    bhq: 1577,
+    bhr: 1578,
+    bhs: 1579,
+    bht: 1580,
+    bhu: 1581,
+    bhv: 1582,
+    bhw: 1583,
+    bhx: 1584,
+    bhy: 1585,
+    biz: 1586,
+    bia: 1587,
+    bib: 1588,
+    bic: 1589,
+    bid: 1590,
+    bie: 1591,
+    bif: 1592,
+    big: 1593,
+    bih: 1594,
+    bii: 1595,
+    bij: 1596,
+    bik: 1597,
+    bil: 1598,
+    bim: 1599,
+    bin: 1600,
+    bio: 1601,
+    bip: 1602,
+    biq: 1603,
+    bir: 1604,
+    bis: 1605,
+    bit: 1606,
+    biu: 1607,
+    biv: 1608,
+    biw: 1609,
+    bix: 1610,
+    biy: 1611,
+    bjz: 1612,
+    bja: 1613,
+    bjb: 1614,
+    bjc: 1615,
+    bjd: 1616,
+    bje: 1617,
+    bjf: 1618,
+    bjg: 1619,
+    bjh: 1620,
+    bji: 1621,
+    bjj: 1622,
+    bjk: 1623,
+    bjl: 1624,
+    bjm: 1625,
+    bjn: 1626,
+    bjo: 1627,
+    bjp: 1628,
+    bjq: 1629,
+    bjr: 1630,
+    bjs: 1631,
+    bjt: 1632,
+    bju: 1633,
+    bjv: 1634,
+    bjw: 1635,
+    bjx: 1636,
+    bjy: 1637,
+    bkz: 1638,
+    bka: 1639,
+    bkb: 1640,
+    bkc: 1641,
+    bkd: 1642,
+    bke: 1643,
+    bkf: 1644,
+    bkg: 1645,
+    bkh: 1646,
+    bki: 1647,
+    bkj: 1648,
+    bkk: 1649,
+    bkl: 1650,
+    bkm: 1651,
+    bkn: 1652,
+    bko: 1653,
+    bkp: 1654,
+    bkq: 1655,
+    bkr: 1656,
+    bks: 1657,
+    bkt: 1658,
+    bku: 1659,
+    bkv: 1660,
+    bkw: 1661,
+    bkx: 1662,
+    bky: 1663,
+    blz: 1664,
+    bla: 1665,
+    blb: 1666,
+    blc: 1667,
+    bld: 1668,
+    ble: 1669,
+    blf: 1670,
+    blg: 1671,
+    blh: 1672,
+    bli: 1673,
+    blj: 1674,
+    blk: 1675,
+    bll: 1676,
+    blm: 1677,
+    bln: 1678,
+    blo: 1679,
+    blp: 1680,
+    blq: 1681,
+    blr: 1682,
+    bls: 1683,
+    blt: 1684,
+    blu: 1685,
+    blv: 1686,
+    blw: 1687,
+    blx: 1688,
+    bly: 1689,
+    bmz: 1690,
+    bma: 1691,
+    bmb: 1692,
+    bmc: 1693,
+    bmd: 1694,
+    bme: 1695,
+    bmf: 1696,
+    bmg: 1697,
+    bmh: 1698,
+    bmi: 1699,
+    bmj: 1700,
+    bmk: 1701,
+    bml: 1702,
+    bmm: 1703,
+    bmn: 1704,
+    bmo: 1705,
+    bmp: 1706,
+    bmq: 1707,
+    bmr: 1708,
+    bms: 1709,
+    bmt: 1710,
+    bmu: 1711,
+    bmv: 1712,
+    bmw: 1713,
+    bmx: 1714,
+    bmy: 1715,
+    bnz: 1716,
+    bna: 1717,
+    bnb: 1718,
+    bnc: 1719,
+    bnd: 1720,
+    bne: 1721,
+    bnf: 1722,
+    bng: 1723,
+    bnh: 1724,
+    bni: 1725,
+    bnj: 1726,
+    bnk: 1727,
+    bnl: 1728,
+    bnm: 1729,
+    bnn: 1730,
+    bno: 1731,
+    bnp: 1732,
+    bnq: 1733,
+    bnr: 1734,
+    bns: 1735,
+    bnt: 1736,
+    bnu: 1737,
+    bnv: 1738,
+    bnw: 1739,
+    bnx: 1740,
+    bny: 1741,
+    boz: 1742,
+    boa: 1743,
+    bob: 1744,
+    boc: 1745,
+    bod: 1746,
+    boe: 1747,
+    bof: 1748,
+    bog: 1749,
+    boh: 1750,
+    boi: 1751,
+    boj: 1752,
+    bok: 1753,
+    bol: 1754,
+    bom: 1755,
+    bon: 1756,
+    boo: 1757,
+    bop: 1758,
+    boq: 1759,
+    bor: 1760,
+    bos: 1761,
+    bot: 1762,
+    bou: 1763,
+    bov: 1764,
+    bow: 1765,
+    box: 1766,
+    boy: 1767,
+    bpz: 1768,
+    bpa: 1769,
+    bpb: 1770,
+    bpc: 1771,
+    bpd: 1772,
+    bpe: 1773,
+    bpf: 1774,
+    bpg: 1775,
+    bph: 1776,
+    bpi: 1777,
+    bpj: 1778,
+    bpk: 1779,
+    bpl: 1780,
+    bpm: 1781,
+    bpn: 1782,
+    bpo: 1783,
+    bpp: 1784,
+    bpq: 1785,
+    bpr: 1786,
+    bps: 1787,
+    bpt: 1788,
+    bpu: 1789,
+    bpv: 1790,
+    bpw: 1791,
+    bpx: 1792,
+    bpy: 1793,
+    bqz: 1794,
+    bqa: 1795,
+    bqb: 1796,
+    bqc: 1797,
+    bqd: 1798,
+    bqe: 1799,
+    bqf: 1800,
+    bqg: 1801,
+    bqh: 1802,
+    bqi: 1803,
+    bqj: 1804,
+    bqk: 1805,
+    bql: 1806,
+    bqm: 1807,
+    bqn: 1808,
+    bqo: 1809,
+    bqp: 1810,
+    bqq: 1811,
+    bqr: 1812,
+    bqs: 1813,
+    bqt: 1814,
+    bqu: 1815,
+    bqv: 1816,
+    bqw: 1817,
+    bqx: 1818,
+    bqy: 1819,
+    brz: 1820,
+    bra: 1821,
+    brb: 1822,
+    brc: 1823,
+    brd: 1824,
+    bre: 1825,
+    brf: 1826,
+    brg: 1827,
+    brh: 1828,
+    bri: 1829,
+    brj: 1830,
+    brk: 1831,
+    brl: 1832,
+    brm: 1833,
+    brn: 1834,
+    bro: 1835,
+    brp: 1836,
+    brq: 1837,
+    brr: 1838,
+    brs: 1839,
+    brt: 1840,
+    bru: 1841,
+    brv: 1842,
+    brw: 1843,
+    brx: 1844,
+    bry: 1845,
+    bsz: 1846,
+    bsa: 1847,
+    bsb: 1848,
+    bsc: 1849,
+    bsd: 1850,
+    bse: 1851,
+    bsf: 1852,
+    bsg: 1853,
+    bsh: 1854,
+    bsi: 1855,
+    bsj: 1856,
+    bsk: 1857,
+    bsl: 1858,
+    bsm: 1859,
+    bsn: 1860,
+    bso: 1861,
+    bsp: 1862,
+    bsq: 1863,
+    bsr: 1864,
+    bss: 1865,
+    bst: 1866,
+    bsu: 1867,
+    bsv: 1868,
+    bsw: 1869,
+    bsx: 1870,
+    bsy: 1871,
+    btz: 1872,
+    bta: 1873,
+    btb: 1874,
+    btc: 1875,
+    btd: 1876,
+    bte: 1877,
+    btf: 1878,
+    btg: 1879,
+    bth: 1880,
+    bti: 1881,
+    btj: 1882,
+    btk: 1883,
+    btl: 1884,
+    btm: 1885,
+    btn: 1886,
+    bto: 1887,
+    btp: 1888,
+    btq: 1889,
+    btr: 1890,
+    bts: 1891,
+    btt: 1892,
+    btu: 1893,
+    btv: 1894,
+    btw: 1895,
+    btx: 1896,
+    bty: 1897,
+    buz: 1898,
+    bua: 1899,
+    bub: 1900,
+    buc: 1901,
+    bud: 1902,
+    bue: 1903,
+    buf: 1904,
+    bug: 1905,
+    buh: 1906,
+    bui: 1907,
+    buj: 1908,
+    buk: 1909,
+    bul: 1910,
+    bum: 1911,
+    bun: 1912,
+    buo: 1913,
+    bup: 1914,
+    buq: 1915,
+    bur: 1916,
+    bus: 1917,
+    but: 1918,
+    buu: 1919,
+    buv: 1920,
+    buw: 1921,
+    bux: 1922,
+    buy: 1923,
+    bvz: 1924,
+    bva: 1925,
+    bvb: 1926,
+    bvc: 1927,
+    bvd: 1928,
+    bve: 1929,
+    bvf: 1930,
+    bvg: 1931,
+    bvh: 1932,
+    bvi: 1933,
+    bvj: 1934,
+    bvk: 1935,
+    bvl: 1936,
+    bvm: 1937,
+    bvn: 1938,
+    bvo: 1939,
+    bvp: 1940,
+    bvq: 1941,
+    bvr: 1942,
+    bvs: 1943,
+    bvt: 1944,
+    bvu: 1945,
+    bvv: 1946,
+    bvw: 1947,
+    bvx: 1948,
+    bvy: 1949,
+    bwz: 1950,
+    bwa: 1951,
+    bwb: 1952,
+    bwc: 1953,
+    bwd: 1954,
+    bwe: 1955,
+    bwf: 1956,
+    bwg: 1957,
+    bwh: 1958,
+    bwi: 1959,
+    bwj: 1960,
+    bwk: 1961,
+    bwl: 1962,
+    bwm: 1963,
+    bwn: 1964,
+    bwo: 1965,
+    bwp: 1966,
+    bwq: 1967,
+    bwr: 1968,
+    bws: 1969,
+    bwt: 1970,
+    bwu: 1971,
+    bwv: 1972,
+    bww: 1973,
+    bwx: 1974,
+    bwy: 1975,
+    bxz: 1976,
+    bxa: 1977,
+    bxb: 1978,
+    bxc: 1979,
+    bxd: 1980,
+    bxe: 1981,
+    bxf: 1982,
+    bxg: 1983,
+    bxh: 1984,
+    bxi: 1985,
+    bxj: 1986,
+    bxk: 1987,
+    bxl: 1988,
+    bxm: 1989,
+    bxn: 1990,
+    bxo: 1991,
+    bxp: 1992,
+    bxq: 1993,
+    bxr: 1994,
+    bxs: 1995,
+    bxt: 1996,
+    bxu: 1997,
+    bxv: 1998,
+    bxw: 1999,
+    bxx: 2000,
+    bxy: 2001,
+    byz: 2002,
+    bya: 2003,
+    byb: 2004,
+    byc: 2005,
+    byd: 2006,
+    bye: 2007,
+    byf: 2008,
+    byg: 2009,
+    byh: 2010,
+    byi: 2011,
+    byj: 2012,
+    byk: 2013,
+    byl: 2014,
+    bym: 2015,
+    byn: 2016,
+    byo: 2017,
+    byp: 2018,
+    byq: 2019,
+    byr: 2020,
+    bys: 2021,
+    byt: 2022,
+    byu: 2023,
+    byv: 2024,
+    byw: 2025,
+    byx: 2026,
+    byy: 2027,
+    czz: 2028,
+    cza: 2029,
+    czb: 2030,
+    czc: 2031,
+    czd: 2032,
+    cze: 2033,
+    czf: 2034,
+    czg: 2035,
+    czh: 2036,
+    czi: 2037,
+    czj: 2038,
+    czk: 2039,
+    czl: 2040,
+    czm: 2041,
+    czn: 2042,
+    czo: 2043,
+    czp: 2044,
+    czq: 2045,
+    czr: 2046,
+    czs: 2047,
+    czt: 2048,
+    czu: 2049,
+    czv: 2050,
+    czw: 2051,
+    czx: 2052,
+    czy: 2053,
+    caz: 2054,
+    caa: 2055,
+    cab: 2056,
+    cac: 2057,
+    cad: 2058,
+    cae: 2059,
+    caf: 2060,
+    cag: 2061,
+    cah: 2062,
+    cai: 2063,
+    caj: 2064,
+    cak: 2065,
+    cal: 2066,
+    cam: 2067,
+    can: 2068,
+    cao: 2069,
+    cap: 2070,
+    caq: 2071,
+    car: 2072,
+    cas: 2073,
+    cat: 2074,
+    cau: 2075,
+    cav: 2076,
+    caw: 2077,
+    cax: 2078,
+    cay: 2079,
+    cbz: 2080,
+    cba: 2081,
+    cbb: 2082,
+    cbc: 2083,
+    cbd: 2084,
+    cbe: 2085,
+    cbf: 2086,
+    cbg: 2087,
+    cbh: 2088,
+    cbi: 2089,
+    cbj: 2090,
+    cbk: 2091,
+    cbl: 2092,
+    cbm: 2093,
+    cbn: 2094,
+    cbo: 2095,
+    cbp: 2096,
+    cbq: 2097,
+    cbr: 2098,
+    cbs: 2099,
+    cbt: 2100,
+    cbu: 2101,
+    cbv: 2102,
+    cbw: 2103,
+    cbx: 2104,
+    cby: 2105,
+    ccz: 2106,
+    cca: 2107,
+    ccb: 2108,
+    ccc: 2109,
+    ccd: 2110,
+    cce: 2111,
+    ccf: 2112,
+    ccg: 2113,
+    cch: 2114,
+    cci: 2115,
+    ccj: 2116,
+    cck: 2117,
+    ccl: 2118,
+    ccm: 2119,
+    ccn: 2120,
+    cco: 2121,
+    ccp: 2122,
+    ccq: 2123,
+    ccr: 2124,
+    ccs: 2125,
+    cct: 2126,
+    ccu: 2127,
+    ccv: 2128,
+    ccw: 2129,
+    ccx: 2130,
+    ccy: 2131,
+    cdz: 2132,
+    cda: 2133,
+    cdb: 2134,
+    cdc: 2135,
+    cdd: 2136,
+    cde: 2137,
+    cdf: 2138,
+    cdg: 2139,
+    cdh: 2140,
+    cdi: 2141,
+    cdj: 2142,
+    cdk: 2143,
+    cdl: 2144,
+    cdm: 2145,
+    cdn: 2146,
+    cdo: 2147,
+    cdp: 2148,
+    cdq: 2149,
+    cdr: 2150,
+    cds: 2151,
+    cdt: 2152,
+    cdu: 2153,
+    cdv: 2154,
+    cdw: 2155,
+    cdx: 2156,
+    cdy: 2157,
+    cez: 2158,
+    cea: 2159,
+    ceb: 2160,
+    cec: 2161,
+    ced: 2162,
+    cee: 2163,
+    cef: 2164,
+    ceg: 2165,
+    ceh: 2166,
+    cei: 2167,
+    cej: 2168,
+    cek: 2169,
+    cel: 2170,
+    cem: 2171,
+    cen: 2172,
+    ceo: 2173,
+    cep: 2174,
+    ceq: 2175,
+    cer: 2176,
+    ces: 2177,
+    cet: 2178,
+    ceu: 2179,
+    cev: 2180,
+    cew: 2181,
+    cex: 2182,
+    cey: 2183,
+    cfz: 2184,
+    cfa: 2185,
+    cfb: 2186,
+    cfc: 2187,
+    cfd: 2188,
+    cfe: 2189,
+    cff: 2190,
+    cfg: 2191,
+    cfh: 2192,
+    cfi: 2193,
+    cfj: 2194,
+    cfk: 2195,
+    cfl: 2196,
+    cfm: 2197,
+    cfn: 2198,
+    cfo: 2199,
+    cfp: 2200,
+    cfq: 2201,
+    cfr: 2202,
+    cfs: 2203,
+    cft: 2204,
+    cfu: 2205,
+    cfv: 2206,
+    cfw: 2207,
+    cfx: 2208,
+    cfy: 2209,
+    cgz: 2210,
+    cga: 2211,
+    cgb: 2212,
+    cgc: 2213,
+    cgd: 2214,
+    cge: 2215,
+    cgf: 2216,
+    cgg: 2217,
+    cgh: 2218,
+    cgi: 2219,
+    cgj: 2220,
+    cgk: 2221,
+    cgl: 2222,
+    cgm: 2223,
+    cgn: 2224,
+    cgo: 2225,
+    cgp: 2226,
+    cgq: 2227,
+    cgr: 2228,
+    cgs: 2229,
+    cgt: 2230,
+    cgu: 2231,
+    cgv: 2232,
+    cgw: 2233,
+    cgx: 2234,
+    cgy: 2235,
+    chz: 2236,
+    cha: 2237,
+    chb: 2238,
+    chc: 2239,
+    chd: 2240,
+    che: 2241,
+    chf: 2242,
+    chg: 2243,
+    chh: 2244,
+    chi: 2245,
+    chj: 2246,
+    chk: 2247,
+    chl: 2248,
+    chm: 2249,
+    chn: 2250,
+    cho: 2251,
+    chp: 2252,
+    chq: 2253,
+    chr: 2254,
+    chs: 2255,
+    cht: 2256,
+    chu: 2257,
+    chv: 2258,
+    chw: 2259,
+    chx: 2260,
+    chy: 2261,
+    ciz: 2262,
+    cia: 2263,
+    cib: 2264,
+    cic: 2265,