Skip to content

Commit 464ded3

Browse files
committed
[GR-46732] Revive UnsafeFieldAccessorFactory for Native Image
PullRequest: graal/14865
2 parents 0821256 + 2aeb5be commit 464ded3

File tree

43 files changed

+6240
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+6240
-8
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
import java.util.Optional;
7373
import java.util.StringJoiner;
7474

75+
import com.oracle.svm.core.reflect.fieldaccessor.UnsafeFieldAccessorFactory;
76+
import jdk.internal.access.JavaLangReflectAccess;
77+
import jdk.internal.reflect.FieldAccessor;
7578
import org.graalvm.compiler.core.common.NumUtil;
7679
import org.graalvm.compiler.core.common.SuppressFBWarnings;
7780
import org.graalvm.nativeimage.AnnotationAccess;
@@ -1881,6 +1884,9 @@ final class Target_jdk_internal_reflect_ReflectionFactory {
18811884
@Alias //
18821885
private static ReflectionFactory soleInstance;
18831886

1887+
@Alias //
1888+
private JavaLangReflectAccess langReflectAccess;
1889+
18841890
/**
18851891
* This substitution eliminates the SecurityManager check in the original method, which would
18861892
* make some build-time verifications fail.
@@ -1890,15 +1896,20 @@ public static ReflectionFactory getReflectionFactory() {
18901896
return soleInstance;
18911897
}
18921898

1893-
/**
1894-
* Do not use the field handle based field accessor but the one based on unsafe. It takes effect
1895-
* when {@code Target_java_lang_reflect_Field#fieldAccessorField#fieldAccessor} is recomputed at
1896-
* runtime. See also GR-39586.
1897-
*/
1898-
@TargetElement(onlyWith = JDK19OrLater.class)
18991899
@Substitute
1900-
static boolean useFieldHandleAccessor() {
1901-
return false;
1900+
public FieldAccessor newFieldAccessor(Field field0, boolean override) {
1901+
Field field = field0;
1902+
Field root = langReflectAccess.getRoot(field);
1903+
if (root != null) {
1904+
// FieldAccessor will use the root unless the modifiers have
1905+
// been overridden
1906+
if (root.getModifiers() == field.getModifiers() || !override) {
1907+
field = root;
1908+
}
1909+
}
1910+
boolean isFinal = Modifier.isFinal(field.getModifiers());
1911+
boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
1912+
return UnsafeFieldAccessorFactory.newFieldAccessor(field, isReadOnly);
19021913
}
19031914
}
19041915

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright (c) 2001, 2005, 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+
26+
package com.oracle.svm.core.reflect.fieldaccessor;
27+
28+
import java.lang.reflect.Field;
29+
30+
class UnsafeBooleanFieldAccessorImpl extends UnsafeFieldAccessorImpl {
31+
UnsafeBooleanFieldAccessorImpl(Field field) {
32+
super(field);
33+
}
34+
35+
@Override
36+
public Object get(Object obj) throws IllegalArgumentException {
37+
return Boolean.valueOf(getBoolean(obj));
38+
}
39+
40+
@Override
41+
public boolean getBoolean(Object obj) throws IllegalArgumentException {
42+
ensureObj(obj);
43+
return unsafe.getBoolean(obj, fieldOffset);
44+
}
45+
46+
@Override
47+
public byte getByte(Object obj) throws IllegalArgumentException {
48+
throw newGetByteIllegalArgumentException();
49+
}
50+
51+
@Override
52+
public char getChar(Object obj) throws IllegalArgumentException {
53+
throw newGetCharIllegalArgumentException();
54+
}
55+
56+
@Override
57+
public short getShort(Object obj) throws IllegalArgumentException {
58+
throw newGetShortIllegalArgumentException();
59+
}
60+
61+
@Override
62+
public int getInt(Object obj) throws IllegalArgumentException {
63+
throw newGetIntIllegalArgumentException();
64+
}
65+
66+
@Override
67+
public long getLong(Object obj) throws IllegalArgumentException {
68+
throw newGetLongIllegalArgumentException();
69+
}
70+
71+
@Override
72+
public float getFloat(Object obj) throws IllegalArgumentException {
73+
throw newGetFloatIllegalArgumentException();
74+
}
75+
76+
@Override
77+
public double getDouble(Object obj) throws IllegalArgumentException {
78+
throw newGetDoubleIllegalArgumentException();
79+
}
80+
81+
@Override
82+
public void set(Object obj, Object value)
83+
throws IllegalArgumentException, IllegalAccessException {
84+
ensureObj(obj);
85+
if (isFinal) {
86+
throwFinalFieldIllegalAccessException(value);
87+
}
88+
if (value == null) {
89+
throwSetIllegalArgumentException(value);
90+
}
91+
if (value instanceof Boolean) {
92+
unsafe.putBoolean(obj, fieldOffset, ((Boolean) value).booleanValue());
93+
return;
94+
}
95+
throwSetIllegalArgumentException(value);
96+
}
97+
98+
@Override
99+
public void setBoolean(Object obj, boolean z)
100+
throws IllegalArgumentException, IllegalAccessException {
101+
ensureObj(obj);
102+
if (isFinal) {
103+
throwFinalFieldIllegalAccessException(z);
104+
}
105+
unsafe.putBoolean(obj, fieldOffset, z);
106+
}
107+
108+
@Override
109+
public void setByte(Object obj, byte b)
110+
throws IllegalArgumentException, IllegalAccessException {
111+
throwSetIllegalArgumentException(b);
112+
}
113+
114+
@Override
115+
public void setChar(Object obj, char c)
116+
throws IllegalArgumentException, IllegalAccessException {
117+
throwSetIllegalArgumentException(c);
118+
}
119+
120+
@Override
121+
public void setShort(Object obj, short s)
122+
throws IllegalArgumentException, IllegalAccessException {
123+
throwSetIllegalArgumentException(s);
124+
}
125+
126+
@Override
127+
public void setInt(Object obj, int i)
128+
throws IllegalArgumentException, IllegalAccessException {
129+
throwSetIllegalArgumentException(i);
130+
}
131+
132+
@Override
133+
public void setLong(Object obj, long l)
134+
throws IllegalArgumentException, IllegalAccessException {
135+
throwSetIllegalArgumentException(l);
136+
}
137+
138+
@Override
139+
public void setFloat(Object obj, float f)
140+
throws IllegalArgumentException, IllegalAccessException {
141+
throwSetIllegalArgumentException(f);
142+
}
143+
144+
@Override
145+
public void setDouble(Object obj, double d)
146+
throws IllegalArgumentException, IllegalAccessException {
147+
throwSetIllegalArgumentException(d);
148+
}
149+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright (c) 2001, 2005, 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+
26+
package com.oracle.svm.core.reflect.fieldaccessor;
27+
28+
import java.lang.reflect.Field;
29+
30+
class UnsafeByteFieldAccessorImpl extends UnsafeFieldAccessorImpl {
31+
UnsafeByteFieldAccessorImpl(Field field) {
32+
super(field);
33+
}
34+
35+
@Override
36+
public Object get(Object obj) throws IllegalArgumentException {
37+
return Byte.valueOf(getByte(obj));
38+
}
39+
40+
@Override
41+
public boolean getBoolean(Object obj) throws IllegalArgumentException {
42+
throw newGetBooleanIllegalArgumentException();
43+
}
44+
45+
@Override
46+
public byte getByte(Object obj) throws IllegalArgumentException {
47+
ensureObj(obj);
48+
return unsafe.getByte(obj, fieldOffset);
49+
}
50+
51+
@Override
52+
public char getChar(Object obj) throws IllegalArgumentException {
53+
throw newGetCharIllegalArgumentException();
54+
}
55+
56+
@Override
57+
public short getShort(Object obj) throws IllegalArgumentException {
58+
return getByte(obj);
59+
}
60+
61+
@Override
62+
public int getInt(Object obj) throws IllegalArgumentException {
63+
return getByte(obj);
64+
}
65+
66+
@Override
67+
public long getLong(Object obj) throws IllegalArgumentException {
68+
return getByte(obj);
69+
}
70+
71+
@Override
72+
public float getFloat(Object obj) throws IllegalArgumentException {
73+
return getByte(obj);
74+
}
75+
76+
@Override
77+
public double getDouble(Object obj) throws IllegalArgumentException {
78+
return getByte(obj);
79+
}
80+
81+
@Override
82+
public void set(Object obj, Object value)
83+
throws IllegalArgumentException, IllegalAccessException {
84+
ensureObj(obj);
85+
if (isFinal) {
86+
throwFinalFieldIllegalAccessException(value);
87+
}
88+
if (value == null) {
89+
throwSetIllegalArgumentException(value);
90+
}
91+
if (value instanceof Byte) {
92+
unsafe.putByte(obj, fieldOffset, ((Byte) value).byteValue());
93+
return;
94+
}
95+
throwSetIllegalArgumentException(value);
96+
}
97+
98+
@Override
99+
public void setBoolean(Object obj, boolean z)
100+
throws IllegalArgumentException, IllegalAccessException {
101+
throwSetIllegalArgumentException(z);
102+
}
103+
104+
@Override
105+
public void setByte(Object obj, byte b)
106+
throws IllegalArgumentException, IllegalAccessException {
107+
ensureObj(obj);
108+
if (isFinal) {
109+
throwFinalFieldIllegalAccessException(b);
110+
}
111+
unsafe.putByte(obj, fieldOffset, b);
112+
}
113+
114+
@Override
115+
public void setChar(Object obj, char c)
116+
throws IllegalArgumentException, IllegalAccessException {
117+
throwSetIllegalArgumentException(c);
118+
}
119+
120+
@Override
121+
public void setShort(Object obj, short s)
122+
throws IllegalArgumentException, IllegalAccessException {
123+
throwSetIllegalArgumentException(s);
124+
}
125+
126+
@Override
127+
public void setInt(Object obj, int i)
128+
throws IllegalArgumentException, IllegalAccessException {
129+
throwSetIllegalArgumentException(i);
130+
}
131+
132+
@Override
133+
public void setLong(Object obj, long l)
134+
throws IllegalArgumentException, IllegalAccessException {
135+
throwSetIllegalArgumentException(l);
136+
}
137+
138+
@Override
139+
public void setFloat(Object obj, float f)
140+
throws IllegalArgumentException, IllegalAccessException {
141+
throwSetIllegalArgumentException(f);
142+
}
143+
144+
@Override
145+
public void setDouble(Object obj, double d)
146+
throws IllegalArgumentException, IllegalAccessException {
147+
throwSetIllegalArgumentException(d);
148+
}
149+
}

0 commit comments

Comments
 (0)