nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java
changeset 32781 d8f34ffbbc7a
parent 30390 357f9a3f9394
child 34732 6605efbe8447
equal deleted inserted replaced
32712:f61a63b7d1e5 32781:d8f34ffbbc7a
    34 
    34 
    35 /**
    35 /**
    36  * Base class for object creation code generation.
    36  * Base class for object creation code generation.
    37  * @param <T> value type
    37  * @param <T> value type
    38  */
    38  */
    39 public abstract class ObjectCreator<T> {
    39 public abstract class ObjectCreator<T> implements CodeGenerator.SplitLiteralCreator {
    40 
    40 
    41     /** List of keys & symbols to initiate in this ObjectCreator */
    41     /** List of keys & symbols to initiate in this ObjectCreator */
    42     final List<MapTuple<T>> tuples;
    42     final List<MapTuple<T>> tuples;
    43 
    43 
    44     /** Code generator */
    44     /** Code generator */
    67 
    67 
    68     /**
    68     /**
    69      * Generate code for making the object.
    69      * Generate code for making the object.
    70      * @param method Script method.
    70      * @param method Script method.
    71      */
    71      */
    72     protected abstract void makeObject(final MethodEmitter method);
    72     public void makeObject(final MethodEmitter method) {
       
    73         createObject(method);
       
    74         // We need to store the object in a temporary slot as populateRange expects to load the
       
    75         // object from a slot (as it is also invoked within split methods). Note that this also
       
    76         // helps optimistic continuations to handle the stack in case an optimistic assumption
       
    77         // fails during initialization (see JDK-8079269).
       
    78         final int objectSlot = method.getUsedSlotsWithLiveTemporaries();
       
    79         final Type objectType = method.peekType();
       
    80         method.storeTemp(objectType, objectSlot);
       
    81         populateRange(method, objectType, objectSlot, 0, tuples.size());
       
    82     }
       
    83 
       
    84     /**
       
    85      * Generate code for creating and initializing the object.
       
    86      * @param method the method emitter
       
    87      */
       
    88     protected abstract void createObject(final MethodEmitter method);
    73 
    89 
    74     /**
    90     /**
    75      * Construct the property map appropriate for the object.
    91      * Construct the property map appropriate for the object.
    76      * @return the newly created property map
    92      * @return the newly created property map
    77      */
    93      */
   123     protected boolean hasArguments() {
   139     protected boolean hasArguments() {
   124         return hasArguments;
   140         return hasArguments;
   125     }
   141     }
   126 
   142 
   127     /**
   143     /**
       
   144      * Get the class of objects created by this ObjectCreator
       
   145      * @return class of created object
       
   146      */
       
   147     abstract protected Class<? extends ScriptObject> getAllocatorClass();
       
   148 
       
   149     /**
   128      * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
   150      * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
   129      *
   151      *
   130      * @param value Value to load.
   152      * @param value Value to load.
   131      * @param type the type of the value to load
   153      * @param type the type of the value to load
   132      */
   154      */
   143     }
   165     }
   144 
   166 
   145     MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
   167     MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
   146         return loadTuple(method, tuple, true);
   168         return loadTuple(method, tuple, true);
   147     }
   169     }
   148 
       
   149     /**
       
   150      * If using optimistic typing, let the code generator realize that the newly created object on the stack
       
   151      * when DUP-ed will be the same value. Basically: {NEW, DUP, INVOKESPECIAL init, DUP} will leave a stack
       
   152      * load specification {unknown, unknown} on stack (that is "there's two values on the stack, but neither
       
   153      * comes from a known local load"). If there's an optimistic operation in the literal initializer,
       
   154      * OptimisticOperation.storeStack will allocate two temporary locals for it and store them as
       
   155      * {ASTORE 4, ASTORE 3}. If we instead do {NEW, DUP, INVOKESPECIAL init, ASTORE 3, ALOAD 3, DUP} we end up
       
   156      * with stack load specification {ALOAD 3, ALOAD 3} (as DUP can track that the value it duplicated came
       
   157      * from a local load), so if/when a continuation needs to be recreated from it, it'll be
       
   158      * able to emit ALOAD 3, ALOAD 3 to recreate the stack. If we didn't do this, deoptimization within an
       
   159      * object literal initialization could in rare cases cause an incompatible change in the shape of the
       
   160      * local variable table for the temporaries, e.g. in the following snippet where a variable is reassigned
       
   161      * to a wider type in an object initializer:
       
   162      * <code>var m = 1; var obj = {p0: m, p1: m = "foo", p2: m}</code>
       
   163      * @param method the current method emitter.
       
   164      */
       
   165     void helpOptimisticRecognizeDuplicateIdentity(final MethodEmitter method) {
       
   166         if (codegen.useOptimisticTypes()) {
       
   167             final Type objectType = method.peekType();
       
   168             final int tempSlot = method.defineTemporaryLocalVariable(objectType.getSlots());
       
   169             method.storeHidden(objectType, tempSlot);
       
   170             method.load(objectType, tempSlot);
       
   171         }
       
   172     }
       
   173 }
   170 }