Skip to content

Commit 2648b5d

Browse files
author
duke
committed
Backport 47c10694c66bc131c8a5e1572340415b8daaba08
1 parent 6b33c1c commit 2648b5d

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

src/java.base/share/classes/java/lang/invoke/MethodHandle.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 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
@@ -1879,8 +1879,7 @@ void updateForm(Function<LambdaForm, LambdaForm> updater) {
18791879
if (oldForm != newForm) {
18801880
assert (newForm.customized == null || newForm.customized == this);
18811881
newForm.prepare(); // as in MethodHandle.<init>
1882-
UNSAFE.putReference(this, FORM_OFFSET, newForm);
1883-
UNSAFE.fullFence();
1882+
UNSAFE.putReferenceRelease(this, FORM_OFFSET, newForm); // properly publish newForm
18841883
}
18851884
} finally {
18861885
updateInProgress = false;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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.
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+
24+
import java.lang.invoke.MethodHandles;
25+
import java.lang.invoke.VarHandle;
26+
import java.util.ArrayList;
27+
28+
/**
29+
* @test
30+
* @bug 8340812
31+
* @summary Verify that LambdaForm customization via MethodHandle::updateForm is thread safe.
32+
* @run main TestLambdaFormCustomization
33+
* @run main/othervm -Djava.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD=0 TestLambdaFormCustomization
34+
*/
35+
public class TestLambdaFormCustomization {
36+
37+
String str = "test";
38+
static final String value = "test" + 42;
39+
40+
// Trigger concurrent LambdaForm customization for VarHandle invokers
41+
void test() throws NoSuchFieldException, IllegalAccessException {
42+
VarHandle varHandle = MethodHandles.lookup().in(getClass()).findVarHandle(getClass(), "str", String.class);
43+
44+
ArrayList<Thread> threads = new ArrayList<>();
45+
for (int threadIdx = 0; threadIdx < 10; threadIdx++) {
46+
threads.add(new Thread(() -> {
47+
for (int i = 0; i < 1000; i++) {
48+
varHandle.compareAndExchange(this, value, value);
49+
varHandle.compareAndExchange(this, value, value);
50+
varHandle.compareAndExchange(this, value, value);
51+
}
52+
}));
53+
}
54+
threads.forEach(Thread::start);
55+
threads.forEach(t -> {
56+
try {
57+
t.join();
58+
} catch (Throwable e) {
59+
throw new IllegalStateException(e);
60+
}
61+
});
62+
}
63+
64+
public static void main(String[] args) throws Exception {
65+
TestLambdaFormCustomization t = new TestLambdaFormCustomization();
66+
for (int i = 0; i < 4000; ++i) {
67+
t.test();
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)