src/jdk/nashorn/internal/runtime/ScriptObject.java

Print this page




 115     /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
 116     public static final int SPILL_RATE = 8;
 117 
 118     /** Map to property information and accessor functions. Ordered by insertion. */
 119     private PropertyMap map;
 120 
 121     /** objects proto. */
 122     private ScriptObject proto;
 123 
 124     /** Object flags. */
 125     private int flags;
 126 
 127     /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
 128     public Object[] spill;
 129 
 130     /** Indexed array data. */
 131     private ArrayData arrayData;
 132 
 133     /** Method handle to retrive prototype of this object */
 134     public static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
 135     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
 136     static final MethodHandle GLOBALFILTER       = findOwnMH("globalFilter", Object.class, Object.class);
 137 
 138     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
 139     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 140     static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 141     static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
 142 
 143     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
 144     private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
 145 
 146     private static final ArrayList<MethodHandle> protoFilters = new ArrayList<>();
 147 
 148     /** Method handle for getting a function argument at a given index. Used from MapCreator */
 149     public static final Call GET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
 150 
 151     /** Method handle for setting a function argument at a given index. Used from MapCreator */
 152     public static final Call SET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
 153 
 154     /** Method handle for getting the proto of a ScriptObject */
 155     public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);


1728             filter = addProtoFilter(GETPROTO, depth - 1);
1729             protoFilters.add(null);
1730             protoFilters.set(listIndex, filter);
1731         }
1732 
1733         return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0))));
1734     }
1735 
1736     /**
1737      * Find the appropriate GET method for an invoke dynamic call.
1738      *
1739      * @param desc     the call site descriptor
1740      * @param request  the link request
1741      * @param operator operator for get: getProp, getMethod, getElem etc
1742      *
1743      * @return GuardedInvocation to be invoked at call site.
1744      */
1745     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
1746         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
1747         if (request.isCallSiteUnstable() || hasWithScope()) {
1748             return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
1749         }
1750 
1751         final FindProperty find = findProperty(name, true);
1752         MethodHandle methodHandle;
1753 
1754         if (find == null) {
1755             if ("getProp".equals(operator)) {
1756                 return noSuchProperty(desc, request);
1757             } else if ("getMethod".equals(operator)) {
1758                 return noSuchMethod(desc, request);
1759             } else if ("getElem".equals(operator)) {
1760                 return createEmptyGetter(desc, name);
1761             }
1762             throw new AssertionError(); // never invoked with any other operation
1763         }
1764 
1765         final Class<?> returnType = desc.getMethodType().returnType();
1766         final Property property = find.getProperty();
1767         methodHandle = find.getGetter(returnType);
1768 


1771         final ScriptObject owner = find.getOwner();
1772 
1773         if (methodHandle != null) {
1774             assert methodHandle.type().returnType().equals(returnType);
1775             if (find.isSelf()) {
1776                 return new GuardedInvocation(methodHandle, guard);
1777             }
1778 
1779             if (!property.hasGetterFunction(owner)) {
1780                 // Add a filter that replaces the self object with the prototype owning the property.
1781                 methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
1782             }
1783             return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
1784         }
1785 
1786         assert !NashornCallSiteDescriptor.isFastScope(desc);
1787         return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
1788     }
1789 
1790     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
1791                                                               final boolean isMethod, final boolean isScope) {
1792         final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
1793         final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
1794         return new GuardedInvocation(invoker, guard);
1795     }
1796 
1797     @SuppressWarnings("unused")
1798     private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
1799         final FindProperty find = findProperty(key, true);
1800 
1801         if (find != null) {
1802             return find.getObjectValue();
1803         }
1804         if (isScope) {
1805             throw referenceError("not.defined", key);
1806         }
1807 
1808         return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
1809     }
1810 
1811     /**
1812      * Find the appropriate GETINDEX method for an invoke dynamic call.
1813      *
1814      * @param desc    the call site descriptor
1815      * @param request the link request
1816      *
1817      * @return GuardedInvocation to be invoked at call site.
1818      */
1819     protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
1820         return findGetIndexMethod(desc.getMethodType());
1821     }
1822 
1823     /**
1824      * Find the appropriate GETINDEX method for an invoke dynamic call.
1825      *




 115     /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
 116     public static final int SPILL_RATE = 8;
 117 
 118     /** Map to property information and accessor functions. Ordered by insertion. */
 119     private PropertyMap map;
 120 
 121     /** objects proto. */
 122     private ScriptObject proto;
 123 
 124     /** Object flags. */
 125     private int flags;
 126 
 127     /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
 128     public Object[] spill;
 129 
 130     /** Indexed array data. */
 131     private ArrayData arrayData;
 132 
 133     /** Method handle to retrive prototype of this object */
 134     public static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
 135     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
 136     static final MethodHandle GLOBALFILTER       = findOwnMH("globalFilter", Object.class, Object.class);
 137 
 138     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
 139     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 140     static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 141     static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
 142 
 143     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
 144     private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
 145 
 146     private static final ArrayList<MethodHandle> protoFilters = new ArrayList<>();
 147 
 148     /** Method handle for getting a function argument at a given index. Used from MapCreator */
 149     public static final Call GET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
 150 
 151     /** Method handle for setting a function argument at a given index. Used from MapCreator */
 152     public static final Call SET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
 153 
 154     /** Method handle for getting the proto of a ScriptObject */
 155     public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);


1728             filter = addProtoFilter(GETPROTO, depth - 1);
1729             protoFilters.add(null);
1730             protoFilters.set(listIndex, filter);
1731         }
1732 
1733         return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0))));
1734     }
1735 
1736     /**
1737      * Find the appropriate GET method for an invoke dynamic call.
1738      *
1739      * @param desc     the call site descriptor
1740      * @param request  the link request
1741      * @param operator operator for get: getProp, getMethod, getElem etc
1742      *
1743      * @return GuardedInvocation to be invoked at call site.
1744      */
1745     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
1746         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
1747         if (request.isCallSiteUnstable() || hasWithScope()) {
1748             return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
1749         }
1750 
1751         final FindProperty find = findProperty(name, true);
1752         MethodHandle methodHandle;
1753 
1754         if (find == null) {
1755             if ("getProp".equals(operator)) {
1756                 return noSuchProperty(desc, request);
1757             } else if ("getMethod".equals(operator)) {
1758                 return noSuchMethod(desc, request);
1759             } else if ("getElem".equals(operator)) {
1760                 return createEmptyGetter(desc, name);
1761             }
1762             throw new AssertionError(); // never invoked with any other operation
1763         }
1764 
1765         final Class<?> returnType = desc.getMethodType().returnType();
1766         final Property property = find.getProperty();
1767         methodHandle = find.getGetter(returnType);
1768 


1771         final ScriptObject owner = find.getOwner();
1772 
1773         if (methodHandle != null) {
1774             assert methodHandle.type().returnType().equals(returnType);
1775             if (find.isSelf()) {
1776                 return new GuardedInvocation(methodHandle, guard);
1777             }
1778 
1779             if (!property.hasGetterFunction(owner)) {
1780                 // Add a filter that replaces the self object with the prototype owning the property.
1781                 methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
1782             }
1783             return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
1784         }
1785 
1786         assert !NashornCallSiteDescriptor.isFastScope(desc);
1787         return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
1788     }
1789 
1790     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
1791                                                               final boolean isMethod) {
1792         final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
1793         final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
1794         return new GuardedInvocation(invoker, guard);
1795     }
1796 
1797     @SuppressWarnings("unused")
1798     private Object megamorphicGet(final String key, final boolean isMethod) {
1799         final FindProperty find = findProperty(key, true);
1800 
1801         if (find != null) {
1802             return find.getObjectValue();



1803         }
1804 
1805         return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
1806     }
1807 
1808     /**
1809      * Find the appropriate GETINDEX method for an invoke dynamic call.
1810      *
1811      * @param desc    the call site descriptor
1812      * @param request the link request
1813      *
1814      * @return GuardedInvocation to be invoked at call site.
1815      */
1816     protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
1817         return findGetIndexMethod(desc.getMethodType());
1818     }
1819 
1820     /**
1821      * Find the appropriate GETINDEX method for an invoke dynamic call.
1822      *