nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
author sundar
Tue, 25 Jun 2013 17:31:19 +0530
changeset 18615 3f6e6adcbc1a
parent 17774 0407501fa563
child 18847 31ca64473a86
permissions -rw-r--r--
8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223 Reviewed-by: hannesw, jlaskey
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    28
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.ACCESSOR_TYPES;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    29
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    30
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.LOG;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    31
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    32
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_TYPE;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    33
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    34
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGuardBoxedPrimitiveSetter;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    35
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    36
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorType;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    37
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorTypeIndex;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    38
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getNumberOfAccessorTypes;
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16275
diff changeset
    39
import static jdk.nashorn.internal.lookup.Lookup.MH;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16275
diff changeset
    40
import static jdk.nashorn.internal.lookup.MethodHandleFactory.stripName;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.lang.invoke.MethodHandles;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import java.lang.invoke.MethodType;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16224
diff changeset
    45
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import jdk.nashorn.internal.codegen.types.Type;
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16275
diff changeset
    47
import jdk.nashorn.internal.lookup.Lookup;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16275
diff changeset
    48
import jdk.nashorn.internal.lookup.MethodHandleFactory;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
 * An AccessorProperty is the most generic property type. An AccessorProperty is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
 * represented as fields in a ScriptObject class.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
public class AccessorProperty extends Property {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    55
    private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
    private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
    private static final int NOOF_TYPES = getNumberOfAccessorTypes();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    60
    /**
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    61
     * Properties in different maps for the same structure class will share their field getters and setters. This could
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    62
     * be further extended to other method handles that are looked up in the AccessorProperty constructor, but right now
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    63
     * these are the most frequently retrieved ones, and lookup of method handle natives only registers in the profiler
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    64
     * for them.
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    65
     */
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    66
    private static ClassValue<GettersSetters> GETTERS_SETTERS = new ClassValue<GettersSetters>() {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    67
        @Override
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    68
        protected GettersSetters computeValue(Class<?> structure) {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    69
            return new GettersSetters(structure);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    70
        }
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    71
    };
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
    72
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
    /** Property getter cache */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
    private MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
    private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
    private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    78
    private static final MethodHandle SPILL_ELEMENT_GETTER;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    79
    private static final MethodHandle SPILL_ELEMENT_SETTER;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    80
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    81
    private static final int SPILL_CACHE_SIZE = 8;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    82
    private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    83
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    84
    static {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    85
        for (int i = 0; i < NOOF_TYPES; i++) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    86
            final Type type = ACCESSOR_TYPES.get(i);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    87
            ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    88
            ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    89
        }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    90
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    91
        final MethodHandle spillGetter = MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    92
        SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    93
        SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
    94
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
    /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
    private MethodHandle primitiveGetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
    /** Seed setter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
    private MethodHandle primitiveSetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
    /** Seed getter for the Object version of this field */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
    private MethodHandle objectGetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   104
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
    /** Seed setter for the Object version of this field */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
    private MethodHandle objectSetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
     * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
     * null means undefined, and primitive types are allowed. The reason a special type is used for
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
     * undefined, is that are no bits left to represent it in primitive types
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
    private Class<?> currentType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   116
     * Delegate constructor. This is used when adding properties to the Global scope, which
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
     * is necessary for outermost levels in a script (the ScriptObject is represented by
16275
d5d430071b22 8009379: Remove $ from generated class names
jlaskey
parents: 16240
diff changeset
   118
     * a JO-prefixed ScriptObject class, but the properties need to be in the Global scope
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
     * and are thus rebound with that as receiver
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
     * @param property  accessor property to rebind
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
     * @param delegate  delegate script object to rebind receiver to
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
    public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) {
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   125
        super(property);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   126
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   127
        this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   128
        this.primitiveSetter = bindTo(property.primitiveSetter, delegate);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   129
        this.objectGetter    = bindTo(property.objectGetter, delegate);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   130
        this.objectSetter    = bindTo(property.objectSetter, delegate);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
        setCurrentType(property.getCurrentType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
    /**
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   136
     * Constructor for spill properties. Array getters and setters will be created on demand.
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   137
     *
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   138
     * @param key    the property key
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   139
     * @param flags  the property flags
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   140
     * @param slot   spill slot
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   141
     */
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   142
    public AccessorProperty(final String key, final int flags, final int slot) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   143
        super(key, flags, slot);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   144
        assert (flags & IS_SPILL) == IS_SPILL;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   145
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   146
        setCurrentType(Object.class);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   147
    }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   148
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   149
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
     * Constructor. Similar to the constructor with both primitive getters and setters, the difference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
     * here being that only one getter and setter (setter is optional for non writable fields) is given
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
     * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   154
     * @param key    the property key
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
     * @param flags  the property flags
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   156
     * @param slot   the property field number or spill slot
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
     * @param getter the property getter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
     * @param setter the property setter or null if non writable, non configurable
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
     */
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   160
    public AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   161
        super(key, flags, slot);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
        // we don't need to prep the setters these will never be invalidated as this is a nasgen
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
        // or known type getter/setter. No invalidations will take place
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
        final Class<?> getterType = getter.type().returnType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
        final Class<?> setterType = setter == null ? null : setter.type().parameterType(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
        assert setterType == null || setterType == getterType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
        if (getterType.isPrimitive()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
            for (int i = 0; i < NOOF_TYPES; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   173
                getters[i] = MH.asType(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
                    Lookup.filterReturnType(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
                        getter,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   176
                        getAccessorType(i).getTypeClass()),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   177
                    ACCESSOR_GETTER_TYPES[i]);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   178
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   179
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   180
            //this will work as the object setter and getter will be converted appropriately
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
            objectGetter = getter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
            objectSetter = setter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
        setCurrentType(getterType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   188
    private static class GettersSetters {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   189
        final MethodHandle[] getters;
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   190
        final MethodHandle[] setters;
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   191
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   192
        public GettersSetters(Class<?> structure) {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   193
            final int fieldCount = ObjectClassGenerator.getFieldCount(structure);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   194
            getters = new MethodHandle[fieldCount];
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   195
            setters = new MethodHandle[fieldCount];
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   196
            for(int i = 0; i < fieldCount; ++i) {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   197
                final String fieldName = ObjectClassGenerator.getFieldName(i, Type.OBJECT);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   198
                getters[i] = MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   199
                setters[i] = MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   200
            }
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   201
        }
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   202
    }
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   203
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
    /**
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   205
     * Constructor for dual field AccessorPropertys.
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   206
     *
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   207
     * @param key              property key
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   208
     * @param flags            property flags
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   209
     * @param structure        structure for objects associated with this property
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   210
     * @param slot             property field number or spill slot
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   211
     */
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   212
    public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot) {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   213
        super(key, flags, slot);
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   214
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   215
        /*
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   216
         * primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   217
         * works in dual field mode, it only means that the property never has a primitive
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   218
         * representation.
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   219
         */
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   220
        primitiveGetter = null;
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   221
        primitiveSetter = null;
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   222
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   223
        if (isParameter() && hasArguments()) {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   224
            final MethodHandle arguments   = MH.getter(lookup, structure, "arguments", Object.class);
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   225
            final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class));
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   226
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   227
            objectGetter = MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   228
            objectSetter = MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   229
        } else {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   230
            final GettersSetters gs = GETTERS_SETTERS.get(structure);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   231
            objectGetter = gs.getters[slot];
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   232
            objectSetter = gs.setters[slot];
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   233
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   234
            if (!OBJECT_FIELDS_ONLY) {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   235
                final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, ObjectClassGenerator.PRIMITIVE_TYPE);
16224
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   236
                primitiveGetter = MH.getter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   237
                primitiveSetter = MH.setter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   238
            }
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   239
        }
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   240
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   241
        Class<?> initialType = null;
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   242
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   243
        if (OBJECT_FIELDS_ONLY || isAlwaysObject()) {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   244
            initialType = Object.class;
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   245
        } else if (!canBePrimitive()) {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   246
            info(key + " cannot be primitive");
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   247
            initialType = Object.class;
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   248
        } else {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   249
            info(key + " CAN be primitive");
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   250
            if (!canBeUndefined()) {
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   251
                info(key + " is always defined");
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   252
                initialType = int.class; //double works too for less type invalidation, but this requires experimentation, e.g. var x = 17; x += 2 will turn it into double now because of lack of range analysis
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   253
            }
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   254
        }
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   255
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   256
        // is always object means "is never initialized to undefined, and always of object type
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   257
        setCurrentType(initialType);
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   258
    }
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   259
0c49ad4e3b55 8006222: Move slot from SpillProperty to Property
jlaskey
parents: 16151
diff changeset
   260
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
     * Copy constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
     * @param property  source property
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
    protected AccessorProperty(final AccessorProperty property) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
        super(property);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   268
        this.getters         = property.getters;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   269
        this.primitiveGetter = property.primitiveGetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
        this.primitiveSetter = property.primitiveSetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
        this.objectGetter    = property.objectGetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
        this.objectSetter    = property.objectSetter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
        setCurrentType(property.getCurrentType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   275
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   277
    private static MethodHandle bindTo(final MethodHandle mh, final Object receiver) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
        if (mh == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   281
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
        return MH.dropArguments(MH.bindTo(mh, receiver), 0, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   283
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   284
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   285
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   286
    protected Property copy() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
        return new AccessorProperty(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   288
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
    @Override
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 17774
diff changeset
   291
    public void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   292
        if (isSpill()) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   293
            self.spill[getSlot()] = value;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   294
        } else {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   295
            try {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   296
                getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   297
            } catch (final Error|RuntimeException e) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   298
                throw e;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   299
            } catch (final Throwable e) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   300
                throw new RuntimeException(e);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   301
            }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   302
        }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   303
    }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   304
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   305
    @Override
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 17774
diff changeset
   306
    public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   307
        if (isSpill()) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   308
            return self.spill[getSlot()];
17774
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   309
        }
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   310
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   311
        try {
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   312
            return getGetter(Object.class).invokeExact((Object)self);
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   313
        } catch (final Error|RuntimeException e) {
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   314
            throw e;
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   315
        } catch (final Throwable e) {
0407501fa563 8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents: 17770
diff changeset
   316
            throw new RuntimeException(e);
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   317
        }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   318
    }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   319
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   320
    @Override
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
    public MethodHandle getGetter(final Class<?> type) {
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   322
        if (isSpill() && objectGetter == null) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   323
            objectGetter = getSpillGetter();
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   324
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   325
        final int i = getAccessorTypeIndex(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
        if (getters[i] == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
            getters[i] = debug(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
                MH.asType(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
                    createGetter(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
                        currentType,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
                        type,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
                        primitiveGetter,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
                        objectGetter),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
                    ACCESSOR_GETTER_TYPES[i]),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
                currentType,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
                type,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
                "get");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   340
        return getters[i];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   342
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   343
    private Property getWiderProperty(final Class<?> type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
        final AccessorProperty newProperty = new AccessorProperty(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
        newProperty.invalidate(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   346
        return newProperty;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   347
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   348
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
    private PropertyMap getWiderMap(final PropertyMap oldMap, final Property newProperty) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
        final PropertyMap newMap = oldMap.replaceProperty(this, newProperty);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
        assert oldMap.size() > 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
        assert newMap.size() == oldMap.size();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   354
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
    // the final three arguments are for debug printout purposes only
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
    @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
    private static Object replaceMap(final Object sobj, final PropertyMap newMap, final String key, final Class<?> oldType, final Class<?> newType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
        if (DEBUG_FIELDS) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
            final PropertyMap oldMap = ((ScriptObject)sobj).getMap();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
            info("Type change for '" + key + "' " + oldType + "=>" + newType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
            finest("setting map " + sobj + " from " + Debug.id(oldMap) + " to " + Debug.id(newMap) + " " + oldMap + " => " + newMap);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
        ((ScriptObject)sobj).setMap(newMap);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
        return sobj;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
    private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   369
        if (isSpill() && objectSetter == null) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   370
            objectSetter = getSpillSetter();
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   371
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
        MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   373
        mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
        mh = debug(mh, currentType, type, "set");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
        return mh;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   377
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   379
    public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   380
        final int i            = getAccessorTypeIndex(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   381
        final int ci           = currentType == null ? -1 : getAccessorTypeIndex(currentType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
        final Class<?> forType = currentType == null ? type : currentType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
        //if we are asking for an object setter, but are still a primitive type, we might try to box it
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   385
        MethodHandle mh;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
        if (needsInvalidator(i, ci)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
            final Property     newProperty = getWiderProperty(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
            final PropertyMap  newMap      = getWiderMap(currentMap, newProperty);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
            final MethodHandle widerSetter = newProperty.getSetter(type, newMap);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   391
            final MethodHandle explodeTypeSetter = MH.filterArguments(widerSetter, 0, MH.insertArguments(REPLACE_MAP, 1, newMap, getKey(), currentType, type));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
            if (currentType != null && currentType.isPrimitive() && type == Object.class) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
                //might try a box check on this to avoid widening field to object storage
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   394
                mh = createGuardBoxedPrimitiveSetter(currentType, generateSetter(currentType, currentType), explodeTypeSetter);
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   395
            } else {
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   396
                mh = explodeTypeSetter;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
            }
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   398
        } else {
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 17246
diff changeset
   399
            mh = generateSetter(forType, type);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   402
        return mh;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   404
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   406
    public boolean canChangeType() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   407
        if (OBJECT_FIELDS_ONLY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   408
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   410
        return currentType != Object.class && (isConfigurable() || isWritable());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
    private boolean needsInvalidator(final int ti, final int fti) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
        return canChangeType() && ti > fti;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
    private void invalidate(final Class<?> newType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
        getters = new MethodHandle[NOOF_TYPES];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
        setCurrentType(newType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
17770
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   422
    private MethodHandle getSpillGetter() {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   423
        final int slot = getSlot();
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   424
        MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   425
        if (getter == null) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   426
            getter = MH.asType(MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot), Lookup.GET_OBJECT_TYPE);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   427
            if (slot < SPILL_CACHE_SIZE) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   428
                SPILL_ACCESSORS[slot * 2] = getter;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   429
            }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   430
        }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   431
        return getter;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   432
    }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   433
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   434
    private MethodHandle getSpillSetter() {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   435
        final int slot = getSlot();
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   436
        MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   437
        if (setter == null) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   438
            setter = MH.asType(MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot), Lookup.SET_OBJECT_TYPE);
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   439
            if (slot < SPILL_CACHE_SIZE) {
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   440
                SPILL_ACCESSORS[slot * 2 + 1] = setter;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   441
            }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   442
        }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   443
        return setter;
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   444
    }
3c8602ec5565 8011630: JSON parsing performance issue
hannesw
parents: 17513
diff changeset
   445
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
    private static void finest(final String str) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
        if (DEBUG_FIELDS) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
            LOG.finest(str);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
    private static void info(final String str) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
        if (DEBUG_FIELDS) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
            LOG.info(str);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
    private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
        if (DEBUG_FIELDS) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   460
           return MethodHandleFactory.addDebugPrintout(
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
               LOG,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
               mh,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
               tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", forType=" + stripName(forType) + ", type=" + stripName(type) + ')');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   465
        return mh;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   466
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   467
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
    private void setCurrentType(final Class<?> currentType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   469
        this.currentType = currentType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
    public Class<?> getCurrentType() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
        return currentType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16523
diff changeset
   478
        return MH.findStatic(lookup, AccessorProperty.class, name, MH.type(rtype, types));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
}