Thu, 11 Jul 2013 18:33:33 +0200
8013925: Remove symbol fields from nodes that don't need them
Reviewed-by: jlaskey, lagergren
1 /*
2 * Copyright (c) 2010-2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package jdk.nashorn.internal.codegen;
28 import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
29 import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
31 import java.util.List;
32 import jdk.nashorn.internal.codegen.types.Type;
33 import jdk.nashorn.internal.ir.Expression;
34 import jdk.nashorn.internal.ir.LiteralNode;
35 import jdk.nashorn.internal.ir.Symbol;
36 import jdk.nashorn.internal.runtime.Property;
37 import jdk.nashorn.internal.runtime.PropertyMap;
38 import jdk.nashorn.internal.runtime.ScriptObject;
39 import jdk.nashorn.internal.scripts.JO;
41 /**
42 * An object creator that uses spill properties.
43 */
44 public class SpillObjectCreator extends ObjectCreator {
46 private final List<Expression> values;
48 /**
49 * Constructor
50 *
51 * @param codegen code generator
52 * @param keys keys for fields in object
53 * @param symbols symbols for fields in object
54 * @param values list of values corresponding to keys
55 */
56 protected SpillObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<Expression> values) {
57 super(codegen, keys, symbols, false, false);
58 this.values = values;
59 makeMap();
60 }
62 @Override
63 protected void makeObject(final MethodEmitter method) {
64 assert !isScope() : "spill scope objects are not currently supported";
66 final int length = keys.size();
67 final Object[] presetValues = new Object[propertyMap.size()];
68 final Class clazz = JO.class;
70 // Compute constant values
71 for (int i = 0; i < length; i++) {
72 final String key = keys.get(i);
73 final Property property = propertyMap.findProperty(key);
75 if (property != null) {
76 presetValues[property.getSlot()] = LiteralNode.objectAsConstant(values.get(i));
77 }
78 }
80 method._new(clazz).dup();
81 codegen.loadConstant(propertyMap);
83 method.invoke(constructorNoLookup(JO.class, PropertyMap.class));
85 method.dup();
86 codegen.loadConstant(presetValues);
88 // Create properties with non-constant values
89 for (int i = 0; i < length; i++) {
90 final String key = keys.get(i);
91 final Property property = propertyMap.findProperty(key);
93 if (property != null && presetValues[property.getSlot()] == LiteralNode.POSTSET_MARKER) {
94 method.dup();
95 method.load(property.getSlot());
96 codegen.load(values.get(i)).convert(OBJECT);
97 method.arraystore();
98 presetValues[property.getSlot()] = null;
99 }
100 }
102 method.putField(Type.typeFor(ScriptObject.class).getInternalName(), "spill", Type.OBJECT_ARRAY.getDescriptor());
103 final int callSiteFlags = codegen.getCallSiteFlags();
105 // Assign properties with valid array index keys
106 for (int i = 0; i < length; i++) {
107 final String key = keys.get(i);
108 final Property property = propertyMap.findProperty(key);
109 final Expression value = values.get(i);
111 if (property == null && value != null) {
112 method.dup();
113 method.load(keys.get(i));
114 codegen.load(value);
115 method.dynamicSetIndex(callSiteFlags);
116 }
117 }
118 }
120 @Override
121 protected PropertyMap makeMap() {
122 assert propertyMap == null : "property map already initialized";
124 propertyMap = new MapCreator(JO.class, keys, symbols) {
125 @Override
126 protected int getPropertyFlags(Symbol symbol, boolean hasArguments) {
127 return super.getPropertyFlags(symbol, hasArguments) | Property.IS_SPILL | Property.IS_ALWAYS_OBJECT;
128 }
129 }.makeSpillMap(false);
131 return propertyMap;
132 }
133 }