src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/GlobalConstants.java
author hannesw
Wed, 21 Mar 2018 16:55:34 +0100
changeset 49275 c639a6b33c5c
parent 47216 71c04702a3d5
permissions -rw-r--r--
8199869: Missing copyright headers in nashorn source code Reviewed-by: sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33343
diff changeset
   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
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33343
diff changeset
   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
}