Skip to content

Commit 4eb04ff

Browse files
committed
8369835: [lworld] Intrinsify new instance-accepting array unsafe operations
Reviewed-by: chagedorn
1 parent 72539b5 commit 4eb04ff

File tree

7 files changed

+193
-0
lines changed

7 files changed

+193
-0
lines changed

src/hotspot/share/classfile/vmIntrinsics.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
428428
case vmIntrinsics::_loadFence:
429429
case vmIntrinsics::_storeFence:
430430
case vmIntrinsics::_fullFence:
431+
case vmIntrinsics::_arrayInstanceBaseOffset:
432+
case vmIntrinsics::_arrayInstanceIndexScale:
433+
case vmIntrinsics::_arrayLayout:
431434
case vmIntrinsics::_compareAndSetLong:
432435
case vmIntrinsics::_weakCompareAndSetLong:
433436
case vmIntrinsics::_weakCompareAndSetLongPlain:

src/hotspot/share/classfile/vmIntrinsics.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,13 @@ class methodHandle;
706706
do_intrinsic(_fullFence, jdk_internal_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
707707
do_name( fullFence_name, "fullFence") \
708708
do_alias( fullFence_signature, void_method_signature) \
709+
do_intrinsic(_arrayInstanceBaseOffset, jdk_internal_misc_Unsafe, arrayInstanceBaseOffset_name, arrayProperties_signature, F_RN) \
710+
do_name( arrayInstanceBaseOffset_name, "arrayInstanceBaseOffset0") \
711+
do_signature(arrayProperties_signature, "([Ljava/lang/Object;)I") \
712+
do_intrinsic(_arrayInstanceIndexScale, jdk_internal_misc_Unsafe, _arrayInstanceIndexScale_name, arrayProperties_signature, F_RN) \
713+
do_name( _arrayInstanceIndexScale_name, "arrayInstanceIndexScale0") \
714+
do_intrinsic(_arrayLayout, jdk_internal_misc_Unsafe, _arrayLayout_name, arrayProperties_signature, F_RN) \
715+
do_name( _arrayLayout_name, "arrayLayout0") \
709716
\
710717
/* Custom branch frequencies profiling support for JSR292 */ \
711718
do_class(java_lang_invoke_MethodHandleImpl, "java/lang/invoke/MethodHandleImpl") \

src/hotspot/share/opto/c2compiler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,9 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
750750
case vmIntrinsics::_storeFence:
751751
case vmIntrinsics::_storeStoreFence:
752752
case vmIntrinsics::_fullFence:
753+
case vmIntrinsics::_arrayInstanceBaseOffset:
754+
case vmIntrinsics::_arrayInstanceIndexScale:
755+
case vmIntrinsics::_arrayLayout:
753756
case vmIntrinsics::_currentCarrierThread:
754757
case vmIntrinsics::_currentThread:
755758
case vmIntrinsics::_setCurrentThread:

src/hotspot/share/opto/library_call.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,10 @@ bool LibraryCallKit::try_to_inline(int predicate) {
485485
case vmIntrinsics::_storeStoreFence:
486486
case vmIntrinsics::_fullFence: return inline_unsafe_fence(intrinsic_id());
487487

488+
case vmIntrinsics::_arrayInstanceBaseOffset: return inline_arrayInstanceBaseOffset();
489+
case vmIntrinsics::_arrayInstanceIndexScale: return inline_arrayInstanceIndexScale();
490+
case vmIntrinsics::_arrayLayout: return inline_arrayLayout();
491+
488492
case vmIntrinsics::_onSpinWait: return inline_onspinwait();
489493

490494
case vmIntrinsics::_currentCarrierThread: return inline_native_currentCarrierThread();
@@ -3293,6 +3297,78 @@ bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
32933297
}
32943298
}
32953299

3300+
// private native int arrayInstanceBaseOffset0(Object[] array);
3301+
bool LibraryCallKit::inline_arrayInstanceBaseOffset() {
3302+
Node* array = argument(1);
3303+
Node* klass_node = load_object_klass(array);
3304+
3305+
jint layout_con = Klass::_lh_neutral_value;
3306+
Node* layout_val = get_layout_helper(klass_node, layout_con);
3307+
int layout_is_con = (layout_val == nullptr);
3308+
3309+
Node* header_size = nullptr;
3310+
if (layout_is_con) {
3311+
int hsize = Klass::layout_helper_header_size(layout_con);
3312+
header_size = intcon(hsize);
3313+
} else {
3314+
Node* hss = intcon(Klass::_lh_header_size_shift);
3315+
Node* hsm = intcon(Klass::_lh_header_size_mask);
3316+
header_size = _gvn.transform(new URShiftINode(layout_val, hss));
3317+
header_size = _gvn.transform(new AndINode(header_size, hsm));
3318+
}
3319+
set_result(header_size);
3320+
return true;
3321+
}
3322+
3323+
// private native int arrayInstanceIndexScale0(Object[] array);
3324+
bool LibraryCallKit::inline_arrayInstanceIndexScale() {
3325+
Node* array = argument(1);
3326+
Node* klass_node = load_object_klass(array);
3327+
3328+
jint layout_con = Klass::_lh_neutral_value;
3329+
Node* layout_val = get_layout_helper(klass_node, layout_con);
3330+
int layout_is_con = (layout_val == nullptr);
3331+
3332+
Node* element_size = nullptr;
3333+
if (layout_is_con) {
3334+
int log_element_size = Klass::layout_helper_log2_element_size(layout_con);
3335+
int elem_size = 1 << log_element_size;
3336+
element_size = intcon(elem_size);
3337+
} else {
3338+
Node* ess = intcon(Klass::_lh_log2_element_size_shift);
3339+
Node* esm = intcon(Klass::_lh_log2_element_size_mask);
3340+
Node* log_element_size = _gvn.transform(new URShiftINode(layout_val, ess));
3341+
log_element_size = _gvn.transform(new AndINode(log_element_size, esm));
3342+
element_size = _gvn.transform(new LShiftINode(intcon(1), log_element_size));
3343+
}
3344+
set_result(element_size);
3345+
return true;
3346+
}
3347+
3348+
// private native int arrayLayout0(Object[] array);
3349+
bool LibraryCallKit::inline_arrayLayout() {
3350+
RegionNode* region = new RegionNode(2);
3351+
Node* phi = new PhiNode(region, TypeInt::POS);
3352+
3353+
Node* array = argument(1);
3354+
Node* klass_node = load_object_klass(array);
3355+
generate_refArray_guard(klass_node, region);
3356+
if (region->req() == 3) {
3357+
phi->add_req(intcon((jint)LayoutKind::REFERENCE));
3358+
}
3359+
3360+
int layout_kind_offset = in_bytes(FlatArrayKlass::layout_kind_offset());
3361+
Node* layout_kind_addr = basic_plus_adr(klass_node, klass_node, layout_kind_offset);
3362+
Node* layout_kind = make_load(nullptr, layout_kind_addr, TypeInt::POS, T_INT, MemNode::unordered);
3363+
3364+
region->init_req(1, control());
3365+
phi->init_req(1, layout_kind);
3366+
3367+
set_control(_gvn.transform(region));
3368+
set_result(_gvn.transform(phi));
3369+
return true;
3370+
}
3371+
32963372
bool LibraryCallKit::inline_onspinwait() {
32973373
insert_mem_bar(Op_OnSpinWait);
32983374
return true;

src/hotspot/share/opto/library_call.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ class LibraryCallKit : public GraphKit {
347347
typedef enum { LS_get_add, LS_get_set, LS_cmp_swap, LS_cmp_swap_weak, LS_cmp_exchange } LoadStoreKind;
348348
bool inline_unsafe_load_store(BasicType type, LoadStoreKind kind, AccessKind access_kind);
349349
bool inline_unsafe_fence(vmIntrinsics::ID id);
350+
bool inline_arrayInstanceBaseOffset();
351+
bool inline_arrayInstanceIndexScale();
352+
bool inline_arrayLayout();
350353
bool inline_onspinwait();
351354
bool inline_fp_conversions(vmIntrinsics::ID id);
352355
bool inline_fp_range_check(vmIntrinsics::ID id);

src/java.base/share/classes/jdk/internal/misc/Unsafe.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ public int arrayLayout(Object[] array) {
245245
return arrayLayout0(array);
246246
}
247247

248+
@IntrinsicCandidate
248249
private native int arrayLayout0(Object[] array);
249250

250251

@@ -4451,8 +4452,10 @@ private void putShortParts(Object o, long offset, byte i0, byte i1) {
44514452
private native void ensureClassInitialized0(Class<?> c);
44524453
private native void notifyStrictStaticAccess0(Class<?> c, long staticFieldOffset, boolean writing);
44534454
private native int arrayBaseOffset0(Class<?> arrayClass); // public version returns long to promote correct arithmetic
4455+
@IntrinsicCandidate
44544456
private native int arrayInstanceBaseOffset0(Object[] array);
44554457
private native int arrayIndexScale0(Class<?> arrayClass);
4458+
@IntrinsicCandidate
44564459
private native int arrayInstanceIndexScale0(Object[] array);
44574460
private native long getObjectSize0(Object o);
44584461
private native int getLoadAverage0(double[] loadavg, int nelems);

test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import static compiler.valhalla.inlinetypes.InlineTypes.rL;
4444

4545
import static compiler.lib.ir_framework.IRNode.LOAD_KLASS;
46+
import static compiler.valhalla.inlinetypes.InlineTypeIRNode.LOAD_OF_ANY_KLASS;
4647
import static compiler.valhalla.inlinetypes.InlineTypes.*;
4748

4849
/*
@@ -167,6 +168,7 @@ public static void main(String[] args) {
167168
InlineTypes.getFramework()
168169
.addScenarios(scenarios[Integer.parseInt(args[0])])
169170
.addFlags("-Xbootclasspath/a:.", "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
171+
"-XX:CompileCommand=inline,jdk.internal.misc.Unsafe::*",
170172
"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
171173
"--add-exports", "java.base/jdk.internal.value=ALL-UNNAMED")
172174
.addHelperClasses(MyValue1.class,
@@ -2028,4 +2030,100 @@ public boolean test88() {
20282030
public void test88_verifier() {
20292031
Asserts.assertTrue(test88(), "test88 failed");
20302032
}
2033+
2034+
private static final long BASE_OFF1 = U.arrayInstanceBaseOffset(TEST_ARRAY1);
2035+
private static final long BASE_OFF2 = U.arrayInstanceBaseOffset(TEST_ARRAY2);
2036+
private static final long BASE_OFF3 = U.arrayInstanceBaseOffset(TEST_ARRAY3);
2037+
private static final long BASE_OFF4 = U.arrayInstanceBaseOffset(TEST_ARRAY4);
2038+
private static final long BASE_OFF5 = U.arrayInstanceBaseOffset(new Object[1]);
2039+
2040+
private static final int IDX_SCALE1 = U.arrayInstanceIndexScale(TEST_ARRAY1);
2041+
private static final int IDX_SCALE2 = U.arrayInstanceIndexScale(TEST_ARRAY2);
2042+
private static final int IDX_SCALE3 = U.arrayInstanceIndexScale(TEST_ARRAY3);
2043+
private static final int IDX_SCALE4 = U.arrayInstanceIndexScale(TEST_ARRAY4);
2044+
private static final int IDX_SCALE5 = U.arrayInstanceIndexScale(new Object[1]);
2045+
2046+
private static final int LAYOUT1 = U.arrayLayout(TEST_ARRAY1);
2047+
private static final int LAYOUT2 = U.arrayLayout(TEST_ARRAY2);
2048+
private static final int LAYOUT3 = U.arrayLayout(TEST_ARRAY3);
2049+
private static final int LAYOUT4 = U.arrayLayout(TEST_ARRAY4);
2050+
private static final int LAYOUT5 = U.arrayLayout(new Object[1]);
2051+
2052+
@Test
2053+
@IR(failOn = {CALL_UNSAFE})
2054+
public long test89(Object[] array) {
2055+
return U.arrayInstanceBaseOffset(array);
2056+
}
2057+
2058+
@Run(test = "test89")
2059+
public void test89_verifier() {
2060+
Asserts.assertEquals(test89(TEST_ARRAY1), BASE_OFF1);
2061+
Asserts.assertEquals(test89(TEST_ARRAY2), BASE_OFF2);
2062+
Asserts.assertEquals(test89(TEST_ARRAY3), BASE_OFF3);
2063+
Asserts.assertEquals(test89(TEST_ARRAY4), BASE_OFF4);
2064+
Asserts.assertEquals(test89(new Object[1]), BASE_OFF5);
2065+
}
2066+
2067+
@Test
2068+
@IR(failOn = {CALL_UNSAFE, LOAD_KLASS, LOAD_OF_ANY_KLASS})
2069+
public long test90() {
2070+
return U.arrayInstanceBaseOffset(TEST_ARRAY1);
2071+
}
2072+
2073+
@Run(test = "test90")
2074+
public void test90_verifier() {
2075+
Asserts.assertEquals(test90(), BASE_OFF1);
2076+
}
2077+
2078+
@Test
2079+
@IR(failOn = {CALL_UNSAFE})
2080+
public int test91(Object[] array) {
2081+
return U.arrayInstanceIndexScale(array);
2082+
}
2083+
2084+
@Run(test = "test91")
2085+
public void test91_verifier() {
2086+
Asserts.assertEquals(test91(TEST_ARRAY1), IDX_SCALE1);
2087+
Asserts.assertEquals(test91(TEST_ARRAY2), IDX_SCALE2);
2088+
Asserts.assertEquals(test91(TEST_ARRAY3), IDX_SCALE3);
2089+
Asserts.assertEquals(test91(TEST_ARRAY4), IDX_SCALE4);
2090+
Asserts.assertEquals(test91(new Object[1]), IDX_SCALE5);
2091+
}
2092+
2093+
@Test
2094+
@IR(failOn = {CALL_UNSAFE, LOAD_KLASS, LOAD_OF_ANY_KLASS})
2095+
public int test92() {
2096+
return U.arrayInstanceIndexScale(TEST_ARRAY1);
2097+
}
2098+
2099+
@Run(test = "test92")
2100+
public void test92_verifier() {
2101+
Asserts.assertEquals(test92(), IDX_SCALE1);
2102+
}
2103+
2104+
@Test
2105+
@IR(failOn = {CALL_UNSAFE})
2106+
public int test93(Object[] array) {
2107+
return U.arrayLayout(array);
2108+
}
2109+
2110+
@Run(test = "test93")
2111+
public void test93_verifier() {
2112+
Asserts.assertEquals(test93(TEST_ARRAY1), LAYOUT1);
2113+
Asserts.assertEquals(test93(TEST_ARRAY2), LAYOUT2);
2114+
Asserts.assertEquals(test93(TEST_ARRAY3), LAYOUT3);
2115+
Asserts.assertEquals(test93(TEST_ARRAY4), LAYOUT4);
2116+
Asserts.assertEquals(test93(new Object[1]), LAYOUT5);
2117+
}
2118+
2119+
@Test
2120+
@IR(failOn = {CALL_UNSAFE, LOAD_KLASS, LOAD_OF_ANY_KLASS})
2121+
public int test94() {
2122+
return U.arrayLayout(TEST_ARRAY1);
2123+
}
2124+
2125+
@Run(test = "test94")
2126+
public void test94_verifier() {
2127+
Asserts.assertEquals(test94(), LAYOUT1);
2128+
}
20312129
}

0 commit comments

Comments
 (0)