--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Thu Apr 25 14:20:23 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Thu Apr 25 14:47:17 2013 +0200
@@ -71,7 +71,6 @@
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
-
import jdk.internal.dynalink.support.NameCodec;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.MethodVisitor;
@@ -674,7 +673,7 @@
* @return the method emitter
*/
MethodEmitter loadUndefined(final Type type) {
- debug("load undefined " + type);
+ debug("load undefined ", type);
pushType(type.loadUndefined(method));
return this;
}
@@ -686,7 +685,7 @@
* @return the method emitter
*/
MethodEmitter loadEmpty(final Type type) {
- debug("load empty " + type);
+ debug("load empty ", type);
pushType(type.loadEmpty(method));
return this;
}
@@ -1076,7 +1075,7 @@
* @return the method emitter
*/
MethodEmitter newarray(final ArrayType arrayType) {
- debug("newarray ", "arrayType=" + arrayType);
+ debug("newarray ", "arrayType=", arrayType);
popType(Type.INT); //LENGTH
pushType(arrayType.newarray(method));
return this;
@@ -1155,7 +1154,7 @@
* @return the method emitter
*/
MethodEmitter invokespecial(final String className, final String methodName, final String methodDescriptor) {
- debug("invokespecial", className + "." + methodName + methodDescriptor);
+ debug("invokespecial", className, ".", methodName, methodDescriptor);
return invoke(INVOKESPECIAL, className, methodName, methodDescriptor, true);
}
@@ -1169,7 +1168,7 @@
* @return the method emitter
*/
MethodEmitter invokevirtual(final String className, final String methodName, final String methodDescriptor) {
- debug("invokevirtual", className + "." + methodName + methodDescriptor + " " + stack);
+ debug("invokevirtual", className, ".", methodName, methodDescriptor, " ", stack);
return invoke(INVOKEVIRTUAL, className, methodName, methodDescriptor, true);
}
@@ -1183,7 +1182,7 @@
* @return the method emitter
*/
MethodEmitter invokestatic(final String className, final String methodName, final String methodDescriptor) {
- debug("invokestatic", className + "." + methodName + methodDescriptor);
+ debug("invokestatic", className, ".", methodName, methodDescriptor);
invoke(INVOKESTATIC, className, methodName, methodDescriptor, false);
return this;
}
@@ -1216,7 +1215,7 @@
* @return the method emitter
*/
MethodEmitter invokeinterface(final String className, final String methodName, final String methodDescriptor) {
- debug("invokeinterface", className + "." + methodName + methodDescriptor);
+ debug("invokeinterface", className, ".", methodName, methodDescriptor);
return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true);
}
@@ -1268,11 +1267,11 @@
*/
void conditionalJump(final Condition cond, final boolean isCmpG, final Label trueLabel) {
if (peekType().isCategory2()) {
- debug("[ld]cmp isCmpG=" + isCmpG);
+ debug("[ld]cmp isCmpG=", isCmpG);
pushType(get2n().cmp(method, isCmpG));
jump(Condition.toUnary(cond), trueLabel, 1);
} else {
- debug("if" + cond);
+ debug("if", cond);
jump(Condition.toBinary(cond, peekType().isObject()), trueLabel, 2);
}
}
@@ -1517,7 +1516,7 @@
*/
private void mergeStackTo(final Label label) {
final ArrayDeque<Type> labelStack = label.getStack();
- //debug(labelStack == null ? " >> Control flow - first visit " + label : " >> Control flow - JOIN with " + labelStack + " at " + label);
+ //debug(labelStack == null ? " >> Control flow - first visit ", label : " >> Control flow - JOIN with ", labelStack, " at ", label);
if (labelStack == null) {
assert stack != null;
label.setStack(stack.clone());
@@ -1710,7 +1709,7 @@
* @return the method emitter
*/
MethodEmitter dynamicNew(final int argCount, final int flags) {
- debug("dynamic_new", "argcount=" + argCount);
+ debug("dynamic_new", "argcount=", argCount);
final String signature = getDynamicSignature(Type.OBJECT, argCount);
method.visitInvokeDynamicInsn("dyn:new", signature, LINKERBOOTSTRAP, flags);
pushType(Type.OBJECT); //TODO fix result type
@@ -1727,7 +1726,7 @@
* @return the method emitter
*/
MethodEmitter dynamicCall(final Type returnType, final int argCount, final int flags) {
- debug("dynamic_call", "args=" + argCount, "returnType=" + returnType);
+ debug("dynamic_call", "args=", argCount, "returnType=", returnType);
final String signature = getDynamicSignature(returnType, argCount); // +1 because the function itself is the 1st parameter for dynamic calls (what you call - call target)
debug(" signature", signature);
method.visitInvokeDynamicInsn("dyn:call", signature, LINKERBOOTSTRAP, flags);
@@ -1746,7 +1745,7 @@
* @return the method emitter
*/
MethodEmitter dynamicRuntimeCall(final String name, final Type returnType, final RuntimeNode.Request request) {
- debug("dynamic_runtime_call", name, "args=" + request.getArity(), "returnType=" + returnType);
+ debug("dynamic_runtime_call", name, "args=", request.getArity(), "returnType=", returnType);
final String signature = getDynamicSignature(returnType, request.getArity());
debug(" signature", signature);
method.visitInvokeDynamicInsn(name, signature, RUNTIMEBOOTSTRAP);
@@ -1817,7 +1816,7 @@
* @return the method emitter
*/
MethodEmitter dynamicGetIndex(final Type result, final int flags, final boolean isMethod) {
- debug("dynamic_get_index", peekType(1) + "[" + peekType() + "]");
+ debug("dynamic_get_index", peekType(1), "[", peekType(), "]");
Type resultType = result;
if (result.isBoolean()) {
@@ -1853,7 +1852,7 @@
* @param flags call site flags for setter
*/
void dynamicSetIndex(final int flags) {
- debug("dynamic_set_index", peekType(2) + "[" + peekType(1) + "] =", peekType());
+ debug("dynamic_set_index", peekType(2), "[", peekType(1), "] =", peekType());
Type value = peekType();
if (value.isObject() || value.isBoolean()) {
@@ -1953,7 +1952,7 @@
* @return the method emitter
*/
MethodEmitter getField(final String className, final String fieldName, final String fieldDescriptor) {
- debug("getfield", "receiver=" + peekType(), className + "." + fieldName + fieldDescriptor);
+ debug("getfield", "receiver=", peekType(), className, ".", fieldName, fieldDescriptor);
final Type receiver = popType();
assert receiver.isObject();
method.visitFieldInsn(GETFIELD, className, fieldName, fieldDescriptor);
@@ -1971,7 +1970,7 @@
* @return the method emitter
*/
MethodEmitter getStatic(final String className, final String fieldName, final String fieldDescriptor) {
- debug("getstatic", className + "." + fieldName + "." + fieldDescriptor);
+ debug("getstatic", className, ".", fieldName, ".", fieldDescriptor);
method.visitFieldInsn(GETSTATIC, className, fieldName, fieldDescriptor);
pushType(fieldType(fieldDescriptor));
return this;
@@ -1985,7 +1984,7 @@
* @param fieldDescriptor field descriptor
*/
void putField(final String className, final String fieldName, final String fieldDescriptor) {
- debug("putfield", "receiver=" + peekType(1), "value=" + peekType());
+ debug("putfield", "receiver=", peekType(1), "value=", peekType());
popType(fieldType(fieldDescriptor));
popType(Type.OBJECT);
method.visitFieldInsn(PUTFIELD, className, fieldName, fieldDescriptor);
@@ -1999,7 +1998,7 @@
* @param fieldDescriptor field descriptor
*/
void putStatic(final String className, final String fieldName, final String fieldDescriptor) {
- debug("putfield", "value=" + peekType());
+ debug("putfield", "value=", peekType());
popType(fieldType(fieldDescriptor));
method.visitFieldInsn(PUTSTATIC, className, fieldName, fieldDescriptor);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Thu Apr 25 14:20:23 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Thu Apr 25 14:47:17 2013 +0200
@@ -54,10 +54,24 @@
* @see SpillProperty
*/
public class AccessorProperty extends Property {
+ private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
private static final int NOOF_TYPES = getNumberOfAccessorTypes();
+ /**
+ * Properties in different maps for the same structure class will share their field getters and setters. This could
+ * be further extended to other method handles that are looked up in the AccessorProperty constructor, but right now
+ * these are the most frequently retrieved ones, and lookup of method handle natives only registers in the profiler
+ * for them.
+ */
+ private static ClassValue<GettersSetters> GETTERS_SETTERS = new ClassValue<GettersSetters>() {
+ @Override
+ protected GettersSetters computeValue(Class<?> structure) {
+ return new GettersSetters(structure);
+ }
+ };
+
/** Property getter cache */
private MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
@@ -152,6 +166,22 @@
setCurrentType(getterType);
}
+ private static class GettersSetters {
+ final MethodHandle[] getters;
+ final MethodHandle[] setters;
+
+ public GettersSetters(Class<?> structure) {
+ final int fieldCount = ObjectClassGenerator.getFieldCount(structure);
+ getters = new MethodHandle[fieldCount];
+ 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());
+ }
+ }
+ }
+
/**
* Constructor for dual field AccessorPropertys.
*
@@ -171,22 +201,19 @@
primitiveGetter = null;
primitiveSetter = null;
- final MethodHandles.Lookup lookup = MethodHandles.lookup();
-
if (isParameter() && hasArguments()) {
- final MethodHandle arguments = MH.getter(MethodHandles.lookup(), structure, "arguments", Object.class);
+ 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);
} else {
- final String fieldNameObject = ObjectClassGenerator.getFieldName(slot, Type.OBJECT);
- final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, ObjectClassGenerator.PRIMITIVE_TYPE);
-
- objectGetter = MH.getter(lookup, structure, fieldNameObject, Type.OBJECT.getTypeClass());
- objectSetter = MH.setter(lookup, structure, fieldNameObject, Type.OBJECT.getTypeClass());
+ 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());
}
@@ -365,7 +392,7 @@
}
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
- return MH.findStatic(MethodHandles.lookup(), AccessorProperty.class, name, MH.type(rtype, types));
+ return MH.findStatic(lookup, AccessorProperty.class, name, MH.type(rtype, types));
}
}