Tue, 30 Apr 2013 10:05:42 -0300
8006220: Simplify PropertyMaps
Reviewed-by: hannesw, lagergren
Contributed-by: james.laskey@oracle.com
jlaskey@3 | 1 | /* |
jlaskey@7 | 2 | * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
jlaskey@3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jlaskey@3 | 4 | * |
jlaskey@3 | 5 | * This code is free software; you can redistribute it and/or modify it |
jlaskey@3 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jlaskey@3 | 7 | * published by the Free Software Foundation. Oracle designates this |
jlaskey@3 | 8 | * particular file as subject to the "Classpath" exception as provided |
jlaskey@3 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
jlaskey@3 | 10 | * |
jlaskey@3 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jlaskey@3 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jlaskey@3 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jlaskey@3 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
jlaskey@3 | 15 | * accompanied this code). |
jlaskey@3 | 16 | * |
jlaskey@3 | 17 | * You should have received a copy of the GNU General Public License version |
jlaskey@3 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
jlaskey@3 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jlaskey@3 | 20 | * |
jlaskey@3 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
jlaskey@3 | 22 | * or visit www.oracle.com if you need additional information or have any |
jlaskey@3 | 23 | * questions. |
jlaskey@3 | 24 | */ |
jlaskey@3 | 25 | |
lagergren@96 | 26 | package jdk.nashorn.internal.codegen; |
jlaskey@3 | 27 | |
jlaskey@3 | 28 | import java.util.List; |
jlaskey@242 | 29 | import static jdk.nashorn.internal.codegen.ObjectClassGenerator.FIELD_PADDING; |
jlaskey@242 | 30 | import static jdk.nashorn.internal.codegen.ObjectClassGenerator.FIELD_ROUNDING; |
jlaskey@3 | 31 | import jdk.nashorn.internal.ir.Symbol; |
jlaskey@3 | 32 | import jdk.nashorn.internal.runtime.Context; |
jlaskey@3 | 33 | import jdk.nashorn.internal.runtime.PropertyMap; |
jlaskey@3 | 34 | |
jlaskey@3 | 35 | /** |
jlaskey@3 | 36 | * Base class for object creation code generation. |
jlaskey@3 | 37 | */ |
jlaskey@3 | 38 | public abstract class ObjectCreator { |
jlaskey@3 | 39 | |
jlaskey@3 | 40 | /** Compile unit for this ObjectCreator, see CompileUnit */ |
lagergren@211 | 41 | //protected final CompileUnit compileUnit; |
jlaskey@3 | 42 | |
jlaskey@3 | 43 | /** List of keys to initiate in this ObjectCreator */ |
jlaskey@3 | 44 | protected final List<String> keys; |
jlaskey@3 | 45 | |
jlaskey@3 | 46 | /** List of symbols to initiate in this ObjectCreator */ |
jlaskey@3 | 47 | protected final List<Symbol> symbols; |
jlaskey@3 | 48 | |
jlaskey@3 | 49 | /** Code generator */ |
jlaskey@3 | 50 | protected final CodeGenerator codegen; |
jlaskey@3 | 51 | |
jlaskey@3 | 52 | private final boolean isScope; |
jlaskey@80 | 53 | private final boolean hasArguments; |
jlaskey@3 | 54 | private int fieldCount; |
jlaskey@242 | 55 | private int paddedFieldCount; |
jlaskey@3 | 56 | private int paramCount; |
jlaskey@3 | 57 | private String fieldObjectClassName; |
jlaskey@3 | 58 | private Class<?> fieldObjectClass; |
jlaskey@3 | 59 | private PropertyMap propertyMap; |
jlaskey@3 | 60 | |
jlaskey@3 | 61 | /** |
jlaskey@3 | 62 | * Constructor |
jlaskey@3 | 63 | * |
jlaskey@80 | 64 | * @param codegen the code generator |
jlaskey@80 | 65 | * @param keys the keys |
jlaskey@80 | 66 | * @param symbols the symbols corresponding to keys, same index |
jlaskey@80 | 67 | * @param isScope is this object scope |
jlaskey@80 | 68 | * @param hasArguments does the created object have an "arguments" property |
jlaskey@3 | 69 | */ |
jlaskey@80 | 70 | protected ObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final boolean isScope, final boolean hasArguments) { |
jlaskey@3 | 71 | this.codegen = codegen; |
jlaskey@3 | 72 | this.keys = keys; |
jlaskey@3 | 73 | this.symbols = symbols; |
jlaskey@3 | 74 | this.isScope = isScope; |
jlaskey@80 | 75 | this.hasArguments = hasArguments; |
jlaskey@3 | 76 | |
jlaskey@3 | 77 | countFields(); |
jlaskey@3 | 78 | findClass(); |
jlaskey@3 | 79 | } |
jlaskey@3 | 80 | |
jlaskey@3 | 81 | /** |
jlaskey@3 | 82 | * Tally the number of fields and parameters. |
jlaskey@3 | 83 | */ |
jlaskey@3 | 84 | private void countFields() { |
jlaskey@3 | 85 | for (final Symbol symbol : this.symbols) { |
jlaskey@3 | 86 | if (symbol != null) { |
jlaskey@80 | 87 | if (hasArguments() && symbol.isParam()) { |
jlaskey@3 | 88 | symbol.setFieldIndex(paramCount++); |
jlaskey@3 | 89 | } else { |
jlaskey@3 | 90 | symbol.setFieldIndex(fieldCount++); |
jlaskey@3 | 91 | } |
jlaskey@3 | 92 | } |
jlaskey@3 | 93 | } |
jlaskey@242 | 94 | |
jlaskey@242 | 95 | paddedFieldCount = (fieldCount + FIELD_PADDING + FIELD_ROUNDING - 1) / FIELD_ROUNDING * FIELD_ROUNDING; |
jlaskey@3 | 96 | } |
jlaskey@3 | 97 | |
jlaskey@3 | 98 | /** |
jlaskey@3 | 99 | * Locate (or indirectly create) the object container class. |
jlaskey@3 | 100 | */ |
jlaskey@3 | 101 | private void findClass() { |
jlaskey@3 | 102 | fieldObjectClassName = isScope() ? |
jlaskey@3 | 103 | ObjectClassGenerator.getClassName(fieldCount, paramCount) : |
jlaskey@242 | 104 | ObjectClassGenerator.getClassName(paddedFieldCount); |
jlaskey@3 | 105 | |
jlaskey@3 | 106 | try { |
jlaskey@3 | 107 | this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName)); |
jlaskey@3 | 108 | } catch (final ClassNotFoundException e) { |
jlaskey@3 | 109 | throw new AssertionError("Nashorn has encountered an internal error. Structure can not be created."); |
jlaskey@3 | 110 | } |
jlaskey@3 | 111 | } |
jlaskey@3 | 112 | |
jlaskey@3 | 113 | /** |
jlaskey@3 | 114 | * Generate code for making the object. |
jlaskey@3 | 115 | * @param method Script method. |
jlaskey@3 | 116 | */ |
lagergren@96 | 117 | protected abstract void makeObject(final MethodEmitter method); |
jlaskey@3 | 118 | |
jlaskey@3 | 119 | /** |
jlaskey@3 | 120 | * Create a new MapCreator |
jlaskey@3 | 121 | * @param clazz type of MapCreator |
jlaskey@3 | 122 | * @return map creator instantiated by type |
jlaskey@3 | 123 | */ |
jlaskey@3 | 124 | protected MapCreator newMapCreator(final Class<?> clazz) { |
jlaskey@3 | 125 | return new MapCreator(clazz, keys, symbols); |
jlaskey@3 | 126 | } |
jlaskey@3 | 127 | |
jlaskey@3 | 128 | /** |
jlaskey@3 | 129 | * Construct the property map appropriate for the object. |
hannesw@72 | 130 | * @return the newly created property map |
jlaskey@3 | 131 | */ |
hannesw@72 | 132 | protected PropertyMap makeMap() { |
jlaskey@242 | 133 | propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments(), fieldCount, paddedFieldCount); |
hannesw@72 | 134 | return propertyMap; |
jlaskey@3 | 135 | } |
jlaskey@3 | 136 | |
jlaskey@3 | 137 | /** |
jlaskey@3 | 138 | * Emit the correct map for the object. |
jlaskey@3 | 139 | * @param method method emitter |
jlaskey@3 | 140 | * @return the method emitter |
jlaskey@3 | 141 | */ |
jlaskey@3 | 142 | protected MethodEmitter loadMap(final MethodEmitter method) { |
jlaskey@3 | 143 | codegen.loadConstant(propertyMap); |
jlaskey@3 | 144 | return method; |
jlaskey@3 | 145 | } |
jlaskey@3 | 146 | |
jlaskey@3 | 147 | /** |
jlaskey@3 | 148 | * Get the class name for the object class, |
jlaskey@131 | 149 | * e.g. {@code com.nashorn.oracle.scripts.JO2P0} |
jlaskey@3 | 150 | * |
jlaskey@3 | 151 | * @return script class name |
jlaskey@3 | 152 | */ |
lagergren@96 | 153 | String getClassName() { |
jlaskey@3 | 154 | return fieldObjectClassName; |
jlaskey@3 | 155 | } |
jlaskey@3 | 156 | |
jlaskey@3 | 157 | /** |
jlaskey@3 | 158 | * Is this a scope object |
jlaskey@3 | 159 | * @return true if scope |
jlaskey@3 | 160 | */ |
jlaskey@3 | 161 | protected boolean isScope() { |
jlaskey@3 | 162 | return isScope; |
jlaskey@3 | 163 | } |
jlaskey@3 | 164 | |
jlaskey@3 | 165 | /** |
jlaskey@80 | 166 | * Does the created object have an "arguments" property |
jlaskey@80 | 167 | * @return true if has an "arguments" property |
jlaskey@3 | 168 | */ |
jlaskey@80 | 169 | protected boolean hasArguments() { |
jlaskey@80 | 170 | return hasArguments; |
jlaskey@3 | 171 | } |
jlaskey@3 | 172 | } |