Skip to content

Commit 3b0ee5a

Browse files
author
Vladimir Kozlov
committed
8225810: Update JVMCI
Reviewed-by: never, dnsimon
1 parent c956e7c commit 3b0ee5a

File tree

15 files changed

+380
-43
lines changed

15 files changed

+380
-43
lines changed

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,33 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jcla
568568
return JVMCIENV->get_jobject(result);
569569
C2V_END
570570

571+
C2V_VMENTRY_NULL(jobject, getArrayType, (JNIEnv* env, jobject, jobject jvmci_type))
572+
if (jvmci_type == NULL) {
573+
JVMCI_THROW_0(NullPointerException);
574+
}
575+
576+
JVMCIObject jvmci_type_object = JVMCIENV->wrap(jvmci_type);
577+
JVMCIKlassHandle array_klass(THREAD);
578+
if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(jvmci_type_object)) {
579+
BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(jvmci_type_object), JVMCI_CHECK_0);
580+
if (type == T_VOID) {
581+
return NULL;
582+
}
583+
array_klass = Universe::typeArrayKlassObj(type);
584+
if (array_klass == NULL) {
585+
JVMCI_THROW_MSG_NULL(InternalError, err_msg("No array klass for primitive type %s", type2name(type)));
586+
}
587+
} else {
588+
Klass* klass = JVMCIENV->asKlass(jvmci_type);
589+
if (klass == NULL) {
590+
JVMCI_THROW_0(NullPointerException);
591+
}
592+
array_klass = klass->array_klass(CHECK_NULL);
593+
}
594+
JVMCIObject result = JVMCIENV->get_jvmci_type(array_klass, JVMCI_CHECK_NULL);
595+
return JVMCIENV->get_jobject(result);
596+
C2V_END
597+
571598
C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
572599
requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);
573600
if (mirror == NULL) {
@@ -2578,6 +2605,18 @@ C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong faile
25782605
return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
25792606
}
25802607

2608+
C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status))
2609+
JavaValue result(T_VOID);
2610+
JavaCallArguments jargs(1);
2611+
jargs.push_int(status);
2612+
JavaCalls::call_static(&result,
2613+
SystemDictionary::System_klass(),
2614+
vmSymbols::exit_method_name(),
2615+
vmSymbols::int_void_signature(),
2616+
&jargs,
2617+
CHECK);
2618+
}
2619+
25812620
#define CC (char*) /*cast a literal from (const char*)*/
25822621
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
25832622

@@ -2624,6 +2663,7 @@ JNINativeMethod CompilerToVM::methods[] = {
26242663
{CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)},
26252664
{CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},
26262665
{CC "lookupType", CC "(" STRING HS_RESOLVED_KLASS "Z)" HS_RESOLVED_TYPE, FN_PTR(lookupType)},
2666+
{CC "getArrayType", CC "(" HS_RESOLVED_TYPE ")" HS_RESOLVED_KLASS, FN_PTR(getArrayType)},
26272667
{CC "lookupClass", CC "(" CLASS ")" HS_RESOLVED_TYPE, FN_PTR(lookupClass)},
26282668
{CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},
26292669
{CC "lookupNameAndTypeRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)},
@@ -2723,6 +2763,7 @@ JNINativeMethod CompilerToVM::methods[] = {
27232763
{CC "getFailedSpeculationsAddress", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getFailedSpeculationsAddress)},
27242764
{CC "releaseFailedSpeculations", CC "(J)V", FN_PTR(releaseFailedSpeculations)},
27252765
{CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)},
2766+
{CC "callSystemExit", CC "(I)V", FN_PTR(callSystemExit)},
27262767
};
27272768

27282769
int CompilerToVM::methods_count() {

src/hotspot/share/jvmci/jvmciEnv.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,9 @@ Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
13611361
return Handle(THREAD, obj);
13621362
} else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
13631363
jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1364+
if (object_handle == 0L) {
1365+
JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
1366+
}
13641367
oop result = resolve_handle(object_handle);
13651368
if (result == NULL) {
13661369
JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,12 @@ HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean com
770770
*/
771771
native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl type);
772772

773+
/**
774+
* Get the array class for {@code type}. This can't be done symbolically since anonymous types
775+
* can't be looked up by name.
776+
*/
777+
native HotSpotResolvedObjectTypeImpl getArrayType(HotSpotResolvedJavaType type);
778+
773779
/**
774780
* Forces initialization of {@code type}.
775781
*/
@@ -978,4 +984,9 @@ HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean com
978984
* @see HotSpotJVMCIRuntime#detachCurrentThread()
979985
*/
980986
native void detachCurrentThread();
987+
988+
/**
989+
* @see HotSpotJVMCIRuntime#exitHotSpot(int)
990+
*/
991+
native void callSystemExit(int status);
981992
}

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ public long getJvmciEnv() {
8787
public int getId() {
8888
return id;
8989
}
90+
91+
@Override
92+
public String toString() {
93+
return id + ":" + super.toString();
94+
}
9095
}

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ public enum Option {
223223
// so that -XX:+JVMCIPrintProperties shows the option.
224224
InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."),
225225
PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."),
226+
AuditHandles(Boolean.class, false, "Record stack trace along with scoped foreign object reference wrappers " +
227+
"to debug issue with a wrapper being used after its scope has closed."),
226228
TraceMethodDataFilter(String.class, null,
227229
"Enables tracing of profiling info when read by JVMCI.",
228230
"Empty value: trace all methods",
@@ -687,9 +689,11 @@ public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
687689
return Collections.unmodifiableMap(backends);
688690
}
689691

692+
@SuppressWarnings("try")
690693
@VMEntryPoint
691694
private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) {
692-
CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, compileState, id));
695+
HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, compileState, id);
696+
CompilationRequestResult result = getCompiler().compileMethod(request);
693697
assert result != null : "compileMethod must always return something";
694698
HotSpotCompilationRequestResult hsResult;
695699
if (result instanceof HotSpotCompilationRequestResult) {
@@ -704,7 +708,6 @@ private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod
704708
hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes);
705709
}
706710
}
707-
708711
return hsResult;
709712
}
710713

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

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@
2222
*/
2323
package jdk.vm.ci.hotspot;
2424

25+
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
26+
2527
import jdk.vm.ci.meta.JavaConstant;
2628
import jdk.vm.ci.meta.ResolvedJavaType;
2729

2830
public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
2931

32+
HotSpotResolvedObjectTypeImpl arrayOfType;
33+
3034
HotSpotResolvedJavaType(String name) {
3135
super(name);
3236
}
@@ -40,4 +44,12 @@ public final int hashCode() {
4044
}
4145

4246
abstract JavaConstant getJavaMirror();
47+
48+
@Override
49+
public HotSpotResolvedObjectType getArrayClass() {
50+
if (arrayOfType == null) {
51+
arrayOfType = runtime().compilerToVm.getArrayType(this);
52+
}
53+
return arrayOfType;
54+
}
4355
}

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
7272
private volatile HotSpotResolvedJavaField[] instanceFields;
7373
private volatile HotSpotResolvedObjectTypeImpl[] interfaces;
7474
private HotSpotConstantPool constantPool;
75-
private HotSpotResolvedObjectType arrayOfType;
7675
private final JavaConstant mirror;
7776
private HotSpotResolvedObjectTypeImpl superClass;
7877

@@ -103,17 +102,24 @@ private static HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer, St
103102
* Creates the JVMCI mirror for a {@link Class} object.
104103
*
105104
* <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
106-
* {@link Class} type. {@link #fromMetaspace} instead.
105+
* {@link Class} type.
107106
* </p>
108107
*
109108
* @param metadataPointer the Klass* to create the mirror for
110109
*/
110+
@SuppressWarnings("try")
111111
HotSpotResolvedObjectTypeImpl(long metadataPointer, String name) {
112112
super(name);
113-
this.metadataPointer = metadataPointer;
114-
this.mirror = runtime().compilerToVm.getJavaMirror(this);
115113
assert metadataPointer != 0;
116-
assert getName().charAt(0) != '[' || isArray() : getName();
114+
this.metadataPointer = metadataPointer;
115+
116+
// The mirror object must be in the global scope since
117+
// this object will be cached in HotSpotJVMCIRuntime.resolvedJavaTypes
118+
// and live across more than one compilation.
119+
try (HotSpotObjectConstantScope global = HotSpotObjectConstantScope.enterGlobalScope()) {
120+
this.mirror = runtime().compilerToVm.getJavaMirror(this);
121+
assert getName().charAt(0) != '[' || isArray() : getName();
122+
}
117123
}
118124

119125
/**
@@ -146,18 +152,6 @@ public int getAccessFlags() {
146152
return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
147153
}
148154

149-
@Override
150-
public HotSpotResolvedObjectType getArrayClass() {
151-
if (arrayOfType == null) {
152-
try {
153-
arrayOfType = (HotSpotResolvedObjectType) runtime().compilerToVm.lookupType("[" + getName(), this, true);
154-
} catch (ClassNotFoundException e) {
155-
throw new JVMCIError(e);
156-
}
157-
}
158-
return arrayOfType;
159-
}
160-
161155
@Override
162156
public ResolvedJavaType getComponentType() {
163157
return runtime().compilerToVm.getComponentType(this);
@@ -580,6 +574,11 @@ public AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJav
580574
return null;
581575
}
582576

577+
if (resolvedMethod.canBeStaticallyBound()) {
578+
// No assumptions are required.
579+
return new AssumptionResult<>(resolvedMethod);
580+
}
581+
583582
ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
584583
if (result != null) {
585584
return new AssumptionResult<>(result, new ConcreteMethod(method, this, result));

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
4646
@NativeImageReinitialize static HotSpotResolvedPrimitiveType[] primitives;
4747

4848
private JavaKind kind;
49-
private HotSpotResolvedObjectType arrayClass;
5049
HotSpotObjectConstantImpl mirror;
5150

5251
/**
@@ -87,14 +86,7 @@ public HotSpotResolvedObjectType getArrayClass() {
8786
if (kind == JavaKind.Void) {
8887
return null;
8988
}
90-
if (arrayClass == null) {
91-
try {
92-
arrayClass = (HotSpotResolvedObjectType) runtime().compilerToVm.lookupType("[" + kind.getTypeChar(), null, true);
93-
} catch (ClassNotFoundException e) {
94-
throw new JVMCIError(e);
95-
}
96-
}
97-
return arrayClass;
89+
return super.getArrayClass();
9890
}
9991

10092
@Override

0 commit comments

Comments
 (0)