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 *
|