/** * 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!! * @param self self reference * @return undefined */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object dumpCounters(final Object self) { final PrintWriter out = Context.getCurrentErr(); out.println("ScriptObject count " + ScriptObject.getCount()); out.println("Scope count " + ScriptObject.getScopeCount()); out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded()); out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved()); out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount()); out.println("ScriptFunction invokes " + ScriptFunction.getInvokes()); out.println("ScriptFunction allocations " + ScriptFunction.getAllocations()); out.println("PropertyMap count " + PropertyMap.getCount()); out.println("PropertyMap cloned " + PropertyMap.getClonedCount()); out.println("PropertyMap history hit " + PropertyMap.getHistoryHit()); out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations()); out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit()); out.println("PropertyMap setProtoNewMapCount " + PropertyMap.getSetProtoNewMapCount()); out.println("Callsite count " + LinkerCallSite.getCount()); out.println("Callsite misses " + LinkerCallSite.getMissCount()); out.println("Callsite misses by site at " + LinkerCallSite.getMissSamplingPercentage() + "%"); LinkerCallSite.getMissCounts(out); return UNDEFINED; }
NativeStrictArguments(final Object[] values, final int numParams,final ScriptObject proto, final PropertyMap map) { super(proto, map); setIsArguments(); final ScriptFunction func = Global.instance().getTypeErrorThrower(); // We have to fill user accessor functions late as these are stored // in this object rather than in the PropertyMap of this object. final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE; initUserAccessors("caller", flags, func, func); initUserAccessors("callee", flags, func, func); setArray(ArrayData.allocate(values)); this.length = values.length; // extend/truncate named arg array as needed and copy values this.namedArgs = new Object[numParams]; if (numParams > values.length) { Arrays.fill(namedArgs, UNDEFINED); } System.arraycopy(values, 0, namedArgs, 0, Math.min(namedArgs.length, values.length)); }
/** * Constructs a property map based on a set of fields. * * @param hasArguments does the created object have an "arguments" property * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. * @param evalCode is this property map created for 'eval' code? * @return New map populated with accessor properties. */ PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum, final boolean evalCode) { final List<Property> properties = new ArrayList<>(); assert tuples != null; for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; final Class<?> initialType = tuple.getValueType(); if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { final int flags = getPropertyFlags(symbol, hasArguments, evalCode); final Property property = new AccessorProperty( key, flags, structure, symbol.getFieldIndex(), initialType); properties.add(property); } } return PropertyMap.newMap(properties, structure.getName(), fieldCount, fieldMaximum, 0); }
PropertyMap makeSpillMap(final boolean hasArguments) { final List<Property> properties = new ArrayList<>(); int spillIndex = 0; assert tuples != null; for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; //TODO initial type is object here no matter what. Is that right? if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { final int flags = getPropertyFlags(symbol, hasArguments, false); properties.add( new SpillProperty( key, flags, spillIndex++)); } } return PropertyMap.newMap(properties, structure.getName(), 0, 0, spillIndex); }
private void loadConstant(final Object object, final CompileUnit compileUnit, final MethodEmitter methodEmitter) { final String unitClassName = compileUnit.getUnitClassName(); final ClassEmitter classEmitter = compileUnit.getClassEmitter(); final int index = compiler.getConstantData().add(object); final Class<?> cls = object.getClass(); if (cls == PropertyMap.class) { methodEmitter.load(index); methodEmitter.invokestatic(unitClassName, GET_MAP.symbolName(), methodDescriptor(PropertyMap.class, int.class)); classEmitter.needGetConstantMethod(PropertyMap.class); } else if (cls.isArray()) { methodEmitter.load(index); final String methodName = ClassEmitter.getArrayMethodName(cls); methodEmitter.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class)); classEmitter.needGetConstantMethod(cls); } else { methodEmitter.loadConstants().load(index).arrayload(); if (object instanceof ArrayData) { // avoid cast to non-public ArrayData subclass methodEmitter.checkcast(ArrayData.class); methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class)); } else if (cls != Object.class) { methodEmitter.checkcast(cls); } } }
private PropertyMap addObjectProperty(final PropertyMap propertyMap, final List<Object> values, final String id, final Object value) { final Property oldProperty = propertyMap.findProperty(id); final PropertyMap newMap; final Class<?> type; final int flags; if (dualFields) { type = getType(value); flags = Property.DUAL_FIELDS; } else { type = Object.class; flags = 0; } if (oldProperty != null) { values.set(oldProperty.getSlot(), value); newMap = propertyMap.replaceProperty(oldProperty, new SpillProperty(id, flags, oldProperty.getSlot(), type));; } else { values.add(value); newMap = propertyMap.addProperty(new SpillProperty(id, flags, propertyMap.size(), type)); } return newMap; }
private Object createObject(final PropertyMap propertyMap, final List<Object> values, final ArrayData arrayData) { final long[] primitiveSpill = dualFields ? new long[values.size()] : null; final Object[] objectSpill = new Object[values.size()]; for (final Property property : propertyMap.getProperties()) { if (!dualFields || property.getType() == Object.class) { objectSpill[property.getSlot()] = values.get(property.getSlot()); } else { primitiveSpill[property.getSlot()] = ObjectClassGenerator.pack((Number) values.get(property.getSlot())); } } final ScriptObject object = dualFields ? new JD(propertyMap, primitiveSpill, objectSpill) : new JO(propertyMap, null, objectSpill); object.setInitialProto(global.getObjectPrototype()); object.setArray(arrayData); return object; }
/** * 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!! * @param self self reference * @return undefined */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object dumpCounters(final Object self) { final PrintWriter out = Context.getCurrentErr(); out.println("ScriptObject count " + ScriptObject.getCount()); out.println("Scope count " + Scope.getScopeCount()); out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded()); out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved()); out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount()); out.println("ScriptFunction invokes " + ScriptFunction.getInvokes()); out.println("ScriptFunction allocations " + ScriptFunction.getAllocations()); out.println("PropertyMap count " + PropertyMap.getCount()); out.println("PropertyMap cloned " + PropertyMap.getClonedCount()); out.println("PropertyMap history hit " + PropertyMap.getHistoryHit()); out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations()); out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit()); out.println("PropertyMap setProtoNewMapCount " + PropertyMap.getSetProtoNewMapCount()); out.println("Callsite count " + LinkerCallSite.getCount()); out.println("Callsite misses " + LinkerCallSite.getMissCount()); out.println("Callsite misses by site at " + LinkerCallSite.getMissSamplingPercentage() + "%"); LinkerCallSite.getMissCounts(out); return UNDEFINED; }
/** * Constructs a property map based on a set of fields. * * @param hasArguments does the created object have an "arguments" property * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. * @param evalCode is this property map created for 'eval' code? * @return New map populated with accessor properties. */ PropertyMap makeFieldMap(final boolean hasArguments, final boolean dualFields, final int fieldCount, final int fieldMaximum, final boolean evalCode) { final List<Property> properties = new ArrayList<>(); assert tuples != null; for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; final Class<?> initialType = dualFields ? tuple.getValueType() : Object.class; if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { final int flags = getPropertyFlags(symbol, hasArguments, evalCode, dualFields); final Property property = new AccessorProperty( key, flags, structure, symbol.getFieldIndex(), initialType); properties.add(property); } } return PropertyMap.newMap(properties, structure.getName(), fieldCount, fieldMaximum, 0); }
PropertyMap makeSpillMap(final boolean hasArguments, final boolean dualFields) { final List<Property> properties = new ArrayList<>(); int spillIndex = 0; assert tuples != null; for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; final Class<?> initialType = dualFields ? tuple.getValueType() : Object.class; if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { final int flags = getPropertyFlags(symbol, hasArguments, false, dualFields); properties.add( new SpillProperty( key, flags, spillIndex++, initialType)); } } return PropertyMap.newMap(properties, structure.getName(), 0, 0, spillIndex); }
private void loadConstant(final Object object, final CompileUnit compileUnit, final MethodEmitter methodEmitter) { final String unitClassName = compileUnit.getUnitClassName(); final ClassEmitter classEmitter = compileUnit.getClassEmitter(); final int index = compiler.getConstantData().add(object); final Class<?> cls = object.getClass(); if (cls == PropertyMap.class) { methodEmitter.load(index); methodEmitter.invokestatic(unitClassName, GET_MAP.symbolName(), methodDescriptor(PropertyMap.class, int.class)); classEmitter.needGetConstantMethod(PropertyMap.class); } else if (cls.isArray()) { methodEmitter.load(index); final String methodName = ClassEmitter.getArrayMethodName(cls); methodEmitter.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class)); classEmitter.needGetConstantMethod(cls); } else { methodEmitter.loadConstants().load(index).arrayload(); if (object instanceof ArrayData) { methodEmitter.checkcast(ArrayData.class); methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class)); } else if (cls != Object.class) { methodEmitter.checkcast(cls); } } }
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; final ScriptObject sobj = (ScriptObject)overrides; this.addBoundProperties(sobj); } else { this.overrides = false; } }
NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) { super(proto, map); setIsArguments(); setArray(ArrayData.allocate(arguments)); this.length = arguments.length; this.callee = callee; this.numMapped = Math.min(numParams, arguments.length); this.numParams = numParams; }
private static PropertyMap checkAndGetMap(final Context context) { // security check first final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL)); } // null check on context context.getClass(); return $nasgenmap$; }
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. newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags)); newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags)); return newMap; }
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; }
@SuppressWarnings("LeakingThisInConstructor") private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) { super(proto, map); if (msg != UNDEFINED) { this.instMessage = JSType.toString(msg); } else { this.delete(NativeError.MESSAGE, false); } NativeError.initException(this); }
@SuppressWarnings("LeakingThisInConstructor") private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) { super(proto, map); if (msg != UNDEFINED) { this.instMessage = JSType.toString(msg); } else { this.delete(NativeError.MESSAGE, false); } NativeError.initException(this); }
private static MethodEmitter newInitWithSpillArraysMethod(final ClassEmitter classEmitter, final Class<?> superClass) { final MethodEmitter init = classEmitter.init(PropertyMap.class, long[].class, Object[].class); init.begin(); init.load(Type.OBJECT, JAVA_THIS.slot()); init.load(Type.OBJECT, INIT_MAP.slot()); init.load(Type.LONG_ARRAY, 2); init.load(Type.OBJECT_ARRAY, 3); init.invoke(constructorNoLookup(superClass, PropertyMap.class, long[].class, Object[].class)); return init; }
/** * Allocate and initialize a new <init> method for scopes. * @param classEmitter Open class emitter. * @return Open method emitter. */ private static MethodEmitter newInitScopeMethod(final ClassEmitter classEmitter) { final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class); init.begin(); init.load(Type.OBJECT, JAVA_THIS.slot()); init.load(Type.OBJECT, INIT_MAP.slot()); init.load(Type.OBJECT, INIT_SCOPE.slot()); init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class)); return init; }
/** * Allocate and initialize a new <init> method for scopes with arguments. * @param classEmitter Open class emitter. * @return Open method emitter. */ private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) { final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, ScriptObject.class); init.begin(); init.load(Type.OBJECT, JAVA_THIS.slot()); init.load(Type.OBJECT, INIT_MAP.slot()); init.load(Type.OBJECT, INIT_SCOPE.slot()); init.load(Type.OBJECT, INIT_ARGUMENTS.slot()); init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, ScriptObject.class)); return init; }
/** * Add an empty <init> method to the JavaScript class. * * @param classEmitter Open class emitter. * @param className Name of JavaScript class. */ private static void newEmptyInit(final String className, final ClassEmitter classEmitter) { final MethodEmitter emptyInit = classEmitter.init(); emptyInit.begin(); emptyInit.load(Type.OBJECT, JAVA_THIS.slot()); emptyInit.loadNull(); emptyInit.invoke(constructorNoLookup(className, PropertyMap.class)); emptyInit.returnVoid(); emptyInit.end(); }
/** * Add an empty <init> method to the JavaScript class. * * @param classEmitter Open class emitter. * @param className Name of JavaScript class. */ private static void newAllocate(final String className, final ClassEmitter classEmitter) { final MethodEmitter allocate = classEmitter.method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), ALLOCATE.symbolName(), ScriptObject.class, PropertyMap.class); allocate.begin(); allocate._new(className, Type.typeFor(ScriptObject.class)); allocate.dup(); allocate.load(Type.typeFor(PropertyMap.class), 0); allocate.invoke(constructorNoLookup(className, PropertyMap.class)); allocate._return(); allocate.end(); }
@SuppressWarnings("LeakingThisInConstructor") private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) { super(proto, map); if (msg != UNDEFINED) { this.instMessage = JSType.toString(msg); } else { this.delete(NativeError.MESSAGE, false); } initException(this); }
private static PropertyMap checkAndGetMap(final Context context) { // security check first final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL)); } Objects.requireNonNull(context); return $nasgenmap$; }
@SuppressWarnings("LeakingThisInConstructor") private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) { super(proto, map); if (msg != UNDEFINED) { this.instMessage = JSType.toString(msg); } else { this.delete(NativeError.MESSAGE, false); } NativeError.initException(this); }
@Override protected PropertyMap makeMap() { assert propertyMap == null : "property map already initialized"; final Class<? extends ScriptObject> clazz = getAllocatorClass(); propertyMap = new MapCreator<>(clazz, tuples).makeSpillMap(false, codegen.useDualFields()); return propertyMap; }
@Override public boolean equals(final Object other) { if (!(other instanceof PropertyMapWrapper)) { return false; } final PropertyMap otherMap = ((PropertyMapWrapper) other).propertyMap; return propertyMap == otherMap || (Arrays.equals(propertyMap.getProperties(), otherMap.getProperties()) && Objects.equals(propertyMap.getClassName(), otherMap.getClassName())); }
/** * Allocate and initialize a new <init> method. * * @param classEmitter Open class emitter. * * @return Open method emitter. */ private static MethodEmitter newInitMethod(final ClassEmitter classEmitter) { final MethodEmitter init = classEmitter.init(PropertyMap.class); init.begin(); init.load(Type.OBJECT, JAVA_THIS.slot()); init.load(Type.OBJECT, INIT_MAP.slot()); init.invoke(constructorNoLookup(ScriptObject.class, PropertyMap.class)); return init; }