nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java
changeset 32781 d8f34ffbbc7a
parent 30390 357f9a3f9394
child 33690 46a1bc24cf2c
equal deleted inserted replaced
32712:f61a63b7d1e5 32781:d8f34ffbbc7a
    59         super(codegen, tuples, false, false);
    59         super(codegen, tuples, false, false);
    60         makeMap();
    60         makeMap();
    61     }
    61     }
    62 
    62 
    63     @Override
    63     @Override
    64     protected void makeObject(final MethodEmitter method) {
    64     public void createObject(final MethodEmitter method) {
    65         assert !isScope() : "spill scope objects are not currently supported";
    65         assert !isScope() : "spill scope objects are not currently supported";
    66 
    66 
    67         final int          length        = tuples.size();
    67         final int          length        = tuples.size();
    68         final boolean      dualFields    = codegen.useDualFields();
    68         final boolean      dualFields    = codegen.useDualFields();
    69         final int          spillLength   = ScriptObject.spillAllocationLength(length);
    69         final int          spillLength   = ScriptObject.spillAllocationLength(length);
    70         final long[]       jpresetValues = dualFields ? new long[spillLength] : null;
    70         final long[]       jpresetValues = dualFields ? new long[spillLength] : null;
    71         final Object[]     opresetValues = new Object[spillLength];
    71         final Object[]     opresetValues = new Object[spillLength];
    72         final Set<Integer> postsetValues = new LinkedHashSet<>();
    72         final Class<?>     objectClass   = getAllocatorClass();
    73         final int          callSiteFlags = codegen.getCallSiteFlags();
       
    74         final Class<?>     objectClass   = dualFields ? JD.class : JO.class;
       
    75         ArrayData          arrayData     = ArrayData.allocate(ScriptRuntime.EMPTY_ARRAY);
    73         ArrayData          arrayData     = ArrayData.allocate(ScriptRuntime.EMPTY_ARRAY);
    76 
    74 
    77         // Compute constant property values
    75         // Compute constant property values
    78         int pos = 0;
    76         int pos = 0;
    79         for (final MapTuple<Expression> tuple : tuples) {
    77         for (final MapTuple<Expression> tuple : tuples) {
    83             //this is a nop of tuple.key isn't e.g. "apply" or another special name
    81             //this is a nop of tuple.key isn't e.g. "apply" or another special name
    84             method.invalidateSpecialName(tuple.key);
    82             method.invalidateSpecialName(tuple.key);
    85 
    83 
    86             if (value != null) {
    84             if (value != null) {
    87                 final Object constantValue = LiteralNode.objectAsConstant(value);
    85                 final Object constantValue = LiteralNode.objectAsConstant(value);
    88                 if (constantValue == LiteralNode.POSTSET_MARKER) {
    86                 if (constantValue != LiteralNode.POSTSET_MARKER) {
    89                     postsetValues.add(pos);
       
    90                 } else {
       
    91                     final Property property = propertyMap.findProperty(key);
    87                     final Property property = propertyMap.findProperty(key);
    92                     if (property != null) {
    88                     if (property != null) {
    93                         // normal property key
    89                         // normal property key
    94                         property.setType(dualFields ? JSType.unboxedFieldType(constantValue) : Object.class);
    90                         property.setType(dualFields ? JSType.unboxedFieldType(constantValue) : Object.class);
    95                         final int slot = property.getSlot();
    91                         final int slot = property.getSlot();
   144         codegen.loadConstant(opresetValues);
   140         codegen.loadConstant(opresetValues);
   145 
   141 
   146         // instantiate the script object with spill objects
   142         // instantiate the script object with spill objects
   147         method.invoke(constructorNoLookup(objectClass, PropertyMap.class, long[].class, Object[].class));
   143         method.invoke(constructorNoLookup(objectClass, PropertyMap.class, long[].class, Object[].class));
   148 
   144 
   149         helpOptimisticRecognizeDuplicateIdentity(method);
       
   150 
       
   151         // Set prefix array data if any
   145         // Set prefix array data if any
   152         if (arrayData.length() > 0) {
   146         if (arrayData.length() > 0) {
   153             method.dup();
   147             method.dup();
   154             codegen.loadConstant(arrayData);
   148             codegen.loadConstant(arrayData);
   155             method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray", void.class, ArrayData.class));
   149             method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray", void.class, ArrayData.class));
   156         }
   150         }
       
   151     }
       
   152 
       
   153     @Override
       
   154     public void populateRange(final MethodEmitter method, final Type objectType, final int objectSlot, final int start, final int end) {
       
   155         final int  callSiteFlags = codegen.getCallSiteFlags();
       
   156         method.load(objectType, objectSlot);
   157 
   157 
   158         // set postfix values
   158         // set postfix values
   159         for (final int i : postsetValues) {
   159         for (int i = start; i < end; i++) {
   160             final MapTuple<Expression> tuple = tuples.get(i);
   160             final MapTuple<Expression> tuple = tuples.get(i);
       
   161 
       
   162             if (LiteralNode.isConstant(tuple.value)) {
       
   163                 continue;
       
   164             }
       
   165 
   161             final Property property = propertyMap.findProperty(tuple.key);
   166             final Property property = propertyMap.findProperty(tuple.key);
       
   167 
   162             if (property == null) {
   168             if (property == null) {
   163                 final int index = ArrayIndex.getArrayIndex(tuple.key);
   169                 final int index = ArrayIndex.getArrayIndex(tuple.key);
   164                 assert ArrayIndex.isValidArrayIndex(index);
   170                 assert ArrayIndex.isValidArrayIndex(index);
   165                 method.dup();
   171                 method.dup();
   166                 method.load(ArrayIndex.toLongIndex(index));
   172                 method.load(ArrayIndex.toLongIndex(index));
   167                 //method.println("putting " + tuple + " into arraydata");
       
   168                 loadTuple(method, tuple);
   173                 loadTuple(method, tuple);
   169                 method.dynamicSetIndex(callSiteFlags);
   174                 method.dynamicSetIndex(callSiteFlags);
   170             } else {
   175             } else {
   171                 method.dup();
   176                 method.dup();
   172                 loadTuple(method, tuple);
   177                 loadTuple(method, tuple);
   176     }
   181     }
   177 
   182 
   178     @Override
   183     @Override
   179     protected PropertyMap makeMap() {
   184     protected PropertyMap makeMap() {
   180         assert propertyMap == null : "property map already initialized";
   185         assert propertyMap == null : "property map already initialized";
   181         final boolean dualFields = codegen.useDualFields();
   186         final Class<? extends ScriptObject> clazz = getAllocatorClass();
   182         final Class<? extends ScriptObject> clazz = dualFields ? JD.class : JO.class;
       
   183         propertyMap = new MapCreator<>(clazz, tuples).makeSpillMap(false, codegen.useDualFields());
   187         propertyMap = new MapCreator<>(clazz, tuples).makeSpillMap(false, codegen.useDualFields());
   184         return propertyMap;
   188         return propertyMap;
   185     }
   189     }
   186 
   190 
   187     @Override
   191     @Override
   188     protected void loadValue(final Expression expr, final Type type) {
   192     protected void loadValue(final Expression expr, final Type type) {
   189         codegen.loadExpressionAsType(expr, type);
   193         codegen.loadExpressionAsType(expr, type);
   190     }
   194     }
       
   195 
       
   196     @Override
       
   197     protected Class<? extends ScriptObject> getAllocatorClass() {
       
   198         return codegen.useDualFields() ? JD.class : JO.class;
       
   199     }
   191 }
   200 }