src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java
author hannesw
Fri, 24 May 2019 16:53:44 +0200
changeset 58624 26867ad686e9
parent 55463 31bf7b93df5d
permissions -rw-r--r--
8223518: Unexpected exception in jjs Reviewed-by: sundar, mschoene, rhalade, jlaskey
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
55463
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     1
/*
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     4
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     7
 * published by the Free Software Foundation.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     8
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    13
 * accompanied this code).
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    14
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    18
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    21
 * questions.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    22
 */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    23
package jdk.vm.ci.hotspot;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    24
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    25
import java.util.ArrayList;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    26
import java.util.List;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    27
import java.util.Objects;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    28
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    29
import jdk.vm.ci.services.Services;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    30
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    31
/**
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    32
 * A mechanism for limiting the lifetime of a foreign object reference encapsulated in a
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    33
 * {@link HotSpotObjectConstant}.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    34
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    35
 * A {@link HotSpotObjectConstant} allocated in a {@linkplain #openLocalScope local} scope will have
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    36
 * its reference to any foreign object cleared when the scope {@linkplain #close() closes}. This
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    37
 * allows the foreign memory manager to reclaim the foreign object (once there are no other strong
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    38
 * references to it).
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    39
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    40
 * {@link HotSpotObjectConstantScope}s have no impact on {@link HotSpotObjectConstant}s that do not
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    41
 * encapsulate a foreign object reference.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    42
 *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    43
 * The object returned by {@link #enterGlobalScope()} or {@link #openLocalScope(Object)} should
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    44
 * always be used in a try-with-resources statement. Failure to close a scope will almost certainly
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    45
 * result in foreign objects being leaked.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    46
 */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    47
public final class HotSpotObjectConstantScope implements AutoCloseable {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    48
    static final ThreadLocal<HotSpotObjectConstantScope> CURRENT = new ThreadLocal<>();
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    49
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    50
    private final HotSpotObjectConstantScope parent;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    51
    private List<IndirectHotSpotObjectConstantImpl> foreignObjects;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    52
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    53
    /**
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    54
     * An object whose {@link Object#toString()} value describes a non-global scope. This is
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    55
     * {@code null} iff this is a global scope.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    56
     */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    57
    final Object localScopeDescription;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    58
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    59
    /**
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    60
     * Opens a local scope that upon closing, will release foreign object references encapsulated by
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    61
     * {@link HotSpotObjectConstant}s created in the scope.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    62
     *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    63
     * @param description an non-null object whose {@link Object#toString()} value describes the
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    64
     *            scope being opened
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    65
     * @return {@code null} if the current runtime does not support remote object references
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    66
     */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    67
    public static HotSpotObjectConstantScope openLocalScope(Object description) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    68
        return Services.IS_IN_NATIVE_IMAGE ? new HotSpotObjectConstantScope(Objects.requireNonNull(description)) : null;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    69
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    70
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    71
    /**
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    72
     * Enters the global scope. This is useful to escape a local scope for execution that will
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    73
     * create foreign object references that need to outlive the local scope.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    74
     *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    75
     * Foreign object references encapsulated by {@link HotSpotObjectConstant}s created in the
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    76
     * global scope are only subject to reclamation once the {@link HotSpotObjectConstant} wrapper
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    77
     * dies.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    78
     *
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    79
     * @return {@code null} if the current runtime does not support remote object references or if
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    80
     *         this thread is currently in the global scope
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    81
     */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    82
    public static HotSpotObjectConstantScope enterGlobalScope() {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    83
        return Services.IS_IN_NATIVE_IMAGE && CURRENT.get() != null ? new HotSpotObjectConstantScope(null) : null;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    84
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    85
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    86
    private HotSpotObjectConstantScope(Object localScopeDescription) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    87
        this.parent = CURRENT.get();
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    88
        CURRENT.set(this);
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    89
        this.localScopeDescription = localScopeDescription;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    90
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    91
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    92
    /**
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    93
     * Determines if this scope is global.
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    94
     */
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    95
    boolean isGlobal() {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    96
        return localScopeDescription == null;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    97
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    98
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
    99
    void add(IndirectHotSpotObjectConstantImpl obj) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   100
        assert !isGlobal();
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   101
        if (foreignObjects == null) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   102
            foreignObjects = new ArrayList<>();
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   103
        }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   104
        foreignObjects.add(obj);
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   105
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   106
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   107
    @VMEntryPoint
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   108
    @Override
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   109
    public void close() {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   110
        if (CURRENT.get() != this) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   111
            throw new IllegalStateException("Cannot close non-active scope");
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   112
        }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   113
        if (foreignObjects != null) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   114
            for (IndirectHotSpotObjectConstantImpl obj : foreignObjects) {
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   115
                obj.clear(localScopeDescription);
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   116
            }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   117
            foreignObjects = null;
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   118
        }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   119
        CURRENT.set(parent);
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   120
    }
31bf7b93df5d 8225810: Update JVMCI
kvn
parents:
diff changeset
   121
}