src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
author hannesw
Wed, 21 Mar 2018 16:55:34 +0100
changeset 49275 c639a6b33c5c
parent 47713 530f16bacbfd
permissions -rw-r--r--
8199869: Missing copyright headers in nashorn source code Reviewed-by: sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
     2
 * Copyright (c) 2010, 2017, 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
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
    28
import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
21441
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
    29
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
    30
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    32
import java.io.IOException;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    33
import java.io.ObjectInputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    34
import java.io.ObjectOutputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    35
import java.io.Serializable;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import java.lang.invoke.SwitchPoint;
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    37
import java.lang.ref.Reference;
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
    38
import java.lang.ref.SoftReference;
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    39
import java.lang.ref.WeakReference;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.util.Arrays;
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
    41
import java.util.BitSet;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import java.util.Collection;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.util.Iterator;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import java.util.NoSuchElementException;
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
    45
import java.util.Set;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import java.util.WeakHashMap;
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
    47
import java.util.concurrent.atomic.LongAdder;
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    48
import jdk.nashorn.internal.runtime.options.Options;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    49
import jdk.nashorn.internal.scripts.JO;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
 * Map of object properties. The PropertyMap is the "template" for JavaScript object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
 * layouts. It contains a map with prototype names as keys and {@link Property} instances
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
 * as values. A PropertyMap is typically passed to the {@link ScriptObject} constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
 * to form the seed map for the ScriptObject.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
 * <p>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
 * All property maps are immutable. If a property is added, modified or removed, the mutator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
 * will return a new map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
 */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    60
public class PropertyMap implements Iterable<Object>, Serializable {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    61
    private static final int INITIAL_SOFT_REFERENCE_DERIVATION_LIMIT =
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    62
            Math.max(0, Options.getIntProperty("nashorn.propertyMap.softReferenceDerivationLimit", 32));
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    63
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
    /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    65
    private static final int NOT_EXTENSIBLE         = 0b0000_0001;
21441
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
    66
    /** Does this map contain valid array keys? */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    67
    private static final int CONTAINS_ARRAY_KEYS    = 0b0000_0010;
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
    68
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
    /** Map status flags. */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    70
    private final int flags;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
    /** Map of properties. */
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    73
    private transient PropertyHashMap properties;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
    75
    /** Number of fields in use. */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    76
    private final int fieldCount;
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
    77
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
    78
    /** Number of fields available. */
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
    79
    private final int fieldMaximum;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
    /** Length of spill in use. */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    82
    private final int spillLength;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    84
    /** Structure class name */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    85
    private final String className;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    86
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    87
    /**
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    88
     * Countdown of number of times this property map has been derived from another property map. When it
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    89
     * reaches zero, the property map will start using weak references instead of soft references to hold on
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    90
     * to its history elements.
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    91
     */
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    92
    private final int softReferenceDerivationLimit;
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    93
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    94
    /** A reference to the expected shared prototype property map. If this is set this
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    95
     * property map should only be used if it the same as the actual prototype map. */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
    96
    private transient SharedPropertyMap sharedProtoMap;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
    97
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    /** History of maps, used to limit map duplication. */
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
    99
    private transient WeakHashMap<Property, Reference<PropertyMap>> history;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
    /** History of prototypes, used to limit map duplication. */
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   102
    private transient WeakHashMap<ScriptObject, SoftReference<PropertyMap>> protoHistory;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   104
    /** SwitchPoints for properties inherited form this map */
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   105
    private transient PropertySwitchPoints propertySwitchPoints;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   106
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   107
    private transient BitSet freeSlots;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   108
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   109
    private static final long serialVersionUID = -7041836752008732533L;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
    /**
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   112
     * Constructs a new property map.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
     *
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   114
     * @param properties   A {@link PropertyHashMap} with initial contents.
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   115
     * @param fieldCount   Number of fields in use.
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   116
     * @param fieldMaximum Number of fields available.
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   117
     * @param spillLength  Number of spill slots used.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   119
    private PropertyMap(final PropertyHashMap properties, final int flags, final String className,
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   120
                        final int fieldCount, final int fieldMaximum, final int spillLength) {
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   121
        this.properties   = properties;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   122
        this.className    = className;
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   123
        this.fieldCount   = fieldCount;
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   124
        this.fieldMaximum = fieldMaximum;
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   125
        this.spillLength  = spillLength;
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   126
        this.flags        = flags;
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   127
        this.softReferenceDerivationLimit = INITIAL_SOFT_REFERENCE_DERIVATION_LIMIT;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   128
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
        if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   130
            count.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
    /**
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   135
     * Constructs a clone of {@code propertyMap} with changed properties, flags, or boundaries.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
     * @param propertyMap Existing property map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   138
     * @param properties  A {@link PropertyHashMap} with a new set of properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
     */
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   140
    private PropertyMap(final PropertyMap propertyMap, final PropertyHashMap properties, final int flags, final int fieldCount, final int spillLength, final int softReferenceDerivationLimit) {
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   141
        this.properties   = properties;
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   142
        this.flags        = flags;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   143
        this.spillLength  = spillLength;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   144
        this.fieldCount   = fieldCount;
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   145
        this.fieldMaximum = propertyMap.fieldMaximum;
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   146
        this.className    = propertyMap.className;
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   147
        // We inherit the parent property propertySwitchPoints instance. It will be cloned when a new listener is added.
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   148
        this.propertySwitchPoints = propertyMap.propertySwitchPoints;
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   149
        this.freeSlots    = propertyMap.freeSlots;
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   150
        this.sharedProtoMap = propertyMap.sharedProtoMap;
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   151
        this.softReferenceDerivationLimit = softReferenceDerivationLimit;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
        if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   154
            count.increment();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   155
            clonedCount.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
    /**
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   160
     * Constructs an exact clone of {@code propertyMap}.
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   161
     *
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   162
     * @param propertyMap Existing property map.
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   163
      */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   164
    protected PropertyMap(final PropertyMap propertyMap) {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   165
        this(propertyMap, propertyMap.properties, propertyMap.flags, propertyMap.fieldCount, propertyMap.spillLength, propertyMap.softReferenceDerivationLimit);
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   166
    }
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   167
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   168
    private void writeObject(final ObjectOutputStream out) throws IOException {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   169
        out.defaultWriteObject();
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   170
        out.writeObject(properties.getProperties());
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   171
    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   172
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   173
    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   174
        in.defaultReadObject();
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   175
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   176
        final Property[] props = (Property[]) in.readObject();
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   177
        this.properties = EMPTY_HASHMAP.immutableAdd(props);
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   178
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   179
        assert className != null;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   180
        final Class<?> structure = Context.forStructureClass(className);
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   181
        for (final Property prop : props) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   182
            prop.initMethodHandles(structure);
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   183
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
     * Public property map allocator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
     *
21441
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   189
     * <p>It is the caller's responsibility to make sure that {@code properties} does not contain
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   190
     * properties with keys that are valid array indices.</p>
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   191
     *
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   192
     * @param properties   Collection of initial properties.
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24778
diff changeset
   193
     * @param className    class name
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   194
     * @param fieldCount   Number of fields in use.
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   195
     * @param fieldMaximum Number of fields available.
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   196
     * @param spillLength  Number of used spill slots.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
     * @return New {@link PropertyMap}.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
     */
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23084
diff changeset
   199
    public static PropertyMap newMap(final Collection<Property> properties, final String className, final int fieldCount, final int fieldMaximum,  final int spillLength) {
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
   200
        final PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   201
        return new PropertyMap(newProperties, 0, className, fieldCount, fieldMaximum, spillLength);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
    /**
18855
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   205
     * Public property map allocator. Used by nasgen generated code.
21441
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   206
     *
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   207
     * <p>It is the caller's responsibility to make sure that {@code properties} does not contain
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   208
     * properties with keys that are valid array indices.</p>
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   209
     *
18855
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   210
     * @param properties Collection of initial properties.
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   211
     * @return New {@link PropertyMap}.
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   212
     */
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   213
    public static PropertyMap newMap(final Collection<Property> properties) {
24769
attila
parents: 24763 23767
diff changeset
   214
        return properties == null || properties.isEmpty()? newMap() : newMap(properties, JO.class.getName(), 0, 0, 0);
18855
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   215
    }
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   216
408663ef8f66 8020015: shared PropertyMaps should not be used without duplication
sundar
parents: 18852
diff changeset
   217
    /**
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   218
     * Return a sharable empty map for the given object class.
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   219
     * @param clazz the base object class
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   220
     * @return New empty {@link PropertyMap}.
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   221
     */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   222
    public static PropertyMap newMap(final Class<? extends ScriptObject> clazz) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   223
        return new PropertyMap(EMPTY_HASHMAP, 0, clazz.getName(), 0, 0, 0);
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   224
    }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   225
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   226
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
     * Return a sharable empty map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
     * @return New empty {@link PropertyMap}.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
     */
18852
604c1d681b6f 8017084: Use spill properties for large object literals
hannesw
parents: 18618
diff changeset
   231
    public static PropertyMap newMap() {
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 29534
diff changeset
   232
        return newMap(JO.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
     * Return number of properties in the map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
     * @return Number of properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
    public int size() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
        return properties.size();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
    /**
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   245
     * Get the number of property SwitchPoints of this map
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   246
     *
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   247
     * @return the number of property SwitchPoints
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   248
     */
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   249
    public int getSwitchPointCount() {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   250
        return propertySwitchPoints == null ? 0 : propertySwitchPoints.getSwitchPointCount();
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   251
    }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   252
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   253
    /**
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   254
     * Add a property switchpoint to this property map for the given {@code key}.
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   255
     *
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   256
     * @param key the property name
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   257
     * @param switchPoint the switchpoint
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   258
     */
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   259
    public void addSwitchPoint(final String key, final SwitchPoint switchPoint) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   260
        // We need to clone listener instance when adding a new listener since we share
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   261
        // the propertySwitchPoints instance with our parent maps that don't need to see the new listener.
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   262
        propertySwitchPoints = PropertySwitchPoints.addSwitchPoint(propertySwitchPoints, key, switchPoint);
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   263
    }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   264
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   265
    /**
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   266
     * Method called when a property of an object using this property map is being created,
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   267
     * modified, or deleted. If a switchpoint for the property exists it will be invalidated.
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   268
     *
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   269
     * @param property The changed property.
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   270
     */
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   271
    public void propertyChanged(final Property property) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   272
        if (propertySwitchPoints != null) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   273
            propertySwitchPoints.invalidateProperty(property);
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   274
        }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   275
    }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   276
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   277
    /**
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   278
     * Method called when the prototype of an object using this property map is changed.
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   279
     */
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   280
    void protoChanged() {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   281
        if (sharedProtoMap != null) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   282
            sharedProtoMap.invalidateSwitchPoint();
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   283
        }
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   284
        if (propertySwitchPoints != null) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   285
            propertySwitchPoints.invalidateInheritedProperties(this);
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   286
        }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   287
    }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   288
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   289
    /**
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   290
     * Returns a SwitchPoint for use with a property inherited from this or a parent map.
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   291
     * If such a switchpoint exists, it will be invalidated when the property is modified
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   292
     * in an object using this map. This method returns {@code null} if no swichpoint exists
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   293
     * for the property.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
     *
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   295
     * @param key Property key.
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   296
     * @return A {@link SwitchPoint} for the property, or null.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
     */
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   298
    public synchronized SwitchPoint getSwitchPoint(final String key) {
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   299
        if (propertySwitchPoints != null) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   300
            final Set<SwitchPoint> existingSwitchPoints = propertySwitchPoints.getSwitchPoints(key);
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   301
            for (final SwitchPoint switchPoint : existingSwitchPoints) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   302
                if (switchPoint != null && !switchPoint.hasBeenInvalidated()) {
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   303
                    return switchPoint;
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   304
                }
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   305
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   308
        return null;
19619
4085b74056ee 8023368: Instance __proto__ property should exist and be writable.
sundar
parents: 19097
diff changeset
   309
    }
4085b74056ee 8023368: Instance __proto__ property should exist and be writable.
sundar
parents: 19097
diff changeset
   310
4085b74056ee 8023368: Instance __proto__ property should exist and be writable.
sundar
parents: 19097
diff changeset
   311
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
     * Add a property to the map, re-binding its getters and setters,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
     * if available, to a given receiver. This is typically the global scope. See
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
     * {@link ScriptObject#addBoundProperties(ScriptObject)}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
     * @param property {@link Property} being added.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
     * @param bindTo   Object to bind to.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
     * @return New {@link PropertyMap} with {@link Property} added.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
     */
18860
e387fde9322a 8014785: Ability to extend global instance by binding properties of another object
sundar
parents: 18855
diff changeset
   321
    PropertyMap addPropertyBind(final AccessorProperty property, final Object bindTo) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   322
        // We must not store bound property in the history as bound properties can't be reused.
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   323
        return addPropertyNoHistory(new AccessorProperty(property, bindTo));
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   324
    }
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   325
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   326
    // Get a logical slot index for a property, with spill slot 0 starting at fieldMaximum.
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   327
    private int logicalSlotIndex(final Property property) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   328
        final int slot = property.getSlot();
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   329
        if (slot < 0) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   330
            return -1;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   331
        }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   332
        return property.isSpill() ? slot + fieldMaximum : slot;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   333
    }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   334
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   335
    private int newSpillLength(final Property newProperty) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   336
        return newProperty.isSpill() ? Math.max(spillLength, newProperty.getSlot() + 1) : spillLength;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   337
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   338
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   339
    private int newFieldCount(final Property newProperty) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   340
        return !newProperty.isSpill() ? Math.max(fieldCount, newProperty.getSlot() + 1) : fieldCount;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   341
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   342
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   343
    private int newFlags(final Property newProperty) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   344
        return isValidArrayIndex(getArrayIndex(newProperty.getKey())) ? flags | CONTAINS_ARRAY_KEYS : flags;
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   345
    }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   346
29534
f0a6624dce16 8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel
hannesw
parents: 28786
diff changeset
   347
    // Update the free slots bitmap for a property that has been deleted and/or added. This method is not synchronized
f0a6624dce16 8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel
hannesw
parents: 28786
diff changeset
   348
    // as it is always invoked on a newly created instance.
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   349
    private void updateFreeSlots(final Property oldProperty, final Property newProperty) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   350
        // Free slots bitset is possibly shared with parent map, so we must clone it before making modifications.
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   351
        boolean freeSlotsCloned = false;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   352
        if (oldProperty != null) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   353
            final int slotIndex = logicalSlotIndex(oldProperty);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   354
            if (slotIndex >= 0) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   355
                final BitSet newFreeSlots = freeSlots == null ? new BitSet() : (BitSet)freeSlots.clone();
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   356
                assert !newFreeSlots.get(slotIndex);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   357
                newFreeSlots.set(slotIndex);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   358
                freeSlots = newFreeSlots;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   359
                freeSlotsCloned = true;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   360
            }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   361
        }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   362
        if (freeSlots != null && newProperty != null) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   363
            final int slotIndex = logicalSlotIndex(newProperty);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   364
            if (slotIndex > -1 && freeSlots.get(slotIndex)) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   365
                final BitSet newFreeSlots = freeSlotsCloned ? freeSlots : ((BitSet)freeSlots.clone());
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   366
                newFreeSlots.clear(slotIndex);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   367
                freeSlots = newFreeSlots.isEmpty() ? null : newFreeSlots;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   368
            }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   369
        }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   370
    }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   371
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   372
    /**
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   373
     * Add a property to the map without adding it to the history. This should be used for properties that
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   374
     * can't be shared such as bound properties, or properties that are expected to be added only once.
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   375
     *
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   376
     * @param property {@link Property} being added.
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   377
     * @return New {@link PropertyMap} with {@link Property} added.
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   378
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   379
    public final PropertyMap addPropertyNoHistory(final Property property) {
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   380
        propertyChanged(property);
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   381
        return addPropertyInternal(property);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   385
     * Add a property to the map.  Cloning or using an existing map if available.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
     * @param property {@link Property} being added.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
     * @return New {@link PropertyMap} with {@link Property} added.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   391
    public final synchronized PropertyMap addProperty(final Property property) {
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   392
        propertyChanged(property);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
        PropertyMap newMap = checkHistory(property);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   395
        if (newMap == null) {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   396
            newMap = addPropertyInternal(property);
29534
f0a6624dce16 8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel
hannesw
parents: 28786
diff changeset
   397
            addToHistory(property, newMap);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   403
    private PropertyMap deriveMap(final PropertyHashMap newProperties, final int newFlags, final int newFieldCount, final int newSpillLength) {
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   404
        return new PropertyMap(this, newProperties, newFlags, newFieldCount, newSpillLength, softReferenceDerivationLimit == 0 ? 0 : softReferenceDerivationLimit - 1);
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   405
    }
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   406
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   407
    private PropertyMap addPropertyInternal(final Property property) {
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   408
        final PropertyHashMap newProperties = properties.immutableAdd(property);
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   409
        final PropertyMap newMap = deriveMap(newProperties, newFlags(property), newFieldCount(property), newSpillLength(property));
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   410
        newMap.updateFreeSlots(null, property);
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   411
        return newMap;
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   412
    }
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   413
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
     * Remove a property from a map. Cloning or using an existing map if available.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
     * @param property {@link Property} being removed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
     * @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   421
    public final synchronized PropertyMap deleteProperty(final Property property) {
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   422
        propertyChanged(property);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
        PropertyMap newMap = checkHistory(property);
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 32890
diff changeset
   424
        final Object key = property.getKey();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
        if (newMap == null && properties.containsKey(key)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
            final PropertyHashMap newProperties = properties.immutableRemove(key);
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   428
            final boolean isSpill = property.isSpill();
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   429
            final int slot = property.getSlot();
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   430
            // If deleted property was last field or spill slot we can make it reusable by reducing field/slot count.
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   431
            // Otherwise mark it as free in free slots bitset.
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   432
            if (isSpill && slot >= 0 && slot == spillLength - 1) {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   433
                newMap = deriveMap(newProperties, flags, fieldCount, spillLength - 1);
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   434
                newMap.freeSlots = freeSlots;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   435
            } else if (!isSpill && slot >= 0 && slot == fieldCount - 1) {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   436
                newMap = deriveMap(newProperties, flags, fieldCount - 1, spillLength);
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   437
                newMap.freeSlots = freeSlots;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   438
            } else {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   439
                newMap = deriveMap(newProperties, flags, fieldCount, spillLength);
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   440
                newMap.updateFreeSlots(property, null);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   441
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
            addToHistory(property, newMap);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
     * Replace an existing property with a new one.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
     * @param oldProperty Property to replace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
     * @param newProperty New {@link Property}.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
     * @return New {@link PropertyMap} with {@link Property} replaced.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   456
    public final PropertyMap replaceProperty(final Property oldProperty, final Property newProperty) {
47713
530f16bacbfd 8190427: Test for JDK-8165198 fails intermittently because of GC
hannesw
parents: 47216
diff changeset
   457
        propertyChanged(oldProperty);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
         * See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
         * This replaceProperty method is called only for the following three cases:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
         *   1. To change flags OR TYPE of an old (cloned) property. We use the same spill slots.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
         *   2. To change one UserAccessor property with another - user getter or setter changed via
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   465
         *      Object.defineProperty function. Again, same spill slots are re-used.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   466
         *   3. Via ScriptObject.setUserAccessors method to set user getter and setter functions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   467
         *      replacing the dummy AccessorProperty with null method handles (added during map init).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   469
         * In case (1) and case(2), the property type of old and new property is same. For case (3),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
         * the old property is an AccessorProperty and the new one is a UserAccessorProperty property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
   473
        final boolean sameType = oldProperty.getClass() == newProperty.getClass();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
        assert sameType ||
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
   475
                oldProperty instanceof AccessorProperty &&
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
   476
                newProperty instanceof UserAccessorProperty :
27307
62ed492cbe63 8062401: User accessors require boxing and do not support optimistic types
hannesw
parents: 26768
diff changeset
   477
            "arbitrary replaceProperty attempted " + sameType + " oldProperty=" + oldProperty.getClass() + " newProperty=" + newProperty.getClass() + " [" + oldProperty.getLocalType() + " => " + newProperty.getLocalType() + "]";
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
         * spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
         * to add spill count of the newly added UserAccessorProperty property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
         */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   483
        final int newSpillLength = sameType ? spillLength : Math.max(spillLength, newProperty.getSlot() + 1);
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   484
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   485
        // Add replaces existing property.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   486
        final PropertyHashMap newProperties = properties.immutableReplace(oldProperty, newProperty);
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   487
        final PropertyMap newMap = deriveMap(newProperties, flags, fieldCount, newSpillLength);
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   488
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   489
        if (!sameType) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   490
            newMap.updateFreeSlots(oldProperty, newProperty);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   491
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 18860
diff changeset
   495
    /**
18617
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   496
     * Make a new UserAccessorProperty property. getter and setter functions are stored in
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   497
     * this ScriptObject and slot values are used in property object. Note that slots
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   498
     * are assigned speculatively and should be added to map before adding other
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   499
     * properties.
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 18860
diff changeset
   500
     *
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 18860
diff changeset
   501
     * @param key the property name
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 18860
diff changeset
   502
     * @param propertyFlags attribute flags of the property
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 18860
diff changeset
   503
     * @return the newly created UserAccessorProperty
18617
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   504
     */
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 32890
diff changeset
   505
    public final UserAccessorProperty newUserAccessors(final Object key, final int propertyFlags) {
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   506
        return new UserAccessorProperty(key, propertyFlags, getFreeSpillSlot());
18617
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   507
    }
f6fe338f62c3 8008458: Strict functions dont share property map
jlaskey
parents: 18325
diff changeset
   508
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
     * Find a property in the map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
     * @param key Key to search for.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
     * @return {@link Property} matching key.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
     */
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 32890
diff changeset
   516
    public final Property findProperty(final Object key) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
        return properties.find(key);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
     * Adds all map properties from another map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
     * @param other The source of properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
     * @return New {@link PropertyMap} with added properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   527
    public final PropertyMap addAll(final PropertyMap other) {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16201
diff changeset
   528
        assert this != other : "adding property map to itself";
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
        final Property[] otherProperties = other.properties.getProperties();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
        final PropertyHashMap newProperties = properties.immutableAdd(otherProperties);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   532
        final PropertyMap newMap = deriveMap(newProperties, flags, fieldCount, spillLength);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
        for (final Property property : otherProperties) {
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   534
            // This method is only safe to use with non-slotted, native getter/setter properties
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   535
            assert property.getSlot() == -1;
26648
9a64e15eff37 8056978: ClassCastException: cannot cast jdk.nashorn.internal.scripts.JO*
hannesw
parents: 26068
diff changeset
   536
            assert !(isValidArrayIndex(getArrayIndex(property.getKey())));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   540
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
     * Return an array of all properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
     * @return Properties as an array.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   547
    public final Property[] getProperties() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
        return properties.getProperties();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
    /**
31197
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   552
     * Return the name of the class of objects using this property map.
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   553
     *
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   554
     * @return class name of owner objects.
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   555
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   556
    public final String getClassName() {
31197
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   557
        return className;
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   558
    }
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   559
1af1f3366c49 8087312: PropertyMapWrapper.equals should compare className
hannesw
parents: 29834
diff changeset
   560
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
     * Prevents the map from having additional properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
     * @return New map with {@link #NOT_EXTENSIBLE} flag set.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
    PropertyMap preventExtensions() {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   566
        return deriveMap(properties, flags | NOT_EXTENSIBLE, fieldCount, spillLength);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
     * Prevents properties in map from being modified.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
     *
16154
de44634fa4ec 8005782: get rid of javadoc errors, warnings in nashorn build
sundar
parents: 16152
diff changeset
   572
     * @return New map with {@link #NOT_EXTENSIBLE} flag set and properties with
de44634fa4ec 8005782: get rid of javadoc errors, warnings in nashorn build
sundar
parents: 16152
diff changeset
   573
     * {@link Property#NOT_CONFIGURABLE} set.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
    PropertyMap seal() {
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   576
        PropertyHashMap newProperties = EMPTY_HASHMAP;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
        for (final Property oldProperty :  properties.getProperties()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   579
            newProperties = newProperties.immutableAdd(oldProperty.addFlags(Property.NOT_CONFIGURABLE));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   582
        return deriveMap(newProperties, flags | NOT_EXTENSIBLE, fieldCount, spillLength);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   583
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   584
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   585
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   586
     * Prevents properties in map from being modified or written to.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   587
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   588
     * @return New map with {@link #NOT_EXTENSIBLE} flag set and properties with
16154
de44634fa4ec 8005782: get rid of javadoc errors, warnings in nashorn build
sundar
parents: 16152
diff changeset
   589
     * {@link Property#NOT_CONFIGURABLE} and {@link Property#NOT_WRITABLE} set.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   590
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   591
    PropertyMap freeze() {
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   592
        PropertyHashMap newProperties = EMPTY_HASHMAP;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24719
diff changeset
   594
        for (final Property oldProperty : properties.getProperties()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
            int propertyFlags = Property.NOT_CONFIGURABLE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
            if (!(oldProperty instanceof UserAccessorProperty)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
                propertyFlags |= Property.NOT_WRITABLE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
            newProperties = newProperties.immutableAdd(oldProperty.addFlags(propertyFlags));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   604
        return deriveMap(newProperties, flags | NOT_EXTENSIBLE, fieldCount, spillLength);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   605
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
     * Check for any configurable properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
     * @return {@code true} if any configurable.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
    private boolean anyConfigurable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
        for (final Property property : properties.getProperties()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
            if (property.isConfigurable()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
               return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   623
     * Check if all properties are frozen.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
     * @return {@code true} if all are frozen.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   627
    private boolean allFrozen() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
        for (final Property property : properties.getProperties()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
            // check if it is a data descriptor
36023
528cc67f1289 8147558: Add support for ES6 collections
hannesw
parents: 35407
diff changeset
   630
            if (!property.isAccessorProperty() && property.isWritable()) {
528cc67f1289 8147558: Add support for ES6 collections
hannesw
parents: 35407
diff changeset
   631
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   632
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
            if (property.isConfigurable()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
               return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
        return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
     * Check prototype history for an existing property map with specified prototype.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
     *
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   644
     * @param proto New prototype object.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
     * @return Existing {@link PropertyMap} or {@code null} if not found.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   647
     */
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   648
    private PropertyMap checkProtoHistory(final ScriptObject proto) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   649
        final PropertyMap cachedMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
        if (protoHistory != null) {
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   651
            final SoftReference<PropertyMap> weakMap = protoHistory.get(proto);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
            cachedMap = (weakMap != null ? weakMap.get() : null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   653
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
            cachedMap = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
        if (Context.DEBUG && cachedMap != null) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   658
            protoHistoryHit.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
        return cachedMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   664
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
     * Add a map to the prototype history.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
     *
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   667
     * @param newProto Prototype to add (key.)
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
     * @param newMap   {@link PropertyMap} associated with prototype.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
     */
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   670
    private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
16759
ecf99910fc31 8011219: Regression with recent PropertyMap history changes
hannesw
parents: 16758
diff changeset
   671
        if (protoHistory == null) {
ecf99910fc31 8011219: Regression with recent PropertyMap history changes
hannesw
parents: 16758
diff changeset
   672
            protoHistory = new WeakHashMap<>();
ecf99910fc31 8011219: Regression with recent PropertyMap history changes
hannesw
parents: 16758
diff changeset
   673
        }
16758
4f7379c41907 8011095: PropertyHashMap.rehash() does not grow enough
jlaskey
parents: 16275
diff changeset
   674
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   675
        protoHistory.put(newProto, new SoftReference<>(newMap));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
     * Track the modification of the map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
     * @param property Mapping property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
     * @param newMap   Modified {@link PropertyMap}.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
    private void addToHistory(final Property property, final PropertyMap newMap) {
24763
20971b9687ec 8043605: Enable history for empty property maps
attila
parents: 24727
diff changeset
   685
        if (history == null) {
20971b9687ec 8043605: Enable history for empty property maps
attila
parents: 24727
diff changeset
   686
            history = new WeakHashMap<>();
20971b9687ec 8043605: Enable history for empty property maps
attila
parents: 24727
diff changeset
   687
        }
16774
745fe7d2536d 8011540: PropertyMap histories should not begin with empty map
jlaskey
parents: 16759
diff changeset
   688
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   689
        history.put(property, softReferenceDerivationLimit == 0 ? new WeakReference<>(newMap) : new SoftReference<>(newMap));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
     * Check the history for a map that already has the given property added.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   694
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   695
     * @param property {@link Property} to add.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     * @return Existing map or {@code null} if not found.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
    private PropertyMap checkHistory(final Property property) {
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   700
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
        if (history != null) {
32890
0118bc9769e1 8137333: Boundless soft caching of property map histories causes high memory pressure
attila
parents: 32695
diff changeset
   702
            final Reference<PropertyMap> ref = history.get(property);
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   703
            final PropertyMap historicMap = ref == null ? null : ref.get();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
            if (historicMap != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
                if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   707
                    historyHit.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
                return historicMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   718
     * Returns true if the two maps have identical properties in the same order, but allows the properties to differ in
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   719
     * their types. This method is mostly useful for tests.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   720
     * @param otherMap the other map
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   721
     * @return true if this map has identical properties in the same order as the other map, allowing the properties to
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   722
     * differ in type.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   723
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   724
    public boolean equalsWithoutType(final PropertyMap otherMap) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   725
        if (properties.size() != otherMap.properties.size()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   726
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   727
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   728
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   729
        final Iterator<Property> iter      = properties.values().iterator();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   730
        final Iterator<Property> otherIter = otherMap.properties.values().iterator();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   731
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   732
        while (iter.hasNext() && otherIter.hasNext()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   733
            if (!iter.next().equalsWithoutType(otherIter.next())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   734
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   735
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   736
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   737
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   738
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   739
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   740
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
    public String toString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24721
diff changeset
   745
        sb.append(Debug.id(this));
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24721
diff changeset
   746
        sb.append(" = {\n");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
24726
34410e0545b1 8037967: Broke the build, by commiting without saving the last review comment
lagergren
parents: 24725
diff changeset
   748
        for (final Property property : getProperties()) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24721
diff changeset
   749
            sb.append('\t');
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   750
            sb.append(property);
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24721
diff changeset
   751
            sb.append('\n');
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   752
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   753
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24721
diff changeset
   754
        sb.append('}');
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   756
        return sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   757
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   758
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   759
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   760
    public Iterator<Object> iterator() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   761
        return new PropertyMapIterator(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   762
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   763
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   764
    /**
21441
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   765
     * Check if this map contains properties with valid array keys
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   766
     *
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   767
     * @return {@code true} if this map contains properties with valid array keys
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   768
     */
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   769
    public final boolean containsArrayKeys() {
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   770
        return (flags & CONTAINS_ARRAY_KEYS) != 0;
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   771
    }
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   772
0b98be59e3cb 8026858: Array length does not handle defined properties correctly
hannesw
parents: 19619
diff changeset
   773
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
     * Test to see if {@link PropertyMap} is extensible.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   776
     * @return {@code true} if {@link PropertyMap} can be added to.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   777
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   778
    boolean isExtensible() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   779
        return (flags & NOT_EXTENSIBLE) == 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   780
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   782
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
     * Test to see if {@link PropertyMap} is not extensible or any properties
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   784
     * can not be modified.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
     * @return {@code true} if {@link PropertyMap} is sealed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
    boolean isSealed() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   789
        return !isExtensible() && !anyConfigurable();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   790
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
     * Test to see if {@link PropertyMap} is not extensible or all properties
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
     * can not be modified.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
     * @return {@code true} if {@link PropertyMap} is frozen.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
    boolean isFrozen() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
        return !isExtensible() && allFrozen();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
    }
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   801
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   802
    /**
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   803
     * Return a free field slot for this map, or {@code -1} if none is available.
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   804
     *
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   805
     * @return free field slot or -1
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   806
     */
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   807
    int getFreeFieldSlot() {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   808
        if (freeSlots != null) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   809
            final int freeSlot = freeSlots.nextSetBit(0);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   810
            if (freeSlot > -1 && freeSlot < fieldMaximum) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   811
                return freeSlot;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   812
            }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   813
        }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   814
        if (fieldCount < fieldMaximum) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   815
            return fieldCount;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   816
        }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   817
        return -1;
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   818
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   819
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   820
    /**
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   821
     * Get a free spill slot for this map.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
     *
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   823
     * @return free spill slot
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
     */
26060
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   825
    int getFreeSpillSlot() {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   826
        if (freeSlots != null) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   827
            final int freeSlot = freeSlots.nextSetBit(fieldMaximum);
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   828
            if (freeSlot > -1) {
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   829
                return freeSlot - fieldMaximum;
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   830
            }
50a029a28ecb 8044851: nashorn properties leak memory
hannesw
parents: 25421
diff changeset
   831
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
        return spillLength;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   833
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   835
    /**
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 21441
diff changeset
   836
     * Return a property map with the same layout that is associated with the new prototype object.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
     *
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   838
     * @param newProto New prototype object to replace oldProto.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
     * @return New {@link PropertyMap} with prototype changed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   840
     */
29534
f0a6624dce16 8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel
hannesw
parents: 28786
diff changeset
   841
    public synchronized PropertyMap changeProto(final ScriptObject newProto) {
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   842
        final PropertyMap nextMap = checkProtoHistory(newProto);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   843
        if (nextMap != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   844
            return nextMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   845
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   846
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   847
        if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
   848
            setProtoNewMapCount.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   849
        }
17513
b9a691fc1df5 8006220: Simplify PropertyMaps
jlaskey
parents: 16774
diff changeset
   850
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   851
        final PropertyMap newMap = makeUnsharedCopy();
27356
2d407b9be8b0 8062132: Nashorn incorrectly binds this for constructor created by another function
hannesw
parents: 27307
diff changeset
   852
        addToProtoHistory(newProto, newMap);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   853
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   854
        return newMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   855
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   856
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   857
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   858
     * Make a copy of this property map with the shared prototype field set to null. Note that this is
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   859
     * only necessary for shared maps of top-level objects. Shared prototype maps represented by
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   860
     * {@link SharedPropertyMap} are automatically converted to plain property maps when they evolve.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   861
     *
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   862
     * @return a copy with the shared proto map unset
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   863
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   864
    PropertyMap makeUnsharedCopy() {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   865
        final PropertyMap newMap = new PropertyMap(this);
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   866
        newMap.sharedProtoMap = null;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   867
        return newMap;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   868
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   869
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   870
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   871
     * Set a reference to the expected parent prototype map. This is used for class-like
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   872
     * structures where we only want to use a top-level property map if all of the
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   873
     * prototype property maps have not been modified.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   874
     *
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   875
     * @param protoMap weak reference to the prototype property map
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   876
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   877
    void setSharedProtoMap(final SharedPropertyMap protoMap) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   878
        sharedProtoMap = protoMap;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   879
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   880
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   881
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   882
     * Get the expected prototype property map if it is known, or null.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   883
     *
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   884
     * @return parent map or null
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   885
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   886
    public PropertyMap getSharedProtoMap() {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   887
        return sharedProtoMap;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   888
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   889
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   890
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   891
     * Returns {@code true} if this map has been used as a shared prototype map (i.e. as a prototype
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   892
     * for a JavaScript constructor function) and has not had properties added, deleted or replaced since then.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   893
     * @return true if this is a valid shared prototype map
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   894
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   895
    boolean isValidSharedProtoMap() {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   896
        return false;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   897
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   898
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   899
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   900
     * Returns the shared prototype switch point, or null if this is not a shared prototype map.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   901
     * @return the shared prototype switch point, or null
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   902
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   903
    SwitchPoint getSharedProtoSwitchPoint() {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   904
        return null;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   905
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   906
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   907
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   908
     * Return true if this map has a shared prototype map which has either been invalidated or does
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   909
     * not match the map of {@code proto}.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   910
     * @param prototype the prototype object
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   911
     * @return true if this is an invalid shared map for {@code prototype}
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   912
     */
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   913
    boolean isInvalidSharedMapFor(final ScriptObject prototype) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   914
        return sharedProtoMap != null
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   915
                && (!sharedProtoMap.isValidSharedProtoMap() || prototype == null || sharedProtoMap != prototype.getMap());
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32527
diff changeset
   916
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   918
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   919
     * {@link PropertyMap} iterator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   921
    private static class PropertyMapIterator implements Iterator<Object> {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   922
        /** Property iterator. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   923
        final Iterator<Property> iter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   924
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   925
        /** Current Property. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
        Property property;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   927
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
         * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
         * @param propertyMap {@link PropertyMap} to iterate over.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   932
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
        PropertyMapIterator(final PropertyMap propertyMap) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
            iter = Arrays.asList(propertyMap.properties.getProperties()).iterator();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
            property = iter.hasNext() ? iter.next() : null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   936
            skipNotEnumerable();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   937
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   938
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   939
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
         * Ignore properties that are not enumerable.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
        private void skipNotEnumerable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   943
            while (property != null && !property.isEnumerable()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
                property = iter.hasNext() ? iter.next() : null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   948
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   949
        public boolean hasNext() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
            return property != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   951
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   953
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   954
        public Object next() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   955
            if (property == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   956
                throw new NoSuchElementException();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   957
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   958
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
            final Object key = property.getKey();
43116
20c7572ce2a5 8170781: PropertyMapIterator throws NoSuchElementException on last element
hannesw
parents: 36023
diff changeset
   960
            property = iter.hasNext() ? iter.next() : null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   961
            skipNotEnumerable();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
            return key;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   964
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   965
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   966
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   967
        public void remove() {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26648
diff changeset
   968
            throw new UnsupportedOperationException("remove");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   969
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   972
    /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   973
     * Debugging and statistics.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   974
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   975
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   976
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   977
     * Debug helper function that returns the diff of two property maps, only
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   978
     * displaying the information that is different and in which map it exists
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   979
     * compared to the other map. Can be used to e.g. debug map guards and
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   980
     * investigate why they fail, causing relink
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   981
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   982
     * @param map0 the first property map
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   983
     * @param map1 the second property map
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   984
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   985
     * @return property map diff as string
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   986
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   987
    public static String diff(final PropertyMap map0, final PropertyMap map1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   988
        final StringBuilder sb = new StringBuilder();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   989
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   990
        if (map0 != map1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   991
           sb.append(">>> START: Map diff");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   992
           boolean found = false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   993
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   994
           for (final Property p : map0.getProperties()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   995
               final Property p2 = map1.findProperty(p.getKey());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   996
               if (p2 == null) {
31548
d158ec7e1e30 8130663: 6 fields can be static fields in Global class
sundar
parents: 31197
diff changeset
   997
                   sb.append("FIRST ONLY : [").append(p).append("]");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   998
                   found = true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   999
               } else if (p2 != p) {
31548
d158ec7e1e30 8130663: 6 fields can be static fields in Global class
sundar
parents: 31197
diff changeset
  1000
                   sb.append("DIFFERENT  : [").append(p).append("] != [").append(p2).append("]");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1001
                   found = true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1002
               }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1003
           }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1004
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1005
           for (final Property p2 : map1.getProperties()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1006
               final Property p1 = map0.findProperty(p2.getKey());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1007
               if (p1 == null) {
31548
d158ec7e1e30 8130663: 6 fields can be static fields in Global class
sundar
parents: 31197
diff changeset
  1008
                   sb.append("SECOND ONLY: [").append(p2).append("]");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1009
                   found = true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1010
               }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1011
           }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1012
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1013
           //assert found;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1014
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1015
           if (!found) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1016
                sb.append(map0).
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1017
                    append("!=").
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1018
                    append(map1);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1019
           }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1020
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1021
           sb.append("<<< END: Map diff\n");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1022
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1023
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1024
        return sb.toString();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1025
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
  1026
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
    // counters updated only in debug mode
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1028
    private static LongAdder count;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1029
    private static LongAdder clonedCount;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1030
    private static LongAdder historyHit;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1031
    private static LongAdder protoInvalidations;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1032
    private static LongAdder protoHistoryHit;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1033
    private static LongAdder setProtoNewMapCount;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1034
    static {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1035
        if (Context.DEBUG) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1036
            count = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1037
            clonedCount = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1038
            historyHit = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1039
            protoInvalidations = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1040
            protoHistoryHit = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1041
            setProtoNewMapCount = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1042
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1043
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1046
     * @return Total number of maps.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1047
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1048
    public static long getCount() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1049
        return count.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1051
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1052
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1053
     * @return The number of maps that were cloned.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1054
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1055
    public static long getClonedCount() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1056
        return clonedCount.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1057
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1058
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1059
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
     * @return The number of times history was successfully used.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1062
    public static long getHistoryHit() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1063
        return historyHit.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1067
     * @return The number of times prototype changes caused invalidation.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1068
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1069
    public static long getProtoInvalidations() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1070
        return protoInvalidations.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1072
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1073
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1074
     * @return The number of times proto history was successfully used.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1075
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1076
    public static long getProtoHistoryHit() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1077
        return protoHistoryHit.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1078
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1079
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1080
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
     * @return The number of times prototypes were modified.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1082
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1083
    public static long getSetProtoNewMapCount() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31548
diff changeset
  1084
        return setProtoNewMapCount.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1085
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1086
}