author | hannesw |
Wed, 21 Mar 2018 16:55:34 +0100 | |
changeset 49275 | c639a6b33c5c |
parent 47216 | 71c04702a3d5 |
permissions | -rw-r--r-- |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
1 |
/* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
2 |
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
4 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. Oracle designates this |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
10 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
15 |
* accompanied this code). |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
16 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
20 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
22 |
* or visit www.oracle.com if you need additional information or have any |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
23 |
* questions. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
24 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
25 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
26 |
package jdk.nashorn.internal.runtime; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
27 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
28 |
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
29 |
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall; |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24745
diff
changeset
|
30 |
import static jdk.nashorn.internal.lookup.Lookup.MH; |
26511
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
25865
diff
changeset
|
31 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; |
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
25865
diff
changeset
|
32 |
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.getProgramPoint; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
33 |
import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote; |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
34 |
|
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
35 |
import java.lang.invoke.MethodHandle; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
36 |
import java.lang.invoke.MethodHandles; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
37 |
import java.lang.invoke.SwitchPoint; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
38 |
import java.util.Arrays; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
39 |
import java.util.HashMap; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
40 |
import java.util.Map; |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
41 |
import java.util.concurrent.atomic.AtomicBoolean; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
42 |
import java.util.logging.Level; |
34447
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33690
diff
changeset
|
43 |
import jdk.dynalink.CallSiteDescriptor; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33690
diff
changeset
|
44 |
import jdk.dynalink.DynamicLinker; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33690
diff
changeset
|
45 |
import jdk.dynalink.linker.GuardedInvocation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33690
diff
changeset
|
46 |
import jdk.dynalink.linker.LinkRequest; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
47 |
import jdk.nashorn.internal.lookup.Lookup; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
48 |
import jdk.nashorn.internal.lookup.MethodHandleFactory; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
49 |
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
50 |
import jdk.nashorn.internal.runtime.logging.DebugLogger; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
51 |
import jdk.nashorn.internal.runtime.logging.Loggable; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
52 |
import jdk.nashorn.internal.runtime.logging.Logger; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
53 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
54 |
/** |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
55 |
* Each context owns one of these. This is basically table of accessors |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
56 |
* for global properties. A global constant is evaluated to a MethodHandle.constant |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
57 |
* for faster access and to avoid walking to proto chain looking for it. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
58 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
59 |
* We put a switchpoint on the global setter, which invalidates the |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
60 |
* method handle constant getters, and reverts to the standard access strategy |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
61 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
62 |
* However, there is a twist - while certain globals like "undefined" and "Math" |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
63 |
* are usually never reassigned, a global value can be reset once, and never again. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
64 |
* This is a rather common pattern, like: |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
65 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
66 |
* x = function(something) { ... |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
67 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
68 |
* Thus everything registered as a global constant gets an extra chance. Set once, |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
69 |
* reregister the switchpoint. Set twice or more - don't try again forever, or we'd |
32534
b3ec7f3b3c2a
8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents:
27369
diff
changeset
|
70 |
* just end up relinking our way into megamorphism. |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
71 |
* |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
72 |
* Also it has to be noted that this kind of linking creates a coupling between a Global |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
73 |
* and the call sites in compiled code belonging to the Context. For this reason, the |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
74 |
* linkage becomes incorrect as soon as the Context has more than one Global. The |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
75 |
* {@link #invalidateForever()} is invoked by the Context to invalidate all linkages and |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
76 |
* turn off the functionality of this object as soon as the Context's {@link Context#newGlobal()} is invoked |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
77 |
* for second time. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
78 |
* |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
79 |
* We can extend this to ScriptObjects in general (GLOBAL_ONLY=false), which requires |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
80 |
* a receiver guard on the constant getter, but it currently leaks memory and its benefits |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
81 |
* have not yet been investigated property. |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
82 |
* |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
83 |
* As long as all Globals in a Context share the same GlobalConstants instance, we need synchronization |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
84 |
* whenever we access it. |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
85 |
*/ |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
86 |
@Logger(name="const") |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
87 |
public final class GlobalConstants implements Loggable { |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
88 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
89 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
90 |
* Should we only try to link globals as constants, and not generic script objects. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
91 |
* Script objects require a receiver guard, which is memory intensive, so this is currently |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
92 |
* disabled. We might implement a weak reference based approach to this later. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
93 |
*/ |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
94 |
public static final boolean GLOBAL_ONLY = true; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
95 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
96 |
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
97 |
|
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
98 |
private static final MethodHandle INVALIDATE_SP = virtualCall(LOOKUP, GlobalConstants.class, "invalidateSwitchPoint", Object.class, Object.class, Access.class).methodHandle(); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
99 |
private static final MethodHandle RECEIVER_GUARD = staticCall(LOOKUP, GlobalConstants.class, "receiverGuard", boolean.class, Access.class, Object.class, Object.class).methodHandle(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
100 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
101 |
/** Logger for constant getters */ |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
102 |
private final DebugLogger log; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
103 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
104 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
105 |
* Access map for this global - associates a symbol name with an Access object, with getter |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
106 |
* and invalidation information |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
107 |
*/ |
33690 | 108 |
private final Map<Object, Access> map = new HashMap<>(); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
109 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
110 |
private final AtomicBoolean invalidatedForever = new AtomicBoolean(false); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
111 |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
112 |
/** |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
113 |
* Constructor - used only by global |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
114 |
* @param log logger, or null if none |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
115 |
*/ |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
116 |
public GlobalConstants(final DebugLogger log) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
117 |
this.log = log == null ? DebugLogger.DISABLED_LOGGER : log; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
118 |
} |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
119 |
|
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
120 |
@Override |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
121 |
public DebugLogger getLogger() { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
122 |
return log; |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
123 |
} |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
124 |
|
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
125 |
@Override |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
126 |
public DebugLogger initLogger(final Context context) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
127 |
return DebugLogger.DISABLED_LOGGER; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
128 |
} |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
129 |
|
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
130 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
131 |
* Information about a constant access and its potential invalidations |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
132 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
133 |
private static class Access { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
134 |
/** name of symbol */ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
135 |
private final String name; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
136 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
137 |
/** switchpoint that invalidates the getters and setters for this access */ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
138 |
private SwitchPoint sp; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
139 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
140 |
/** invalidation count for this access, i.e. how many times has this property been reset */ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
141 |
private int invalidations; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
142 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
143 |
/** has a guard guarding this property getter failed? */ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
144 |
private boolean guardFailed; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
145 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
146 |
private static final int MAX_RETRIES = 2; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
147 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
148 |
private Access(final String name, final SwitchPoint sp) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
149 |
this.name = name; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
150 |
this.sp = sp; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
151 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
152 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
153 |
private boolean hasBeenInvalidated() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
154 |
return sp.hasBeenInvalidated(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
155 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
156 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
157 |
private boolean guardFailed() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
158 |
return guardFailed; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
159 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
160 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
161 |
private void failGuard() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
162 |
invalidateOnce(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
163 |
guardFailed = true; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
164 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
165 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
166 |
private void newSwitchPoint() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
167 |
assert hasBeenInvalidated(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
168 |
sp = new SwitchPoint(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
169 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
170 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
171 |
private void invalidate(final int count) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
172 |
if (!sp.hasBeenInvalidated()) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
173 |
SwitchPoint.invalidateAll(new SwitchPoint[] { sp }); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
174 |
invalidations += count; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
175 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
176 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
177 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
178 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
179 |
* Invalidate the access, but do not contribute to the invalidation count |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
180 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
181 |
private void invalidateUncounted() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
182 |
invalidate(0); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
183 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
184 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
185 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
186 |
* Invalidate the access, and contribute 1 to the invalidation count |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
187 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
188 |
private void invalidateOnce() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
189 |
invalidate(1); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
190 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
191 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
192 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
193 |
* Invalidate the access and make sure that we never try to turn this into |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
194 |
* a MethodHandle.constant getter again |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
195 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
196 |
private void invalidateForever() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
197 |
invalidate(MAX_RETRIES); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
198 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
199 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
200 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
201 |
* Are we allowed to relink this as constant getter, even though it |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
202 |
* it has been reset |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
203 |
* @return true if we can relink as constant, one retry is allowed |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
204 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
205 |
private boolean mayRetry() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
206 |
return invalidations < MAX_RETRIES; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
207 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
208 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
209 |
@Override |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
210 |
public String toString() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
211 |
return "[" + quote(name) + " <id=" + Debug.id(this) + "> inv#=" + invalidations + '/' + MAX_RETRIES + " sp_inv=" + sp.hasBeenInvalidated() + ']'; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
212 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
213 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
214 |
String getName() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
215 |
return name; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
216 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
217 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
218 |
SwitchPoint getSwitchPoint() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
219 |
return sp; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
220 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
221 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
222 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
223 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
224 |
* To avoid an expensive global guard "is this the same global", similar to the |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
225 |
* receiver guard on the ScriptObject level, we invalidate all getters once |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
226 |
* when we switch globals. This is used from the class cache. We _can_ reuse |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
227 |
* the same class for a new global, but the builtins and global scoped variables |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
228 |
* will have changed. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
229 |
*/ |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
230 |
public void invalidateAll() { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
231 |
if (!invalidatedForever.get()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
232 |
log.info("New global created - invalidating all constant callsites without increasing invocation count."); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
233 |
synchronized (this) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
234 |
for (final Access acc : map.values()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
235 |
acc.invalidateUncounted(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
236 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
237 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
238 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
239 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
240 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
241 |
/** |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
242 |
* To avoid an expensive global guard "is this the same global", similar to the |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
243 |
* receiver guard on the ScriptObject level, we invalidate all getters when the |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
244 |
* second Global is created by the Context owning this instance. After this |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
245 |
* method is invoked, this GlobalConstants instance will both invalidate all the |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
246 |
* switch points it produced, and it will stop handing out new method handles |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
247 |
* altogether. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
248 |
*/ |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
249 |
public void invalidateForever() { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
250 |
if (invalidatedForever.compareAndSet(false, true)) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
251 |
log.info("New global created - invalidating all constant callsites."); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
252 |
synchronized (this) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
253 |
for (final Access acc : map.values()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
254 |
acc.invalidateForever(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
255 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
256 |
map.clear(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
257 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
258 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
259 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
260 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
261 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
262 |
* Invalidate the switchpoint of an access - we have written to |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
263 |
* the property |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
264 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
265 |
* @param obj receiver |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
266 |
* @param acc access |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
267 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
268 |
* @return receiver, so this can be used as param filter |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
269 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
270 |
@SuppressWarnings("unused") |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
271 |
private synchronized Object invalidateSwitchPoint(final Object obj, final Access acc) { |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
272 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
273 |
log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
274 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
275 |
acc.invalidateOnce(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
276 |
if (acc.mayRetry()) { |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
277 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
278 |
log.info("Retry is allowed for " + acc + "... Creating a new switchpoint."); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
279 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
280 |
acc.newSwitchPoint(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
281 |
} else { |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
282 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24738
diff
changeset
|
283 |
log.info("This was the last time I allowed " + quote(acc.getName()) + " to relink as constant."); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
284 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
285 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
286 |
return obj; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
287 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
288 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
289 |
private Access getOrCreateSwitchPoint(final String name) { |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
290 |
Access acc = map.get(name); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
291 |
if (acc != null) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
292 |
return acc; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
293 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
294 |
final SwitchPoint sp = new SwitchPoint(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
295 |
map.put(name, acc = new Access(name, sp)); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
296 |
return acc; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
297 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
298 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
299 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
300 |
* Called from script object on property deletion to erase a property |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
301 |
* that might be linked as MethodHandle.constant and force relink |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
302 |
* @param name name of property |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
303 |
*/ |
33690 | 304 |
void delete(final Object name) { |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
305 |
if (!invalidatedForever.get()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
306 |
synchronized (this) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
307 |
final Access acc = map.get(name); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
308 |
if (acc != null) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
309 |
acc.invalidateForever(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
310 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
311 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
312 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
313 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
314 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
315 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
316 |
* Receiver guard is used if we extend the global constants to script objects in general. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
317 |
* As the property can have different values in different script objects, while Global is |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
318 |
* by definition a singleton, we need this for ScriptObject constants (currently disabled) |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
319 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
320 |
* TODO: Note - this seems to cause memory leaks. Use weak references? But what is leaking seems |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
321 |
* to be the Access objects, which isn't the case for Globals. Weird. |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
322 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
323 |
* @param acc access |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
324 |
* @param boundReceiver the receiver bound to the callsite |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
325 |
* @param receiver the receiver to check against |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
326 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
327 |
* @return true if this receiver is still the one we bound to the callsite |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
328 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
329 |
@SuppressWarnings("unused") |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
330 |
private static boolean receiverGuard(final Access acc, final Object boundReceiver, final Object receiver) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
331 |
final boolean id = receiver == boundReceiver; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
332 |
if (!id) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
333 |
acc.failGuard(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
334 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
335 |
return id; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
336 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
337 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
338 |
private static boolean isGlobalSetter(final ScriptObject receiver, final FindProperty find) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
339 |
if (find == null) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
340 |
return receiver.isScope(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
341 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
342 |
return find.getOwner().isGlobal(); |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
343 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
344 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
345 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
346 |
* Augment a setter with switchpoint for invalidating its getters, should the setter be called |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
347 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
348 |
* @param find property lookup |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
349 |
* @param inv normal guarded invocation for this setter, as computed by the ScriptObject linker |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
350 |
* @param desc callsite descriptor |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
351 |
* @param request link request |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
352 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
353 |
* @return null if failed to set up constant linkage |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
354 |
*/ |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
355 |
GuardedInvocation findSetMethod(final FindProperty find, final ScriptObject receiver, final GuardedInvocation inv, final CallSiteDescriptor desc, final LinkRequest request) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
356 |
if (invalidatedForever.get() || (GLOBAL_ONLY && !isGlobalSetter(receiver, find))) { |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
357 |
return null; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
358 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
359 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
32534
diff
changeset
|
360 |
final String name = NashornCallSiteDescriptor.getOperand(desc); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
361 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
362 |
synchronized (this) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
363 |
final Access acc = getOrCreateSwitchPoint(name); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
364 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
365 |
if (log.isEnabled()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
366 |
log.fine("Trying to link constant SETTER ", acc); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
367 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
368 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
369 |
if (!acc.mayRetry() || invalidatedForever.get()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
370 |
if (log.isEnabled()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
371 |
log.fine("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
372 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
373 |
return null; |
27103
7a1a7ab2879c
8060471: DynamicLinker.getLinkedCallSiteLocation() is called even when logger is disabled, and it creates a stacktrace. This contributes unnecessarily to compile time.
lagergren
parents:
26768
diff
changeset
|
374 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
375 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
376 |
if (acc.hasBeenInvalidated()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
377 |
log.info("New chance for " + acc); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
378 |
acc.newSwitchPoint(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
379 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
380 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
381 |
assert !acc.hasBeenInvalidated(); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
382 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
383 |
// if we haven't given up on this symbol, add a switchpoint invalidation filter to the receiver parameter |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
384 |
final MethodHandle target = inv.getInvocation(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
385 |
final Class<?> receiverType = target.type().parameterType(0); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
386 |
final MethodHandle boundInvalidator = MH.bindTo(INVALIDATE_SP, this); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
387 |
final MethodHandle invalidator = MH.asType(boundInvalidator, boundInvalidator.type().changeParameterType(0, receiverType).changeReturnType(receiverType)); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
388 |
final MethodHandle mh = MH.filterArguments(inv.getInvocation(), 0, MH.insertArguments(invalidator, 1, acc)); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
389 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
390 |
assert inv.getSwitchPoints() == null : Arrays.asList(inv.getSwitchPoints()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
391 |
log.info("Linked setter " + quote(name) + " " + acc.getSwitchPoint()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
392 |
return new GuardedInvocation(mh, inv.getGuard(), acc.getSwitchPoint(), inv.getException()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
393 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
394 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
395 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
396 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
397 |
* Try to reuse constant method handles for getters |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
398 |
* @param c constant value |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
399 |
* @return method handle (with dummy receiver) that returns this constant |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
400 |
*/ |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
401 |
public static MethodHandle staticConstantGetter(final Object c) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
402 |
return MH.dropArguments(JSType.unboxConstant(c), 0, Object.class); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
403 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
404 |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
405 |
private MethodHandle constantGetter(final Object c) { |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
406 |
final MethodHandle mh = staticConstantGetter(c); |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
407 |
if (log.isEnabled()) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
408 |
return MethodHandleFactory.addDebugPrintout(log, Level.FINEST, mh, "getting as constant"); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
409 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
410 |
return mh; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
411 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
412 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
413 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
414 |
* Try to turn a getter into a MethodHandle.constant, if possible |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
415 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
416 |
* @param find property lookup |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
417 |
* @param receiver receiver |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
418 |
* @param desc callsite descriptor |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
419 |
* |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
420 |
* @return resulting getter, or null if failed to create constant |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
421 |
*/ |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
422 |
GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
423 |
// Only use constant getter for fast scope access, because the receiver may change between invocations |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
424 |
// for slow-scope and non-scope callsites. |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
425 |
// Also return null for user accessor properties as they may have side effects. |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
426 |
if (invalidatedForever.get() || !NashornCallSiteDescriptor.isFastScope(desc) |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
427 |
|| (GLOBAL_ONLY && !find.getOwner().isGlobal()) |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
428 |
|| find.getProperty() instanceof UserAccessorProperty) { |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
429 |
return null; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
430 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
431 |
|
26511
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
25865
diff
changeset
|
432 |
final boolean isOptimistic = NashornCallSiteDescriptor.isOptimistic(desc); |
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
25865
diff
changeset
|
433 |
final int programPoint = isOptimistic ? getProgramPoint(desc) : INVALID_PROGRAM_POINT; |
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
25865
diff
changeset
|
434 |
final Class<?> retType = desc.getMethodType().returnType(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
32534
diff
changeset
|
435 |
final String name = NashornCallSiteDescriptor.getOperand(desc); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
436 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
437 |
synchronized (this) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
438 |
final Access acc = getOrCreateSwitchPoint(name); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
439 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
440 |
log.fine("Starting to look up object value " + name); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
441 |
final Object c = find.getObjectValue(); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
442 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
443 |
if (log.isEnabled()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
444 |
log.fine("Trying to link constant GETTER " + acc + " value = " + c); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
445 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
446 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
447 |
if (acc.hasBeenInvalidated() || acc.guardFailed() || invalidatedForever.get()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
448 |
if (log.isEnabled()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
449 |
log.info("*** GET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
450 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
451 |
return null; |
27103
7a1a7ab2879c
8060471: DynamicLinker.getLinkedCallSiteLocation() is called even when logger is disabled, and it creates a stacktrace. This contributes unnecessarily to compile time.
lagergren
parents:
26768
diff
changeset
|
452 |
} |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
453 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
454 |
final MethodHandle cmh = constantGetter(c); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
455 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
456 |
MethodHandle mh; |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
457 |
MethodHandle guard; |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
458 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
459 |
if (isOptimistic) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
460 |
if (JSType.getAccessorTypeIndex(cmh.type().returnType()) <= JSType.getAccessorTypeIndex(retType)) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
461 |
//widen return type - this is pessimistic, so it will always work |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
462 |
mh = MH.asType(cmh, cmh.type().changeReturnType(retType)); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
463 |
} else { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
464 |
//immediately invalidate - we asked for a too wide constant as a narrower one |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
465 |
mh = MH.dropArguments(MH.insertArguments(JSType.THROW_UNWARRANTED.methodHandle(), 0, c, programPoint), 0, Object.class); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
466 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
467 |
} else { |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
468 |
//pessimistic return type filter |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
469 |
mh = Lookup.filterReturnType(cmh, retType); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
470 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
471 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
472 |
if (find.getOwner().isGlobal()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
473 |
guard = null; |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
474 |
} else { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
475 |
guard = MH.insertArguments(RECEIVER_GUARD, 0, acc, receiver); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
476 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
477 |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
478 |
if (log.isEnabled()) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
479 |
log.info("Linked getter " + quote(name) + " as MethodHandle.constant() -> " + c + " " + acc.getSwitchPoint()); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
480 |
mh = MethodHandleFactory.addDebugPrintout(log, Level.FINE, mh, "get const " + acc); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
481 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
482 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27103
diff
changeset
|
483 |
return new GuardedInvocation(mh, guard, acc.getSwitchPoint(), null); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
484 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
485 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
diff
changeset
|
486 |
} |