author | hannesw |
Wed, 21 Mar 2018 16:55:34 +0100 | |
changeset 49275 | c639a6b33c5c |
parent 47713 | 530f16bacbfd |
permissions | -rw-r--r-- |
16147 | 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 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
17513 | 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 | 31 |
|
23767 | 32 |
import java.io.IOException; |
33 |
import java.io.ObjectInputStream; |
|
34 |
import java.io.ObjectOutputStream; |
|
35 |
import java.io.Serializable; |
|
16147 | 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 | 40 |
import java.util.Arrays; |
26060 | 41 |
import java.util.BitSet; |
16147 | 42 |
import java.util.Collection; |
43 |
import java.util.Iterator; |
|
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 | 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 | 49 |
import jdk.nashorn.internal.scripts.JO; |
16147 | 50 |
|
51 |
/** |
|
52 |
* Map of object properties. The PropertyMap is the "template" for JavaScript object |
|
53 |
* layouts. It contains a map with prototype names as keys and {@link Property} instances |
|
54 |
* as values. A PropertyMap is typically passed to the {@link ScriptObject} constructor |
|
55 |
* to form the seed map for the ScriptObject. |
|
56 |
* <p> |
|
57 |
* All property maps are immutable. If a property is added, modified or removed, the mutator |
|
58 |
* will return a new map. |
|
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 | 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 | 68 |
|
16147 | 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 | 71 |
|
72 |
/** Map of properties. */ |
|
23767 | 73 |
private transient PropertyHashMap properties; |
16147 | 74 |
|
17513 | 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 | 77 |
|
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 | 80 |
|
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 | 83 |
|
23767 | 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 | 97 |
|
16147 | 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 | 100 |
|
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 | 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 | 106 |
|
26060 | 107 |
private transient BitSet freeSlots; |
108 |
||
23767 | 109 |
private static final long serialVersionUID = -7041836752008732533L; |
16147 | 110 |
|
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 | 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 | 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 | 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 | 121 |
this.properties = properties; |
23767 | 122 |
this.className = className; |
17513 | 123 |
this.fieldCount = fieldCount; |
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 | 128 |
|
129 |
if (Context.DEBUG) { |
|
32527
b105632002c5
8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents:
31548
diff
changeset
|
130 |
count.increment(); |
16147 | 131 |
} |
132 |
} |
|
133 |
||
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 | 136 |
* |
137 |
* @param propertyMap Existing property map. |
|
138 |
* @param properties A {@link PropertyHashMap} with a new set of properties. |
|
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 | 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 | 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 | 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 | 152 |
|
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 | 156 |
} |
157 |
} |
|
158 |
||
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 | 161 |
* |
162 |
* @param propertyMap Existing property map. |
|
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 | 166 |
} |
167 |
||
23767 | 168 |
private void writeObject(final ObjectOutputStream out) throws IOException { |
169 |
out.defaultWriteObject(); |
|
170 |
out.writeObject(properties.getProperties()); |
|
171 |
} |
|
172 |
||
173 |
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { |
|
174 |
in.defaultReadObject(); |
|
175 |
||
176 |
final Property[] props = (Property[]) in.readObject(); |
|
177 |
this.properties = EMPTY_HASHMAP.immutableAdd(props); |
|
178 |
||
179 |
assert className != null; |
|
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 | 182 |
prop.initMethodHandles(structure); |
183 |
} |
|
16147 | 184 |
} |
185 |
||
186 |
/** |
|
187 |
* Public property map allocator. |
|
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 | 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 | 197 |
* @return New {@link PropertyMap}. |
198 |
*/ |
|
23767 | 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 | 202 |
} |
203 |
||
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 | 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 | 227 |
* Return a sharable empty map. |
228 |
* |
|
229 |
* @return New empty {@link PropertyMap}. |
|
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 | 233 |
} |
234 |
||
235 |
/** |
|
236 |
* Return number of properties in the map. |
|
237 |
* |
|
238 |
* @return Number of properties. |
|
239 |
*/ |
|
240 |
public int size() { |
|
241 |
return properties.size(); |
|
242 |
} |
|
243 |
||
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 | 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 | 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 | 306 |
} |
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 | 312 |
* Add a property to the map, re-binding its getters and setters, |
313 |
* if available, to a given receiver. This is typically the global scope. See |
|
314 |
* {@link ScriptObject#addBoundProperties(ScriptObject)} |
|
315 |
* |
|
316 |
* @param property {@link Property} being added. |
|
317 |
* @param bindTo Object to bind to. |
|
318 |
* |
|
319 |
* @return New {@link PropertyMap} with {@link Property} added. |
|
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 | 326 |
// Get a logical slot index for a property, with spill slot 0 starting at fieldMaximum. |
327 |
private int logicalSlotIndex(final Property property) { |
|
328 |
final int slot = property.getSlot(); |
|
329 |
if (slot < 0) { |
|
330 |
return -1; |
|
331 |
} |
|
332 |
return property.isSpill() ? slot + fieldMaximum : slot; |
|
333 |
} |
|
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 | 345 |
} |
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 | 349 |
private void updateFreeSlots(final Property oldProperty, final Property newProperty) { |
350 |
// Free slots bitset is possibly shared with parent map, so we must clone it before making modifications. |
|
351 |
boolean freeSlotsCloned = false; |
|
352 |
if (oldProperty != null) { |
|
353 |
final int slotIndex = logicalSlotIndex(oldProperty); |
|
354 |
if (slotIndex >= 0) { |
|
355 |
final BitSet newFreeSlots = freeSlots == null ? new BitSet() : (BitSet)freeSlots.clone(); |
|
356 |
assert !newFreeSlots.get(slotIndex); |
|
357 |
newFreeSlots.set(slotIndex); |
|
358 |
freeSlots = newFreeSlots; |
|
359 |
freeSlotsCloned = true; |
|
360 |
} |
|
361 |
} |
|
362 |
if (freeSlots != null && newProperty != null) { |
|
363 |
final int slotIndex = logicalSlotIndex(newProperty); |
|
364 |
if (slotIndex > -1 && freeSlots.get(slotIndex)) { |
|
365 |
final BitSet newFreeSlots = freeSlotsCloned ? freeSlots : ((BitSet)freeSlots.clone()); |
|
366 |
newFreeSlots.clear(slotIndex); |
|
367 |
freeSlots = newFreeSlots.isEmpty() ? null : newFreeSlots; |
|
368 |
} |
|
369 |
} |
|
370 |
} |
|
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 | 382 |
} |
383 |
||
384 |
/** |
|
385 |
* Add a property to the map. Cloning or using an existing map if available. |
|
386 |
* |
|
387 |
* @param property {@link Property} being added. |
|
388 |
* |
|
389 |
* @return New {@link PropertyMap} with {@link Property} added. |
|
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 | 393 |
PropertyMap newMap = checkHistory(property); |
394 |
||
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 | 398 |
} |
399 |
||
400 |
return newMap; |
|
401 |
} |
|
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 | 414 |
/** |
415 |
* Remove a property from a map. Cloning or using an existing map if available. |
|
416 |
* |
|
417 |
* @param property {@link Property} being removed. |
|
418 |
* |
|
419 |
* @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found. |
|
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 | 423 |
PropertyMap newMap = checkHistory(property); |
33690 | 424 |
final Object key = property.getKey(); |
16147 | 425 |
|
426 |
if (newMap == null && properties.containsKey(key)) { |
|
427 |
final PropertyHashMap newProperties = properties.immutableRemove(key); |
|
26060 | 428 |
final boolean isSpill = property.isSpill(); |
429 |
final int slot = property.getSlot(); |
|
430 |
// If deleted property was last field or spill slot we can make it reusable by reducing field/slot count. |
|
431 |
// Otherwise mark it as free in free slots bitset. |
|
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 | 434 |
newMap.freeSlots = freeSlots; |
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 | 437 |
newMap.freeSlots = freeSlots; |
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 | 440 |
newMap.updateFreeSlots(property, null); |
441 |
} |
|
16147 | 442 |
addToHistory(property, newMap); |
443 |
} |
|
444 |
||
445 |
return newMap; |
|
446 |
} |
|
447 |
||
448 |
/** |
|
449 |
* Replace an existing property with a new one. |
|
450 |
* |
|
451 |
* @param oldProperty Property to replace. |
|
452 |
* @param newProperty New {@link Property}. |
|
453 |
* |
|
454 |
* @return New {@link PropertyMap} with {@link Property} replaced. |
|
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 | 458 |
/* |
459 |
* See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods. |
|
460 |
* |
|
461 |
* This replaceProperty method is called only for the following three cases: |
|
462 |
* |
|
463 |
* 1. To change flags OR TYPE of an old (cloned) property. We use the same spill slots. |
|
464 |
* 2. To change one UserAccessor property with another - user getter or setter changed via |
|
465 |
* Object.defineProperty function. Again, same spill slots are re-used. |
|
466 |
* 3. Via ScriptObject.setUserAccessors method to set user getter and setter functions |
|
467 |
* replacing the dummy AccessorProperty with null method handles (added during map init). |
|
468 |
* |
|
469 |
* In case (1) and case(2), the property type of old and new property is same. For case (3), |
|
470 |
* the old property is an AccessorProperty and the new one is a UserAccessorProperty property. |
|
471 |
*/ |
|
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 | 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 | 478 |
|
479 |
/* |
|
480 |
* spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need |
|
481 |
* to add spill count of the newly added UserAccessorProperty property. |
|
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 | 489 |
if (!sameType) { |
490 |
newMap.updateFreeSlots(oldProperty, newProperty); |
|
491 |
} |
|
16147 | 492 |
return newMap; |
493 |
} |
|
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 | 505 |
public final UserAccessorProperty newUserAccessors(final Object key, final int propertyFlags) { |
26060 | 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 | 509 |
/** |
510 |
* Find a property in the map. |
|
511 |
* |
|
512 |
* @param key Key to search for. |
|
513 |
* |
|
514 |
* @return {@link Property} matching key. |
|
515 |
*/ |
|
33690 | 516 |
public final Property findProperty(final Object key) { |
16147 | 517 |
return properties.find(key); |
518 |
} |
|
519 |
||
520 |
/** |
|
521 |
* Adds all map properties from another map. |
|
522 |
* |
|
523 |
* @param other The source of properties. |
|
524 |
* |
|
525 |
* @return New {@link PropertyMap} with added properties. |
|
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 | 529 |
final Property[] otherProperties = other.properties.getProperties(); |
530 |
final PropertyHashMap newProperties = properties.immutableAdd(otherProperties); |
|
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 | 533 |
for (final Property property : otherProperties) { |
26060 | 534 |
// This method is only safe to use with non-slotted, native getter/setter properties |
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 | 537 |
} |
538 |
||
539 |
return newMap; |
|
540 |
} |
|
541 |
||
542 |
/** |
|
543 |
* Return an array of all properties. |
|
544 |
* |
|
545 |
* @return Properties as an array. |
|
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 | 548 |
return properties.getProperties(); |
549 |
} |
|
550 |
||
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 | 561 |
* Prevents the map from having additional properties. |
562 |
* |
|
563 |
* @return New map with {@link #NOT_EXTENSIBLE} flag set. |
|
564 |
*/ |
|
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 | 567 |
} |
568 |
||
569 |
/** |
|
570 |
* Prevents properties in map from being modified. |
|
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 | 574 |
*/ |
575 |
PropertyMap seal() { |
|
17513 | 576 |
PropertyHashMap newProperties = EMPTY_HASHMAP; |
16147 | 577 |
|
578 |
for (final Property oldProperty : properties.getProperties()) { |
|
579 |
newProperties = newProperties.immutableAdd(oldProperty.addFlags(Property.NOT_CONFIGURABLE)); |
|
580 |
} |
|
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 | 583 |
} |
584 |
||
585 |
/** |
|
586 |
* Prevents properties in map from being modified or written to. |
|
587 |
* |
|
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 | 590 |
*/ |
591 |
PropertyMap freeze() { |
|
17513 | 592 |
PropertyHashMap newProperties = EMPTY_HASHMAP; |
16147 | 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 | 595 |
int propertyFlags = Property.NOT_CONFIGURABLE; |
596 |
||
597 |
if (!(oldProperty instanceof UserAccessorProperty)) { |
|
598 |
propertyFlags |= Property.NOT_WRITABLE; |
|
599 |
} |
|
600 |
||
601 |
newProperties = newProperties.immutableAdd(oldProperty.addFlags(propertyFlags)); |
|
602 |
} |
|
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 | 605 |
} |
606 |
||
607 |
/** |
|
608 |
* Check for any configurable properties. |
|
609 |
* |
|
610 |
* @return {@code true} if any configurable. |
|
611 |
*/ |
|
612 |
private boolean anyConfigurable() { |
|
613 |
for (final Property property : properties.getProperties()) { |
|
614 |
if (property.isConfigurable()) { |
|
615 |
return true; |
|
616 |
} |
|
617 |
} |
|
618 |
||
619 |
return false; |
|
620 |
} |
|
621 |
||
622 |
/** |
|
623 |
* Check if all properties are frozen. |
|
624 |
* |
|
625 |
* @return {@code true} if all are frozen. |
|
626 |
*/ |
|
627 |
private boolean allFrozen() { |
|
628 |
for (final Property property : properties.getProperties()) { |
|
629 |
// check if it is a data descriptor |
|
36023 | 630 |
if (!property.isAccessorProperty() && property.isWritable()) { |
631 |
return false; |
|
16147 | 632 |
} |
633 |
if (property.isConfigurable()) { |
|
634 |
return false; |
|
635 |
} |
|
636 |
} |
|
637 |
||
638 |
return true; |
|
639 |
} |
|
640 |
||
641 |
/** |
|
642 |
* Check prototype history for an existing property map with specified prototype. |
|
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 | 645 |
* |
646 |
* @return Existing {@link PropertyMap} or {@code null} if not found. |
|
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 | 649 |
final PropertyMap cachedMap; |
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 | 652 |
cachedMap = (weakMap != null ? weakMap.get() : null); |
653 |
} else { |
|
654 |
cachedMap = null; |
|
655 |
} |
|
656 |
||
657 |
if (Context.DEBUG && cachedMap != null) { |
|
32527
b105632002c5
8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents:
31548
diff
changeset
|
658 |
protoHistoryHit.increment(); |
16147 | 659 |
} |
660 |
||
661 |
return cachedMap; |
|
662 |
} |
|
663 |
||
664 |
/** |
|
665 |
* Add a map to the prototype history. |
|
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 | 668 |
* @param newMap {@link PropertyMap} associated with prototype. |
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 | 676 |
} |
677 |
||
678 |
/** |
|
679 |
* Track the modification of the map. |
|
680 |
* |
|
681 |
* @param property Mapping property. |
|
682 |
* @param newMap Modified {@link PropertyMap}. |
|
683 |
*/ |
|
684 |
private void addToHistory(final Property property, final PropertyMap newMap) { |
|
24763 | 685 |
if (history == null) { |
686 |
history = new WeakHashMap<>(); |
|
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 | 690 |
} |
691 |
||
692 |
/** |
|
693 |
* Check the history for a map that already has the given property added. |
|
694 |
* |
|
695 |
* @param property {@link Property} to add. |
|
696 |
* |
|
697 |
* @return Existing map or {@code null} if not found. |
|
698 |
*/ |
|
699 |
private PropertyMap checkHistory(final Property property) { |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
21441
diff
changeset
|
700 |
|
16147 | 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 | 704 |
|
705 |
if (historicMap != null) { |
|
706 |
if (Context.DEBUG) { |
|
32527
b105632002c5
8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents:
31548
diff
changeset
|
707 |
historyHit.increment(); |
16147 | 708 |
} |
709 |
||
710 |
return historicMap; |
|
711 |
} |
|
712 |
} |
|
713 |
||
714 |
return null; |
|
715 |
} |
|
716 |
||
717 |
/** |
|
24719 | 718 |
* Returns true if the two maps have identical properties in the same order, but allows the properties to differ in |
719 |
* their types. This method is mostly useful for tests. |
|
720 |
* @param otherMap the other map |
|
721 |
* @return true if this map has identical properties in the same order as the other map, allowing the properties to |
|
722 |
* differ in type. |
|
723 |
*/ |
|
724 |
public boolean equalsWithoutType(final PropertyMap otherMap) { |
|
725 |
if (properties.size() != otherMap.properties.size()) { |
|
726 |
return false; |
|
727 |
} |
|
728 |
||
729 |
final Iterator<Property> iter = properties.values().iterator(); |
|
730 |
final Iterator<Property> otherIter = otherMap.properties.values().iterator(); |
|
731 |
||
732 |
while (iter.hasNext() && otherIter.hasNext()) { |
|
733 |
if (!iter.next().equalsWithoutType(otherIter.next())) { |
|
734 |
return false; |
|
735 |
} |
|
736 |
} |
|
737 |
||
738 |
return true; |
|
739 |
} |
|
740 |
||
16147 | 741 |
@Override |
742 |
public String toString() { |
|
743 |
final StringBuilder sb = new StringBuilder(); |
|
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 | 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 | 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 | 752 |
} |
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 | 755 |
|
756 |
return sb.toString(); |
|
757 |
} |
|
758 |
||
759 |
@Override |
|
760 |
public Iterator<Object> iterator() { |
|
761 |
return new PropertyMapIterator(this); |
|
762 |
} |
|
763 |
||
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 | 774 |
* Test to see if {@link PropertyMap} is extensible. |
775 |
* |
|
776 |
* @return {@code true} if {@link PropertyMap} can be added to. |
|
777 |
*/ |
|
778 |
boolean isExtensible() { |
|
779 |
return (flags & NOT_EXTENSIBLE) == 0; |
|
780 |
} |
|
781 |
||
782 |
/** |
|
783 |
* Test to see if {@link PropertyMap} is not extensible or any properties |
|
784 |
* can not be modified. |
|
785 |
* |
|
786 |
* @return {@code true} if {@link PropertyMap} is sealed. |
|
787 |
*/ |
|
788 |
boolean isSealed() { |
|
789 |
return !isExtensible() && !anyConfigurable(); |
|
790 |
} |
|
791 |
||
792 |
/** |
|
793 |
* Test to see if {@link PropertyMap} is not extensible or all properties |
|
794 |
* can not be modified. |
|
795 |
* |
|
796 |
* @return {@code true} if {@link PropertyMap} is frozen. |
|
797 |
*/ |
|
798 |
boolean isFrozen() { |
|
799 |
return !isExtensible() && allFrozen(); |
|
800 |
} |
|
26060 | 801 |
|
17513 | 802 |
/** |
26060 | 803 |
* Return a free field slot for this map, or {@code -1} if none is available. |
17513 | 804 |
* |
26060 | 805 |
* @return free field slot or -1 |
17513 | 806 |
*/ |
26060 | 807 |
int getFreeFieldSlot() { |
808 |
if (freeSlots != null) { |
|
809 |
final int freeSlot = freeSlots.nextSetBit(0); |
|
810 |
if (freeSlot > -1 && freeSlot < fieldMaximum) { |
|
811 |
return freeSlot; |
|
812 |
} |
|
813 |
} |
|
814 |
if (fieldCount < fieldMaximum) { |
|
815 |
return fieldCount; |
|
816 |
} |
|
817 |
return -1; |
|
17513 | 818 |
} |
16147 | 819 |
|
820 |
/** |
|
26060 | 821 |
* Get a free spill slot for this map. |
16147 | 822 |
* |
26060 | 823 |
* @return free spill slot |
16147 | 824 |
*/ |
26060 | 825 |
int getFreeSpillSlot() { |
826 |
if (freeSlots != null) { |
|
827 |
final int freeSlot = freeSlots.nextSetBit(fieldMaximum); |
|
828 |
if (freeSlot > -1) { |
|
829 |
return freeSlot - fieldMaximum; |
|
830 |
} |
|
831 |
} |
|
16147 | 832 |
return spillLength; |
833 |
} |
|
834 |
||
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 | 837 |
* |
17513 | 838 |
* @param newProto New prototype object to replace oldProto. |
16147 | 839 |
* @return New {@link PropertyMap} with prototype changed. |
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 | 843 |
if (nextMap != null) { |
844 |
return nextMap; |
|
845 |
} |
|
846 |
||
847 |
if (Context.DEBUG) { |
|
32527
b105632002c5
8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents:
31548
diff
changeset
|
848 |
setProtoNewMapCount.increment(); |
16147 | 849 |
} |
17513 | 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 | 853 |
|
854 |
return newMap; |
|
855 |
} |
|
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 | 917 |
|
918 |
/** |
|
919 |
* {@link PropertyMap} iterator. |
|
920 |
*/ |
|
921 |
private static class PropertyMapIterator implements Iterator<Object> { |
|
922 |
/** Property iterator. */ |
|
923 |
final Iterator<Property> iter; |
|
924 |
||
925 |
/** Current Property. */ |
|
926 |
Property property; |
|
927 |
||
928 |
/** |
|
929 |
* Constructor. |
|
930 |
* |
|
931 |
* @param propertyMap {@link PropertyMap} to iterate over. |
|
932 |
*/ |
|
933 |
PropertyMapIterator(final PropertyMap propertyMap) { |
|
934 |
iter = Arrays.asList(propertyMap.properties.getProperties()).iterator(); |
|
935 |
property = iter.hasNext() ? iter.next() : null; |
|
936 |
skipNotEnumerable(); |
|
937 |
} |
|
938 |
||
939 |
/** |
|
940 |
* Ignore properties that are not enumerable. |
|
941 |
*/ |
|
942 |
private void skipNotEnumerable() { |
|
943 |
while (property != null && !property.isEnumerable()) { |
|
944 |
property = iter.hasNext() ? iter.next() : null; |
|
945 |
} |
|
946 |
} |
|
947 |
||
948 |
@Override |
|
949 |
public boolean hasNext() { |
|
950 |
return property != null; |
|
951 |
} |
|
952 |
||
953 |
@Override |
|
954 |
public Object next() { |
|
955 |
if (property == null) { |
|
956 |
throw new NoSuchElementException(); |
|
957 |
} |
|
958 |
||
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 | 961 |
skipNotEnumerable(); |
962 |
||
963 |
return key; |
|
964 |
} |
|
965 |
||
966 |
@Override |
|
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 | 969 |
} |
970 |
} |
|
971 |
||
972 |
/* |
|
973 |
* Debugging and statistics. |
|
974 |
*/ |
|
975 |
||
24719 | 976 |
/** |
977 |
* Debug helper function that returns the diff of two property maps, only |
|
978 |
* displaying the information that is different and in which map it exists |
|
979 |
* compared to the other map. Can be used to e.g. debug map guards and |
|
980 |
* investigate why they fail, causing relink |
|
981 |
* |
|
982 |
* @param map0 the first property map |
|
983 |
* @param map1 the second property map |
|
984 |
* |
|
985 |
* @return property map diff as string |
|
986 |
*/ |
|
987 |
public static String diff(final PropertyMap map0, final PropertyMap map1) { |
|
988 |
final StringBuilder sb = new StringBuilder(); |
|
989 |
||
990 |
if (map0 != map1) { |
|
991 |
sb.append(">>> START: Map diff"); |
|
992 |
boolean found = false; |
|
993 |
||
994 |
for (final Property p : map0.getProperties()) { |
|
995 |
final Property p2 = map1.findProperty(p.getKey()); |
|
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 | 998 |
found = true; |
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 | 1001 |
found = true; |
1002 |
} |
|
1003 |
} |
|
1004 |
||
1005 |
for (final Property p2 : map1.getProperties()) { |
|
1006 |
final Property p1 = map0.findProperty(p2.getKey()); |
|
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 | 1009 |
found = true; |
1010 |
} |
|
1011 |
} |
|
1012 |
||
1013 |
//assert found; |
|
1014 |
||
1015 |
if (!found) { |
|
1016 |
sb.append(map0). |
|
1017 |
append("!="). |
|
1018 |
append(map1); |
|
1019 |
} |
|
1020 |
||
1021 |
sb.append("<<< END: Map diff\n"); |
|
1022 |
} |
|
1023 |
||
1024 |
return sb.toString(); |
|
1025 |
} |
|
1026 |
||
16147 | 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 | 1044 |
|
1045 |
/** |
|
1046 |
* @return Total number of maps. |
|
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 | 1050 |
} |
1051 |
||
1052 |
/** |
|
1053 |
* @return The number of maps that were cloned. |
|
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 | 1057 |
} |
1058 |
||
1059 |
/** |
|
1060 |
* @return The number of times history was successfully used. |
|
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 | 1064 |
} |
1065 |
||
1066 |
/** |
|
1067 |
* @return The number of times prototype changes caused invalidation. |
|
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 | 1071 |
} |
1072 |
||
1073 |
/** |
|
1074 |
* @return The number of times proto history was successfully used. |
|
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 | 1078 |
} |
1079 |
||
1080 |
/** |
|
1081 |
* @return The number of times prototypes were modified. |
|
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 | 1085 |
} |
1086 |
} |