Skip to content

Commit e7fe782

Browse files
committed
added jdk.graal.compiler.word.WordFactory
1 parent dd2c3a2 commit e7fe782

File tree

7 files changed

+269
-100
lines changed

7 files changed

+269
-100
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CheckGraalInvariants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ public static void runTest(InvariantsTool tool) {
337337
verifiers.add(new VerifyVirtualizableUsage());
338338
verifiers.add(new VerifyUpdateUsages());
339339
verifiers.add(new VerifyLibGraalContextChecks());
340+
verifiers.add(new VerifyWordFactoryUsage());
340341
verifiers.add(new VerifyBailoutUsage());
341342
verifiers.add(new VerifySystemPropertyUsage());
342343
verifiers.add(new VerifyInstanceOfUsage());
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024, 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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.core.test;
26+
27+
import jdk.graal.compiler.nodes.StructuredGraph;
28+
import jdk.graal.compiler.nodes.java.MethodCallTargetNode;
29+
import jdk.graal.compiler.nodes.spi.CoreProviders;
30+
import jdk.graal.compiler.phases.VerifyPhase;
31+
import jdk.vm.ci.meta.MetaUtil;
32+
33+
/**
34+
* Ensures that Graal compiler code uses {@link jdk.graal.compiler.word.WordFactory} instead of
35+
* {@link org.graalvm.word.WordFactory} to create word values.
36+
*/
37+
public class VerifyWordFactoryUsage extends VerifyPhase<CoreProviders> {
38+
39+
@Override
40+
public boolean checkContract() {
41+
return false;
42+
}
43+
44+
@Override
45+
protected void verify(StructuredGraph graph, CoreProviders context) {
46+
47+
String badWordFactory = MetaUtil.toInternalName(org.graalvm.word.WordFactory.class.getName());
48+
49+
for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
50+
if (t.targetMethod().getDeclaringClass().getName().equals(badWordFactory)) {
51+
throw new VerificationError("accessing %s in %s is prohibited - use %s instead",
52+
badWordFactory,
53+
graph.method().format("%H.%n(%p)"),
54+
jdk.graal.compiler.word.WordFactory.class.getName());
55+
56+
}
57+
}
58+
}
59+
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/word/Word.java

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,6 @@
3535
import org.graalvm.word.SignedWord;
3636
import org.graalvm.word.UnsignedWord;
3737
import org.graalvm.word.WordBase;
38-
import org.graalvm.word.WordFactory;
39-
import org.graalvm.word.impl.WordBoxFactory;
4038

4139
import jdk.graal.compiler.core.common.calc.Condition;
4240
import jdk.graal.compiler.core.common.calc.UnsignedMath;
@@ -63,14 +61,6 @@ public abstract class Word implements SignedWord, UnsignedWord, Pointer {
6361

6462
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
6563

66-
static {
67-
BoxFactoryImpl.initialize();
68-
}
69-
70-
public static void ensureInitialized() {
71-
/* Calling this method ensures that the static initializer has been executed. */
72-
}
73-
7464
/**
7565
* Links a method to a canonical operation represented by an {@link Opcode} val.
7666
*/
@@ -119,19 +109,6 @@ public enum Opcode {
119109
TO_RAW_VALUE,
120110
}
121111

122-
static class BoxFactoryImpl extends WordBoxFactory {
123-
static void initialize() {
124-
assert boxFactory == null : "BoxFactory must be initialized only once.";
125-
boxFactory = new BoxFactoryImpl();
126-
}
127-
128-
@SuppressWarnings("unchecked")
129-
@Override
130-
public <T extends WordBase> T boxImpl(long val) {
131-
return (T) HostedWord.boxLong(val);
132-
}
133-
}
134-
135112
/*
136113
* Outside users must use the different signed() and unsigned() methods to ensure proper
137114
* expansion of 32-bit values on 64-bit systems.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package jdk.graal.compiler.word;
42+
43+
import org.graalvm.word.PointerBase;
44+
import org.graalvm.word.SignedWord;
45+
import org.graalvm.word.UnsignedWord;
46+
import org.graalvm.word.WordBase;
47+
import org.graalvm.word.impl.WordFactoryOpcode;
48+
import org.graalvm.word.impl.WordFactoryOperation;
49+
50+
/**
51+
* Provides factory methods to create boxed {@link WordBase} objects specific to the class loader
52+
* loading this class. This avoids type confusion caused by using
53+
* {@link org.graalvm.word.WordFactory} which can lead word objects specific to one class loader
54+
* (e.g. the libgraal class loader) into code expecting word objects loaded by another class loader
55+
* (e.g. the native image class loader).
56+
*/
57+
public final class WordFactory {
58+
59+
private WordFactory() {
60+
}
61+
62+
@SuppressWarnings("unchecked")
63+
private static <T extends WordBase> T box(long val) {
64+
return (T) HostedWord.boxLong(val);
65+
}
66+
67+
/**
68+
* @see org.graalvm.word.WordFactory#zero()
69+
*/
70+
@WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
71+
public static <T extends WordBase> T zero() {
72+
return box(0L);
73+
}
74+
75+
/**
76+
* @see org.graalvm.word.WordFactory#nullPointer()
77+
*/
78+
@WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
79+
public static <T extends PointerBase> T nullPointer() {
80+
return box(0L);
81+
}
82+
83+
/**
84+
* @see org.graalvm.word.WordFactory#pointer(long)
85+
*/
86+
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
87+
public static <T extends PointerBase> T pointer(long val) {
88+
return box(val);
89+
}
90+
91+
/**
92+
* @see org.graalvm.word.WordFactory#unsigned(int)
93+
*/
94+
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
95+
public static <T extends UnsignedWord> T unsigned(int val) {
96+
return box(val & 0xffffffffL);
97+
}
98+
99+
/**
100+
* @see org.graalvm.word.WordFactory#unsigned(long)
101+
*/
102+
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
103+
public static <T extends UnsignedWord> T unsigned(long val) {
104+
return box(val);
105+
}
106+
107+
/**
108+
* @see org.graalvm.word.WordFactory#signed(int)
109+
*/
110+
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
111+
public static <T extends SignedWord> T signed(int val) {
112+
return box(val);
113+
}
114+
115+
/**
116+
* @see org.graalvm.word.WordFactory#signed(long)
117+
*/
118+
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
119+
public static <T extends SignedWord> T signed(long val) {
120+
return box(val);
121+
}
122+
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/word/WordTypes.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,26 @@
2424
*/
2525
package jdk.graal.compiler.word;
2626

27-
import static org.graalvm.nativeimage.ImageInfo.inImageBuildtimeCode;
28-
2927
import jdk.graal.compiler.core.common.Fields;
3028
import jdk.graal.compiler.core.common.type.AbstractObjectStamp;
3129
import jdk.graal.compiler.core.common.type.Stamp;
3230
import jdk.graal.compiler.core.common.type.StampFactory;
31+
import jdk.graal.compiler.debug.GraalError;
3332
import jdk.graal.compiler.graph.Node;
3433
import jdk.graal.compiler.nodes.StructuredGraph;
3534
import jdk.graal.compiler.nodes.ValueNode;
3635
import jdk.graal.compiler.nodes.type.StampTool;
36+
import org.graalvm.nativeimage.ImageInfo;
3737
import org.graalvm.word.WordBase;
38-
import org.graalvm.word.WordFactory;
3938

4039
import jdk.vm.ci.meta.JavaKind;
4140
import jdk.vm.ci.meta.JavaType;
4241
import jdk.vm.ci.meta.MetaAccessProvider;
4342
import jdk.vm.ci.meta.ResolvedJavaMethod;
4443
import jdk.vm.ci.meta.ResolvedJavaType;
44+
import org.graalvm.word.impl.WordFactoryOperation;
45+
46+
import java.util.List;
4547

4648
/**
4749
* Encapsulates information for Java types representing raw words (as opposed to Objects).
@@ -62,7 +64,7 @@ public class WordTypes {
6264
/**
6365
* Resolved type for {@link WordFactory}.
6466
*/
65-
private final ResolvedJavaType wordFactoryType;
67+
private final List<ResolvedJavaType> wordFactoryTypes;
6668

6769
/**
6870
* Resolved type for {@link ObjectAccess}.
@@ -81,24 +83,29 @@ public WordTypes(MetaAccessProvider metaAccess, JavaKind wordKind) {
8183
this.wordBaseType = metaAccess.lookupJavaType(WordBase.class);
8284
this.wordBaseClass = WordBase.class;
8385
this.wordImplType = metaAccess.lookupJavaType(Word.class);
84-
this.wordFactoryType = metaAccess.lookupJavaType(WordFactory.class);
86+
this.wordFactoryTypes = List.of(
87+
metaAccess.lookupJavaType(org.graalvm.word.WordFactory.class),
88+
metaAccess.lookupJavaType(WordFactory.class));
8589
this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class);
8690
this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class);
8791

88-
if (!inImageBuildtimeCode()) {
89-
Word.ensureInitialized();
90-
}
9192
this.wordImplType.initialize();
9293
}
9394

9495
/**
9596
* Determines if a given method denotes a word operation.
9697
*/
9798
public boolean isWordOperation(ResolvedJavaMethod targetMethod) {
98-
final boolean isWordFactory = wordFactoryType.equals(targetMethod.getDeclaringClass());
99+
final boolean isWordFactory = wordFactoryTypes.contains(targetMethod.getDeclaringClass());
99100
if (isWordFactory) {
100101
return !targetMethod.isConstructor();
101102
}
103+
if (ImageInfo.inImageBuildtimeCode()) {
104+
// Can only retrieve annotations at libgraal build time
105+
GraalError.guarantee(targetMethod.getAnnotation(WordFactoryOperation.class) == null,
106+
"%s.wordFactoryTypes should include %s", WordTypes.class.getName(), targetMethod.getDeclaringClass().getName());
107+
}
108+
102109
final boolean isObjectAccess = objectAccessType.equals(targetMethod.getDeclaringClass());
103110
final boolean isBarrieredAccess = barrieredAccessType.equals(targetMethod.getDeclaringClass());
104111
if (isObjectAccess || isBarrieredAccess) {

0 commit comments

Comments
 (0)