Compare commits

...

33 Commits
1460 ... 1536

Author SHA1 Message Date
Mikhail Grishchenko
a2a2572f78 updated JTreg exclude list
exclude some tests from security/infra/java/security/cert/CertPathValidator
JBR-3500 exclude sun/java2d/ClassCastExceptionForInvalidSurface.java for linux-all
2021-06-25 19:22:14 +07:00
Maxim Kartashev
7b992c7cd7 JBR-3568 Backport JDK-8261812 to JBR11 2021-06-25 11:15:01 +03:00
Anton Tarasov
8678f41971 JBR-3337 jb/java/jcef/HandleJSQueryTest3314.sh: fails on macOS-aarch64 with "JS Query was not handled in 2nd opened browser" 2021-06-23 18:03:55 +03:00
Denis Konoplev
752c0e5a49 JBR-3544: Generate popup invoked instead of New in this directory
Fix logical error
2021-06-23 12:00:03 +03:00
Denis Konoplev
3ea7913eaf JBR-3544: Generate popup invoked instead of New in this directory
CR: change duplicate Ctrl to Cmd
2021-06-21 22:31:04 +03:00
Anton Tarasov
9b4f72ad18 JBR-3545 Window.setMinimumSize does not respect DPI scaling 2021-06-21 20:42:49 +03:00
Denis Konoplev
d5fa37b63f JBR-3544: Generate popup invoked instead of New in this directory
Fix duplicate system shortcut
2021-06-21 18:26:25 +03:00
Denis Fokin
6a42bb54bd JRE-408 JBR-3515 fix NullPointerException in MetalRootPaneUI.installWindowListeners
(cherry picked from commit 584d554af529cff445b0f09bc2d57be55e138b7a)
2021-06-18 07:18:59 +07:00
Alexey Ushakov
3b03c698ce JBR-2207 TitledBorder leaks PropertyChangeListener
Added a separate pass with sending setVisible(false) to the frames holding TitledBorder references in order to get WINDOW_DEACTIVATED (to clear KeyBoardFocusManager.activeWindow field)
2021-06-16 16:00:55 +03:00
Vitaly Provodin
a56060d465 exclude the test failing because of JDK-8268678 2021-06-15 05:30:09 +07:00
Maxim Kartashev
97ddad2e99 JBR-3516 IDEA doesn't start when located in folder with cyrillic characters
Fix failing Windows x86 builds.
Fixes commit cad1ad4ba1
2021-06-11 11:40:28 +03:00
Maxim Kartashev
01ea54d751 JBR-3520 Correct stack-use-after-scope in jni_NewObjectA
Casting a variable to a non-reference type technically makes the
resulting expression a prvalue, which then gets bound to a reference
that is alive up until the end of the function. The prvalue is then
touched in the destructor of DTraceReturnProbeMark_NewObjectA and this
is detected by Address Sanitizer as stack-use-after-scope.

The fix is to cast to a reference type thus avoiding the creation of the
prvalue and lifetime issues connected with that.
2021-06-09 11:48:37 +03:00
Maxim Kartashev
cad1ad4ba1 JBR-3516 IDEA doesn't start when located in folder with cyrillic characters
Make JVM_LoadLibrary() use new os::dll_load_utf8() interface that
supports UTF-8 path names, leaving other users of os::dll_load()
unaffected.
2021-06-08 12:21:53 +03:00
Alexey Ushakov
c0be778e20 JBR-3344 "Exit Full Screen" action doesn't work, the only way is mouse click on window's native "green" button.
Restored JBR-1931 fix partially reverted by JBR-1718
2021-06-07 20:54:10 +03:00
Vitaly Provodin
0b659fef1b JBR-3500 exclude ClassCastExceptionForInvalidSurface test only causing Xwayland crash 2021-06-01 04:44:33 +07:00
Vitaly Provodin
e62fb2762f JBR-3500 exclude ClassCastExceptionForInvalidSurface test only causing Xwayland crash 2021-06-01 04:43:20 +07:00
Vitaly Provodin
90fff7bb1e JBR-3500 exclude tests related to JBR-3167 causing Xwayland crash 2021-06-01 04:40:40 +07:00
Nikita Gubarkov
f117b0e8ff JBR-3376 Added check for -1 glyph info pointer in OGLTextRenderer.c 2021-05-24 23:41:25 +03:00
Maxim Kartashev
5a2da540da JBR-2755 IDE UI became slow via remote X Server connection from Windows
When XGetImage() calls become slow in a remote X11 session, fake
XGetImage() with client-side XCreateImage() that is filled with some
background color. The color is chosen from several top left corner
pixels of the "slow" images obtained with XGetImage().

This feature activates in a remote X11 session only and is
controlled with -Dremote.x11.workaround={true|false|auto}.
2021-05-21 17:10:04 +03:00
Denis Konoplev
23a7dbd486 EA-252361: Check window for null 2021-05-20 14:14:38 +03:00
Maxim Kartashev
104ef7a512 JBR-3448 Crash when using -Dsun.java2d.trace=count 2021-05-19 15:39:45 +03:00
Artem Semenov
55c667055e JBR-3469: SIGILL at [libsystem_kernel] __kill in -[AWTView accessibleSelectedText]: unrecognized selector sent to instance 2021-05-19 13:43:25 +03:00
Artem Semenov
bc024f9af1 JBR-3437: Refactoring the a11y code 2021-05-18 18:51:34 +03:00
Vitaly Provodin
dbcbc5cf36 exclude tests related to 8233568 and 8258945 2021-05-18 04:44:17 +07:00
Vitaly Provodin
19aa9c5ab2 JBR-3459 Fix race condition in ClassLoaderDataGraph::classes_do
InstanceKlass in ClassLoaderData can be uninitialized when
ClassLoaderDataGraph::classes_do is called. Using
ClassLoaderDataGraph::dictionary_classes_do is safe but problem is still
persisting with anonymous classes.
2021-05-17 07:21:59 +07:00
Vitaly Provodin
4038661a40 JBR-3458 Skip dynamic proxy classes based on com.sun.proxy 2021-05-17 07:21:58 +07:00
Vitaly Provodin
f3f243e15e Support for redefinition of Well Known classses (java.*,jdk.*, sun.*) 2021-05-17 07:21:58 +07:00
Vitaly Provodin
967eca8d1d JBR-3140 - support for modularized HotswapAgent
Add -XX:HotswapAgent=[disabled,fatjar.core]
2021-05-17 07:21:58 +07:00
Vitaly Provodin
c011487364 JBR-3111 Update class in all dictionaries where it was already defined
This patch keeps compatibility with std redefinition, that does not
create a new Klass, but modifies it, then it is modified in all
dictionaries containing this class.
2021-05-17 07:21:57 +07:00
Vitaly Provodin
e90312b97a DCEVM Code cleanup
- Rename confusing method name old_if_redefined to old_if_redefining
- Remove unused is_redefining_gc_run
2021-05-17 07:21:57 +07:00
Vitaly Provodin
3cc4c7947b JBR-3110 Fix assert in MetadataOnStackMark
Fixed fastdebug tests crashes in redefine gc run
2021-05-17 07:21:57 +07:00
Vitaly Provodin
92948257a6 JBR-3106 Check InstanceKlass::has_nestmate_access_to with active classes 2021-05-17 07:21:56 +07:00
Nikita Gubarkov
fcd5fd2fe9 JBR-2924 Added test for SFNS italic font inclination on MacOS 2021-05-16 00:35:45 +03:00
90 changed files with 2598 additions and 1107 deletions

View File

@@ -1,7 +1,7 @@
From d75ca6d0d1799ffde4199f6ef5047699b98d3ff2 Mon Sep 17 00:00:00 2001
From 07373a8bd65d7c2663024709f0d5b7e0e41aba40 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:09:39 +0100
Subject: [PATCH 01/18] Apply basic dcevm11 patch
Subject: [PATCH 01/28] Apply basic dcevm11 patch
---
src/hotspot/share/ci/ciObjectFactory.cpp | 25 +
@@ -449,10 +449,10 @@ index d26f1f11fb4..fd4b134d7a7 100644
// An entry in the class loader data dictionaries, this describes a class as
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index fc4efecc6e7..903979c9ef2 100644
index e4f1b934afc..ef4011c1292 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -2446,6 +2446,8 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHand
@@ -2428,6 +2428,8 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHand
skip_throwableInit_check = true;
}
}
@@ -461,7 +461,7 @@ index fc4efecc6e7..903979c9ef2 100644
if (method->is_hidden()) {
if (skip_hidden) continue;
}
@@ -3628,6 +3630,62 @@ void java_lang_invoke_DirectMethodHandle::serialize_offsets(SerializeClosure* f)
@@ -3610,6 +3612,62 @@ void java_lang_invoke_DirectMethodHandle::serialize_offsets(SerializeClosure* f)
}
#endif
@@ -524,7 +524,7 @@ index fc4efecc6e7..903979c9ef2 100644
// Support for java_lang_invoke_MethodHandle
int java_lang_invoke_MethodHandle::_type_offset;
@@ -3814,6 +3872,11 @@ void java_lang_invoke_ResolvedMethodName::set_vmtarget(oop resolved_method, Meth
@@ -3796,6 +3854,11 @@ void java_lang_invoke_ResolvedMethodName::set_vmtarget(oop resolved_method, Meth
resolved_method->address_field_put(_vmtarget_offset, (address)m);
}
@@ -537,7 +537,7 @@ index fc4efecc6e7..903979c9ef2 100644
// lookup ResolvedMethod oop in the table, or create a new one and intern it
oop resolved_method = ResolvedMethodTable::find_method(m());
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index bd9cdca3fe3..da004d1b307 100644
index 910bb084b63..89a46264553 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -67,6 +67,8 @@
@@ -561,7 +561,7 @@ index bd9cdca3fe3..da004d1b307 100644
static void allocate_fixup_lists();
static void compute_offsets();
@@ -1055,6 +1057,55 @@ class java_lang_invoke_DirectMethodHandle: AllStatic {
@@ -1048,6 +1050,55 @@ class java_lang_invoke_DirectMethodHandle: AllStatic {
static int member_offset_in_bytes() { return _member_offset; }
};
@@ -617,7 +617,7 @@ index bd9cdca3fe3..da004d1b307 100644
// Interface to java.lang.invoke.LambdaForm objects
// (These are a private interface for managing adapter code generation.)
@@ -1106,6 +1157,7 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
@@ -1099,6 +1150,7 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
static Method* vmtarget(oop resolved_method);
static void set_vmtarget(oop resolved_method, Method* method);
@@ -977,7 +977,7 @@ index 05239c57866..c1357bde0ed 100644
methodHandle _method; // current method being verified
VerificationType _this_type; // the verification type of the current class
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index 44cf2583eb9..41e9a84cd69 100644
index 8955dd0b366..26ff6ee9853 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -286,6 +286,8 @@
@@ -1684,10 +1684,10 @@ index 81998728f66..b9ccdee8cca 100644
}
}
diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
index 77c28924b0d..84891b48c2a 100644
index 6cf7aec68f8..61a406377ee 100644
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
@@ -1467,6 +1467,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
@@ -1471,6 +1471,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
NULL, // host klass
NULL, // cp_patches
ClassFileParser::INTERNAL, // internal visibility
@@ -2260,7 +2260,7 @@ index 21e7f652652..e9cc3de9652 100644
if (log_is_enabled(Debug, class, resolve) && k != NULL) {
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 378dcce8cf5..f92d2697e0e 100644
index 0d686d85fc7..70b525533cd 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -936,6 +936,7 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name,
@@ -2273,7 +2273,7 @@ index 378dcce8cf5..f92d2697e0e 100644
if (log_is_enabled(Debug, class, resolve) && k != NULL) {
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
new file mode 100644
index 00000000000..80c31135487
index 00000000000..83c0952de37
--- /dev/null
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -0,0 +1,2255 @@
@@ -4534,7 +4534,7 @@ index 00000000000..80c31135487
+}
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
new file mode 100644
index 00000000000..3f95cf42645
index 00000000000..b712d69a193
--- /dev/null
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -0,0 +1,202 @@
@@ -4819,7 +4819,7 @@ index 6600848e2d3..9337b6ab585 100644
if (_code_blobs != NULL) {
for (int i=0; i<_code_blobs->length(); i++) {
diff --git a/src/hotspot/share/prims/jvmtiExport.hpp b/src/hotspot/share/prims/jvmtiExport.hpp
index cc5868f1e93..a6cbac03bb2 100644
index b8246554f74..be2c373aba7 100644
--- a/src/hotspot/share/prims/jvmtiExport.hpp
+++ b/src/hotspot/share/prims/jvmtiExport.hpp
@@ -176,6 +176,7 @@ class JvmtiExport : public AllStatic {

View File

@@ -1,7 +1,7 @@
From ebd5c9df33771ad5181a225cccc0cca3881a4dbe Mon Sep 17 00:00:00 2001
From 41093b9513718c3122f3ff36da7fc2eeca224a10 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:18:22 +0100
Subject: [PATCH 02/18] dcevm11 fixes
Subject: [PATCH 02/28] dcevm11 fixes
1. We need to set classRedefinitionCount on new class, not old class.
@@ -463,7 +463,7 @@ index 2cc98b636f1..e8107a39813 100644
// link this class into the implementors list of every interface it implements
void process_interfaces(Thread *thread);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 80c31135487..43d761cdbb2 100644
index 83c0952de37..92ce6c27b8a 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1,4 +1,4 @@
@@ -1394,7 +1394,7 @@ index 80c31135487..43d761cdbb2 100644
ResourceMark mark(THREAD);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 3f95cf42645..a48e07e3a6a 100644
index b712d69a193..60b62c3170a 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -16,6 +16,8 @@

View File

@@ -1,7 +1,7 @@
From aaefe6f66a8d363eb35fcdc8ce29bb25be67fe1c Mon Sep 17 00:00:00 2001
From caa877d9126bd91d6719675a83928ba01bffb69a Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 12 Dec 2018 19:38:28 +0100
Subject: [PATCH 03/18] Support for Concurrent Mark Sweep (CMS) collector
Subject: [PATCH 03/28] Support for Concurrent Mark Sweep (CMS) collector
---
.../share/gc/cms/compactibleFreeListSpace.cpp | 139 ++++++++++++------
@@ -422,7 +422,7 @@ index 6b109fcd2e5..8c255d6d428 100644
Klass* new_version = oop(cur_obj)->klass()->new_version();
if (new_version->update_information() == NULL) {
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 43d761cdbb2..14af1aad21b 100644
index 92ce6c27b8a..41e82ae7a69 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -54,6 +54,7 @@

View File

@@ -1,7 +1,7 @@
From 002ad1880190d0749f8f8d325c587fd9275bdab2 Mon Sep 17 00:00:00 2001
From 93373779a1d44181ca07498faa8a0e8d7fc6b608 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@mailprofiler.com>
Date: Wed, 11 Mar 2020 14:19:34 +0100
Subject: [PATCH 04/18] Fix class cast exception on redefinition of class A,
Subject: [PATCH 04/28] Fix class cast exception on redefinition of class A,
that is superclass of B that has anonymous class C
---

View File

@@ -1,7 +1,7 @@
From a00292280f4e3754bffc7a0c562dca1d7552eb39 Mon Sep 17 00:00:00 2001
From c8850725d4c84f93beaee3c05f9d8f9862fe6159 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:20:08 +0100
Subject: [PATCH 05/18] HotswapAgent integration
Date: Thu, 15 Nov 2018 03:20:08 +0700
Subject: [PATCH 05/28] HotswapAgent integration
It include:
@@ -37,7 +37,7 @@ old DCEVM
make/launcher/Launcher-jdk.jartool.gmk | 2 +
make/launcher/Launcher-jdk.javadoc.gmk | 3 +-
make/launcher/Launcher-jdk.jcmd.gmk | 13 +++-
make/launcher/Launcher-jdk.jconsole.gmk | 3 +-
make/launcher/Launcher-jdk.jconsole.gmk | 1 +
make/launcher/Launcher-jdk.jdeps.gmk | 3 +
make/launcher/Launcher-jdk.jdi.gmk | 1 +
make/launcher/Launcher-jdk.jlink.gmk | 5 +-
@@ -55,7 +55,7 @@ old DCEVM
.../classes/com/sun/beans/package-info.java | 26 +++++++
.../com/sun/beans/util/package-info.java | 26 +++++++
.../share/classes/module-info.java | 3 +
28 files changed, 209 insertions(+), 11 deletions(-)
28 files changed, 208 insertions(+), 10 deletions(-)
create mode 100644 src/java.desktop/share/classes/com/sun/beans/introspect/package-info.java
create mode 100644 src/java.desktop/share/classes/com/sun/beans/package-info.java
create mode 100644 src/java.desktop/share/classes/com/sun/beans/util/package-info.java
@@ -259,16 +259,14 @@ index 7117fa78059..761a52d8466 100644
# Hook to include the corresponding custom file, if present.
diff --git a/make/launcher/Launcher-jdk.jconsole.gmk b/make/launcher/Launcher-jdk.jconsole.gmk
index 575b9e0595b..9b38683a489 100644
index 575b9e0595b..2f442f69113 100644
--- a/make/launcher/Launcher-jdk.jconsole.gmk
+++ b/make/launcher/Launcher-jdk.jconsole.gmk
@@ -29,7 +29,8 @@ $(eval $(call SetupBuildLauncher, jconsole, \
MAIN_CLASS := sun.tools.jconsole.JConsole, \
@@ -30,6 +30,7 @@ $(eval $(call SetupBuildLauncher, jconsole, \
JAVA_ARGS := --add-opens java.base/java.io=jdk.jconsole \
-Djconsole.showOutputViewer \
- -Djdk.attach.allowAttachSelf=true, \
+ -Djdk.attach.allowAttachSelf=true \
+ -XX:+DisableHotswapAgent, \
-Djdk.attach.allowAttachSelf=true, \
+ -XX:+DisableHotswapAgent, \
CFLAGS_windows := -DJAVAW, \
LIBS_windows := user32.lib, \
))
@@ -392,7 +390,7 @@ index 82311e69fd6..bd39f8595b2 100644
CFLAGS := -DENABLE_ARG_FILES, \
))
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index 41e9a84cd69..1f67eb202b5 100644
index 26ff6ee9853..2409af9b06e 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -342,6 +342,7 @@

View File

@@ -1,7 +1,7 @@
From 62f3578e0a73913c1262a1612a464d19abfeb626 Mon Sep 17 00:00:00 2001
From 1552e3854e11fb835452aa531ef53b78bb4588a5 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 4 Oct 2020 21:12:12 +0200
Subject: [PATCH 06/18] Support for Lambda class redefinition
Subject: [PATCH 06/28] Support for Lambda class redefinition
---
.../share/classfile/classLoaderData.cpp | 9 +++
@@ -111,7 +111,7 @@ index 06f6c869d63..1dbbffa197f 100644
TRAPS);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 14af1aad21b..0b239b2ff6d 100644
index 41e82ae7a69..b94caa39562 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -488,6 +488,8 @@ void VM_EnhancedRedefineClasses::doit() {
@@ -208,7 +208,7 @@ index 14af1aad21b..0b239b2ff6d 100644
// Sort the affected klasses such that a supertype is always on a smaller array index than its subtype.
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index a48e07e3a6a..3551b06ecde 100644
index 60b62c3170a..d8a11b51fe9 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -116,6 +116,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
@@ -242,7 +242,7 @@ index af2ec48c2e1..7741328979f 100644
assert(newer_method != NULL, "method_with_idnum() should not be NULL");
assert(old_method != newer_method, "sanity check");
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
index c071f8b7cc6..e484b8991d1 100644
index 1983b4f45f0..5e7aca092eb 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -820,6 +820,7 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,

View File

@@ -1,7 +1,7 @@
From 4b445e7a7f77f82f757c12010e3c88b2eb4698f9 Mon Sep 17 00:00:00 2001
From 83c2efaeb6ea9ee29c6d9eb779991db787c036ac Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 23 May 2020 10:02:15 +0200
Subject: [PATCH 07/18] Fix "no original bytecode found" error if method with
Subject: [PATCH 07/28] Fix "no original bytecode found" error if method with
bkp is missing
Sometimes IDE can deploy class with erroneous method, such method has
@@ -102,7 +102,7 @@ index 4533476ff8f..193e1845b23 100644
void set_breakpoint(int bci);
void clear_breakpoint(int bci);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 0b239b2ff6d..aba99bb60fa 100644
index b94caa39562..1fbba406087 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1356,14 +1356,16 @@ void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {

View File

@@ -1,7 +1,7 @@
From c022124c6e0680d2dfc174f66fc858b0eb2591dc Mon Sep 17 00:00:00 2001
From f9e238b9bf2cc3ae0c437fa3ebb1703c35f575cf Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 24 May 2020 12:07:42 +0200
Subject: [PATCH 08/18] Replace deleted method with
Subject: [PATCH 08/28] Replace deleted method with
Universe::throw_no_such_method_error
---

View File

@@ -1,7 +1,7 @@
From aa1d291c7349e5cecf9d93e817d0866460deb903 Mon Sep 17 00:00:00 2001
From a579caf20ac76a5d7cc159d5fed2efa074380f0f Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 12 Jun 2020 17:43:52 +0200
Subject: [PATCH 09/18] Support for G1 gc
Subject: [PATCH 09/28] Support for G1 gc
---
src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 20 +++
@@ -31,10 +31,10 @@ Subject: [PATCH 09/18] Support for G1 gc
create mode 100644 src/hotspot/share/gc/shared/dcevmSharedGC.hpp
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index dea8d9fdb0e..33664a30519 100644
index a15b400c8e4..985fbad581b 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -2108,6 +2108,21 @@ public:
@@ -2111,6 +2111,21 @@ public:
}
};
@@ -56,7 +56,7 @@ index dea8d9fdb0e..33664a30519 100644
void G1CollectedHeap::object_iterate(ObjectClosure* cl) {
IterateObjectClosureRegionClosure blk(cl);
heap_region_iterate(&blk);
@@ -2117,6 +2132,11 @@ void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
@@ -2124,6 +2139,11 @@ void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
_hrm.iterate(cl);
}
@@ -69,7 +69,7 @@ index dea8d9fdb0e..33664a30519 100644
HeapRegionClaimer *hrclaimer,
uint worker_id) const {
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
index 8a171dc6b52..05a068bb2e0 100644
index be160d04bfe..9e92ee4a1fa 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -144,6 +144,7 @@ class G1CollectedHeap : public CollectedHeap {
@@ -1040,7 +1040,7 @@ index d0a6d665aa0..3dc4cc1323c 100644
SystemDictionary::oops_do(oopClosure);
}
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index aba99bb60fa..8b6fad2128e 100644
index 1fbba406087..e67fc2dd58f 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -36,7 +36,6 @@
@@ -1244,7 +1244,7 @@ index aba99bb60fa..8b6fad2128e 100644
ResourceMark mark(THREAD);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 3551b06ecde..62a0fbf54d4 100644
index d8a11b51fe9..9755944d70b 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -86,9 +86,10 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {

View File

@@ -1,7 +1,7 @@
From b6ea0ee6fcc376f575be0f461c494664d55ed986 Mon Sep 17 00:00:00 2001
From 8d14e792d9849beedc74de690cf4d208ac384878 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 13 Jun 2020 18:50:59 +0200
Subject: [PATCH 10/18] Change log level in advanced redefinition
Subject: [PATCH 10/28] Change log level in advanced redefinition
- Change log level for "Comparing different class ver.." to debug
- Fix adjust_method_entries_dcevm logging levels and severity
@@ -11,7 +11,7 @@ Subject: [PATCH 10/18] Change log level in advanced redefinition
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 8b6fad2128e..a8adfa5af47 100644
index e67fc2dd58f..5be9bb74305 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -915,7 +915,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {

View File

@@ -1,7 +1,7 @@
From ef1098751c596a03fd1721affc20d221b3544d37 Mon Sep 17 00:00:00 2001
From 5c437ade174426dbaf99a53823597ac7d3b1b4da Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 6 Oct 2020 22:15:31 +0200
Subject: [PATCH 11/18] AllowEnhancedClassRedefinition is false (disabled) by
Subject: [PATCH 11/28] AllowEnhancedClassRedefinition is false (disabled) by
default
---

View File

@@ -1,7 +1,7 @@
From 6a78dda15c66cbba1ca6a2d7f3df3a55fc087f50 Mon Sep 17 00:00:00 2001
From 8b1c8178e66af30012fdda3e7f1076309daaf6c4 Mon Sep 17 00:00:00 2001
From: Artem Khvastunov <artem.khvastunov@jetbrains.com>
Date: Tue, 14 Apr 2020 19:11:35 +0200
Subject: [PATCH 12/18] add jvmtiEnhancedRedefineClasses.* to CMakeLists.txt
Subject: [PATCH 12/28] add jvmtiEnhancedRedefineClasses.* to CMakeLists.txt
---
jb/project/hotspot-cmake/CMakeLists.txt | 2 ++

View File

@@ -1,14 +1,14 @@
From 80c1cd01b45735928e3b3e9283b5484ea6a70a7f Mon Sep 17 00:00:00 2001
From 5e7a1218684556596677f39ae01b2ec13ff68a19 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Mon, 19 Oct 2020 20:00:04 +0200
Subject: [PATCH 13/18] Set HOTSPOT_VM_DISTRO=Dynamic Code Evolution
Subject: [PATCH 13/28] Set HOTSPOT_VM_DISTRO=Dynamic Code Evolution
---
make/autoconf/version-numbers | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers
index 1d08f6a80dc..88b4d460ee8 100644
index b9440902d34..c487ac6f047 100644
--- a/make/autoconf/version-numbers
+++ b/make/autoconf/version-numbers
@@ -44,7 +44,7 @@ PRODUCT_NAME=OpenJDK

View File

@@ -1,7 +1,7 @@
From 122562d31005edd3573a645c3a02c1d8fe843c5e Mon Sep 17 00:00:00 2001
From c2a4abf7d01ecd7bd262e824338d6235a584086b Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 11 Oct 2020 10:43:28 +0200
Subject: [PATCH 14/18] Fix G1 nmethod registration
Subject: [PATCH 14/28] Fix G1 nmethod registration
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 19 ++++++++++++++++---
@@ -9,7 +9,7 @@ Subject: [PATCH 14/18] Fix G1 nmethod registration
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index a8adfa5af47..4ee12b7021f 100644
index 5be9bb74305..f4bde7504c8 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -217,7 +217,14 @@ void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
@@ -53,7 +53,7 @@ index a8adfa5af47..4ee12b7021f 100644
log_trace(redefine, class, obsolete, metadata)("After updating instances");
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 62a0fbf54d4..d00109a0b92 100644
index 9755944d70b..4c0412d343d 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -116,7 +116,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {

View File

@@ -1,7 +1,7 @@
From 0156b2084be20579b407e112a00ba15f54248003 Mon Sep 17 00:00:00 2001
From f0b7253294f14a64a5a4d0ef825e5377da03efa5 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Thu, 22 Oct 2020 20:15:20 +0200
Subject: [PATCH 15/18] Initialize method's _new_version/_old_version to NULL
Subject: [PATCH 15/28] Initialize method's _new_version/_old_version to NULL
---
src/hotspot/share/oops/method.cpp | 3 ++-

View File

@@ -1,7 +1,7 @@
From 81ba8f1d120e158a7b0cfa09b5dd51295d51901f Mon Sep 17 00:00:00 2001
From 0550e70425054a77e32fb96770d416b077720857 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 23 Oct 2020 10:20:26 +0200
Subject: [PATCH 16/18] Clear dcevm code separation
Subject: [PATCH 16/28] Clear dcevm code separation
---
src/hotspot/share/classfile/systemDictionary.cpp | 4 ++--
@@ -93,10 +93,10 @@ index 9dc184d02f5..bff1c3627b0 100644
is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
current_klass->external_name());
diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
index 84891b48c2a..6f19e2939a2 100644
index 61a406377ee..da9df7a21a2 100644
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
@@ -1467,7 +1467,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
@@ -1471,7 +1471,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
NULL, // host klass
NULL, // cp_patches
ClassFileParser::INTERNAL, // internal visibility

View File

@@ -1,7 +1,7 @@
From a022248d12e37084c8f8987a44d567ba0e02fb6d Mon Sep 17 00:00:00 2001
From fde9f15ed4fdb5139b6b81238d0a667327b552bb Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 23 Oct 2020 11:07:40 +0200
Subject: [PATCH 17/18] Fix metadataOnStack bug
Subject: [PATCH 17/28] Fix metadataOnStack bug
---
.../share/classfile/classLoaderData.cpp | 7 +-

View File

@@ -0,0 +1,25 @@
From 5b5f620932894e807956b45653d153d001be9fb1 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 1 Nov 2020 21:19:00 +0100
Subject: [PATCH 18/28] Ignore MetadataOnStackMark if redefining_gc_run
---
src/hotspot/share/classfile/classLoaderData.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index bba5ce0511f..8b2deb70e1b 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1401,7 +1401,7 @@ bool ClassLoaderDataGraph::do_unloading(bool clean_previous_versions) {
bool walk_all_metadata = clean_previous_versions &&
JvmtiExport::has_redefined_a_class() &&
InstanceKlass::has_previous_versions_and_reset();
- MetadataOnStackMark md_on_stack(walk_all_metadata, AllowEnhancedClassRedefinition);
+ MetadataOnStackMark md_on_stack(walk_all_metadata, Universe::is_redefining_gc_run());
// Save previous _unloading pointer for CMS which may add to unloading list before
// purging and we don't want to rewalk the previously unloaded class loader data.
--
2.23.0

View File

@@ -1,7 +1,7 @@
From 46795cd6c086e2008b270f89971bb07ad34ac355 Mon Sep 17 00:00:00 2001
From 29ac3233d58d9a1a30160ae13a895ff70e504022 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Wed, 11 Nov 2020 18:45:15 +0100
Subject: [PATCH 18/18] Fix LoadedClassesClosure - fixes problems with remote
Subject: [PATCH 19/28] Fix LoadedClassesClosure - fixes problems with remote
debugging
---

View File

@@ -1,7 +1,7 @@
From 62fc66fa74886bd8bb15cd3e2084175f7ad5d0c7 Mon Sep 17 00:00:00 2001
From 99e8f8d420dd09d6fb7f035d4baf7ef4816177e8 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Fri, 5 Feb 2021 23:30:49 +0100
Subject: [PATCH 19/19] Disable AllowEnhancedClassRedefinition in flight
Subject: [PATCH 20/28] Disable AllowEnhancedClassRedefinition in flight
recorder
---

View File

@@ -0,0 +1,41 @@
From 1bb55ff9f91733e45dd6f87eb4201a989b3338e3 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Fri, 12 Feb 2021 12:33:11 +0100
Subject: [PATCH 21/28] JBR-3106 Check InstanceKlass::has_nestmate_access_to
with active classes
Dcevm can leave old host in nested class if nested class is not
redefined together with host class
---
src/hotspot/share/oops/instanceKlass.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 710e0ddc930..24eb3ed68a6 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -327,11 +327,21 @@ bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
return false;
}
+ // (DCEVM) cur_host can be old, decide accessibility based on active version
+ if (AllowEnhancedClassRedefinition) {
+ cur_host = InstanceKlass::cast(cur_host->active_version());
+ }
+
Klass* k_nest_host = k->nest_host(icce, CHECK_false);
if (k_nest_host == NULL) {
return false;
}
+ // (DCEVM) k_nest_host can be old, decide accessibility based on active version
+ if (AllowEnhancedClassRedefinition) {
+ k_nest_host = InstanceKlass::cast(k_nest_host->active_version());
+ }
+
bool access = (cur_host == k_nest_host);
if (log_is_enabled(Trace, class, nestmates)) {
--
2.23.0

View File

@@ -0,0 +1,31 @@
From 52427060aba227d09dce4bd14410e1e626d64e46 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 7 Feb 2021 12:08:58 +0100
Subject: [PATCH 22/28] JBR-3110 Fix assert in MetadataOnStackMark
Fixed fastdebug tests crashes in redefine gc run
---
src/hotspot/share/classfile/metadataOnStackMark.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/classfile/metadataOnStackMark.cpp b/src/hotspot/share/classfile/metadataOnStackMark.cpp
index 9d7bdbde74b..66049f11629 100644
--- a/src/hotspot/share/classfile/metadataOnStackMark.cpp
+++ b/src/hotspot/share/classfile/metadataOnStackMark.cpp
@@ -49,10 +49,11 @@ NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
MetadataOnStackMark::MetadataOnStackMark(bool redefinition_walk, bool ignore) : _ignore(ignore) {
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
assert(_used_buffers == NULL, "sanity check");
- assert(!_is_active, "MetadataOnStackMarks do not nest");
- NOT_PRODUCT(_is_active = true;)
if (!ignore) {
+ assert(!_is_active, "MetadataOnStackMarks do not nest");
+ NOT_PRODUCT(_is_active = true;)
+
Threads::metadata_handles_do(Metadata::mark_on_stack);
if (redefinition_walk) {
--
2.23.0

View File

@@ -0,0 +1,78 @@
From 93cea8d61ef395a1ef9e308b0d3a8f9409b108d0 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 12 Feb 2021 11:27:39 +0100
Subject: [PATCH 23/28] Code cleanup
- Rename confusing method name old_if_redefined to old_if_redefining
- Remove unused is_redefining_gc_run
---
src/hotspot/share/classfile/dictionary.cpp | 6 +++---
src/hotspot/share/classfile/dictionary.hpp | 2 +-
src/hotspot/share/memory/universe.hpp | 5 -----
3 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp
index dda5188c370..4e361d439f4 100644
--- a/src/hotspot/share/classfile/dictionary.cpp
+++ b/src/hotspot/share/classfile/dictionary.cpp
@@ -381,7 +381,7 @@ InstanceKlass* Dictionary::find(unsigned int hash, Symbol* name,
int index = hash_to_index(hash);
DictionaryEntry* entry = get_entry(index, hash, name);
if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
- return old_if_redefined(entry->instance_klass());
+ return old_if_redefining(entry->instance_klass());
} else {
return NULL;
}
@@ -394,7 +394,7 @@ InstanceKlass* Dictionary::find_class(int index, unsigned int hash,
assert (index == index_for(name), "incorrect index?");
DictionaryEntry* entry = get_entry(index, hash, name);
- return old_if_redefined((entry != NULL) ? entry->instance_klass() : NULL);
+ return old_if_redefining((entry != NULL) ? entry->instance_klass() : NULL);
}
@@ -406,7 +406,7 @@ InstanceKlass* Dictionary::find_shared_class(int index, unsigned int hash,
assert (index == index_for(name), "incorrect index?");
DictionaryEntry* entry = get_entry(index, hash, name);
- return old_if_redefined((entry != NULL) ? entry->instance_klass() : NULL);
+ return old_if_redefining((entry != NULL) ? entry->instance_klass() : NULL);
}
diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp
index 5eaa741d500..f6e08e7bfd5 100644
--- a/src/hotspot/share/classfile/dictionary.hpp
+++ b/src/hotspot/share/classfile/dictionary.hpp
@@ -120,7 +120,7 @@ public:
void rollback_redefinition();
// (DCEVM) return old class if redefining in AllowEnhancedClassRedefinition, otherwise return "k"
- static InstanceKlass* old_if_redefined(InstanceKlass* k) {
+ static InstanceKlass* old_if_redefining(InstanceKlass* k) {
return (k != NULL && k->is_redefining()) ? ((InstanceKlass* )k->old_version()) : k;
}
};
diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp
index b32db16b9cf..742dada0e8f 100644
--- a/src/hotspot/share/memory/universe.hpp
+++ b/src/hotspot/share/memory/universe.hpp
@@ -52,13 +52,8 @@ class LatestMethodCache : public CHeapObj<mtClass> {
Klass* _klass;
int _method_idnum;
- static bool _is_redefining_gc_run;
-
public:
- static bool is_redefining_gc_run() { return _is_redefining_gc_run; }
- static void set_redefining_gc_run(bool b) { _is_redefining_gc_run = b; }
-
LatestMethodCache() { _klass = NULL; _method_idnum = -1; }
~LatestMethodCache() { _klass = NULL; _method_idnum = -1; }
--
2.23.0

View File

@@ -0,0 +1,95 @@
From dcb44f0e56dbc63b90d655b694a3f7751744fe53 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 13 Feb 2021 20:47:52 +0100
Subject: [PATCH 24/28] JBR-3111 Update class in all dictionaries where it was
already defined
This patch keeps compatibility with std redefinition, that does not
create a new Klass, but modifies it, then it is modified in all
dictionaries containing this class.
---
src/hotspot/share/classfile/classLoaderData.cpp | 9 +++++++++
src/hotspot/share/classfile/classLoaderData.hpp | 3 +++
src/hotspot/share/classfile/dictionary.cpp | 2 +-
src/hotspot/share/classfile/dictionary.hpp | 2 +-
src/hotspot/share/classfile/systemDictionary.cpp | 4 +++-
5 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 8b2deb70e1b..4e06b09e7d5 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1274,6 +1274,15 @@ void ClassLoaderDataGraph::rollback_redefinition() {
}
}
+// (DCEVM) - iterate over all classes in all dictionaries
+bool ClassLoaderDataGraph::dictionary_classes_do_update_klass(Symbol* name, InstanceKlass* k, InstanceKlass* old_klass) {
+ bool ok = false;
+ FOR_ALL_DICTIONARY(cld) {
+ ok = cld->dictionary()->update_klass(name, k, old_klass) || ok;
+ }
+ return ok;
+}
+
// Walks all entries in the dictionary including entries initiated by this class loader.
void ClassLoaderDataGraph::dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) {
Thread* thread = Thread::current();
diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp
index 00a84610b43..16711dca237 100644
--- a/src/hotspot/share/classfile/classLoaderData.hpp
+++ b/src/hotspot/share/classfile/classLoaderData.hpp
@@ -130,6 +130,9 @@ class ClassLoaderDataGraph : public AllStatic {
// Enhanced class redefinition
static void rollback_redefinition();
+ // Enhanced class redefinition
+ static bool dictionary_classes_do_update_klass(Symbol* name, InstanceKlass* k, InstanceKlass* old_klass);
+
// Iterate all classes and their class loaders, including initiating class loaders.
static void dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*));
diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp
index 4e361d439f4..6c072407fd9 100644
--- a/src/hotspot/share/classfile/dictionary.cpp
+++ b/src/hotspot/share/classfile/dictionary.cpp
@@ -345,7 +345,7 @@ DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
}
// (DCEVM) replace old_class by new class in dictionary
-bool Dictionary::update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass) {
+bool Dictionary::update_klass(Symbol* name, InstanceKlass* k, InstanceKlass* old_klass) {
// There are several entries for the same class in the dictionary: One extra entry for each parent classloader of the classloader of the class.
bool found = false;
for (int index = 0; index < table_size(); index++) {
diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp
index f6e08e7bfd5..2932cc9c320 100644
--- a/src/hotspot/share/classfile/dictionary.hpp
+++ b/src/hotspot/share/classfile/dictionary.hpp
@@ -115,7 +115,7 @@ public:
void free_entry(DictionaryEntry* entry);
// Enhanced class redefinition
- bool update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass);
+ bool update_klass(Symbol* name, InstanceKlass* k, InstanceKlass* old_klass);
void rollback_redefinition();
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 9e0f4dd3c96..789b5fb1e6d 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1606,7 +1606,9 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, InstanceKlass* ol
Dictionary* dictionary = loader_data->dictionary();
unsigned int d_hash = dictionary->compute_hash(name_h);
if (is_redefining) {
- bool ok = dictionary->update_klass(d_hash, name_h, loader_data, k, old_klass);
+ // Update all dictionaries containing old_class to new_class
+ // outcome must be same as result of standard redefinition, that does not create a new Klass
+ bool ok = ClassLoaderDataGraph::dictionary_classes_do_update_klass(name_h, k, old_klass);
assert (ok, "must have found old class and updated!");
}
check_constraints(d_hash, k, class_loader_h, !is_redefining, CHECK);
--
2.23.0

View File

@@ -0,0 +1,527 @@
From b9692c48bdbad8474251cfe72ac85e5c7ff2847e Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Thu, 18 Jun 2020 18:40:11 +0200
Subject: [PATCH 25/28] JBR-3140 - support for modularized HotswapAgent
Add -XX:HotswapAgent=[disabled,fatjar.core]
---
make/launcher/Launcher-java.base.gmk | 1 -
make/launcher/Launcher-java.rmi.gmk | 2 -
make/launcher/Launcher-java.scripting.gmk | 3 +-
make/launcher/Launcher-java.security.jgss.gmk | 3 --
make/launcher/Launcher-jdk.aot.gmk | 2 -
make/launcher/Launcher-jdk.compiler.gmk | 5 +-
make/launcher/Launcher-jdk.hotspot.agent.gmk | 1 -
make/launcher/Launcher-jdk.jartool.gmk | 2 -
make/launcher/Launcher-jdk.javadoc.gmk | 3 +-
make/launcher/Launcher-jdk.jcmd.gmk | 13 +----
make/launcher/Launcher-jdk.jdeps.gmk | 3 --
make/launcher/Launcher-jdk.jdi.gmk | 1 -
make/launcher/Launcher-jdk.jlink.gmk | 5 +-
make/launcher/Launcher-jdk.jshell.gmk | 1 -
make/launcher/Launcher-jdk.jstatd.gmk | 1 -
make/launcher/Launcher-jdk.pack.gmk | 1 -
make/launcher/Launcher-jdk.rmic.gmk | 1 -
.../Launcher-jdk.scripting.nashorn.shell.gmk | 3 +-
src/hotspot/share/runtime/arguments.cpp | 48 +++++++++++--------
.../runtime/flags/jvmFlagConstraintList.cpp | 23 +++++++++
.../runtime/flags/jvmFlagConstraintList.hpp | 1 +
.../flags/jvmFlagConstraintsRuntime.cpp | 10 ++++
.../flags/jvmFlagConstraintsRuntime.hpp | 1 +
src/hotspot/share/runtime/globals.hpp | 12 ++++-
24 files changed, 81 insertions(+), 65 deletions(-)
diff --git a/make/launcher/Launcher-java.base.gmk b/make/launcher/Launcher-java.base.gmk
index 38ba29530d8..f6d4aa28fe6 100644
--- a/make/launcher/Launcher-java.base.gmk
+++ b/make/launcher/Launcher-java.base.gmk
@@ -52,7 +52,6 @@ endif
$(eval $(call SetupBuildLauncher, keytool, \
MAIN_CLASS := sun.security.tools.keytool.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
################################################################################
diff --git a/make/launcher/Launcher-java.rmi.gmk b/make/launcher/Launcher-java.rmi.gmk
index 07046232275..a69a90bcc81 100644
--- a/make/launcher/Launcher-java.rmi.gmk
+++ b/make/launcher/Launcher-java.rmi.gmk
@@ -27,10 +27,8 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, rmid, \
MAIN_CLASS := sun.rmi.server.Activation, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, rmiregistry, \
MAIN_CLASS := sun.rmi.registry.RegistryImpl, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-java.scripting.gmk b/make/launcher/Launcher-java.scripting.gmk
index cf100e20789..057d2bf3aca 100644
--- a/make/launcher/Launcher-java.scripting.gmk
+++ b/make/launcher/Launcher-java.scripting.gmk
@@ -27,6 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jrunscript, \
MAIN_CLASS := com.sun.tools.script.shell.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT \
- -XX:+DisableHotswapAgent, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT, \
))
diff --git a/make/launcher/Launcher-java.security.jgss.gmk b/make/launcher/Launcher-java.security.jgss.gmk
index 2b856bfccb4..7411e1a21c4 100644
--- a/make/launcher/Launcher-java.security.jgss.gmk
+++ b/make/launcher/Launcher-java.security.jgss.gmk
@@ -28,16 +28,13 @@ include LauncherCommon.gmk
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupBuildLauncher, kinit, \
MAIN_CLASS := sun.security.krb5.internal.tools.Kinit, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, klist, \
MAIN_CLASS := sun.security.krb5.internal.tools.Klist, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, ktab, \
MAIN_CLASS := sun.security.krb5.internal.tools.Ktab, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
endif
diff --git a/make/launcher/Launcher-jdk.aot.gmk b/make/launcher/Launcher-jdk.aot.gmk
index 2c52c31a555..10717a5e1c5 100644
--- a/make/launcher/Launcher-jdk.aot.gmk
+++ b/make/launcher/Launcher-jdk.aot.gmk
@@ -31,7 +31,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jaotc, \
MAIN_CLASS := jdk.tools.jaotc.Main, \
EXTRA_JAVA_ARGS := -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI \
- -XX:+DisableHotswapAgent \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.amd64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.code=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
@@ -41,7 +40,6 @@ $(eval $(call SetupBuildLauncher, jaotc, \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
, \
JAVA_ARGS := --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
- -XX:+DisableHotswapAgent \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.amd64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.sparc=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
diff --git a/make/launcher/Launcher-jdk.compiler.gmk b/make/launcher/Launcher-jdk.compiler.gmk
index 744969546de..f71c37adf74 100644
--- a/make/launcher/Launcher-jdk.compiler.gmk
+++ b/make/launcher/Launcher-jdk.compiler.gmk
@@ -27,14 +27,12 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javac, \
MAIN_CLASS := com.sun.tools.javac.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT \
- -XX:+DisableHotswapAgent, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, serialver, \
MAIN_CLASS := sun.tools.serialver.SerialVer, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
@@ -43,7 +41,6 @@ ifeq ($(ENABLE_SJAVAC), yes)
# into any real images
$(eval $(call SetupBuildLauncher, sjavac, \
MAIN_CLASS := com.sun.tools.sjavac.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/bin, \
))
diff --git a/make/launcher/Launcher-jdk.hotspot.agent.gmk b/make/launcher/Launcher-jdk.hotspot.agent.gmk
index 9f12b05b172..76da3600368 100644
--- a/make/launcher/Launcher-jdk.hotspot.agent.gmk
+++ b/make/launcher/Launcher-jdk.hotspot.agent.gmk
@@ -27,6 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jhsdb, \
MAIN_CLASS := sun.jvm.hotspot.SALauncher, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
diff --git a/make/launcher/Launcher-jdk.jartool.gmk b/make/launcher/Launcher-jdk.jartool.gmk
index 647d82b65b1..f74e82bfdae 100644
--- a/make/launcher/Launcher-jdk.jartool.gmk
+++ b/make/launcher/Launcher-jdk.jartool.gmk
@@ -27,10 +27,8 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jar, \
MAIN_CLASS := sun.tools.jar.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jarsigner, \
MAIN_CLASS := sun.security.tools.jarsigner.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-jdk.javadoc.gmk b/make/launcher/Launcher-jdk.javadoc.gmk
index c3d2093be04..889028a2b17 100644
--- a/make/launcher/Launcher-jdk.javadoc.gmk
+++ b/make/launcher/Launcher-jdk.javadoc.gmk
@@ -27,7 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javadoc, \
MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT \
- -XX:+DisableHotswapAgent, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jcmd.gmk b/make/launcher/Launcher-jdk.jcmd.gmk
index 761a52d8466..7117fa78059 100644
--- a/make/launcher/Launcher-jdk.jcmd.gmk
+++ b/make/launcher/Launcher-jdk.jcmd.gmk
@@ -30,7 +30,6 @@ $(eval $(call SetupBuildLauncher, jinfo, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
- -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
@@ -38,36 +37,28 @@ $(eval $(call SetupBuildLauncher, jmap, \
MAIN_CLASS := sun.tools.jmap.JMap, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
- -Dsun.jvm.hotspot.debugger.useWindbgDebugger \
- -XX:+DisableHotswapAgent, \
+ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
MACOSX_PRIVILEGED := true, \
))
$(eval $(call SetupBuildLauncher, jps, \
MAIN_CLASS := sun.tools.jps.Jps, \
- JAVA_ARGS := \
- -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jstack, \
MAIN_CLASS := sun.tools.jstack.JStack, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
- -Dsun.jvm.hotspot.debugger.useWindbgDebugger \
- -XX:+DisableHotswapAgent, \
+ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
MACOSX_PRIVILEGED := true, \
))
$(eval $(call SetupBuildLauncher, jstat, \
MAIN_CLASS := sun.tools.jstat.Jstat, \
- JAVA_ARGS := \
- -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jcmd, \
MAIN_CLASS := sun.tools.jcmd.JCmd, \
- JAVA_ARGS := \
- -XX:+DisableHotswapAgent, \
))
# Hook to include the corresponding custom file, if present.
diff --git a/make/launcher/Launcher-jdk.jdeps.gmk b/make/launcher/Launcher-jdk.jdeps.gmk
index 5448278dae7..217523c48cc 100644
--- a/make/launcher/Launcher-jdk.jdeps.gmk
+++ b/make/launcher/Launcher-jdk.jdeps.gmk
@@ -27,18 +27,15 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javap, \
MAIN_CLASS := com.sun.tools.javap.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jdeps, \
MAIN_CLASS := com.sun.tools.jdeps.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jdeprscan, \
MAIN_CLASS := com.sun.tools.jdeprscan.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jdi.gmk b/make/launcher/Launcher-jdk.jdi.gmk
index 27bd448e3ae..fcce98cf430 100644
--- a/make/launcher/Launcher-jdk.jdi.gmk
+++ b/make/launcher/Launcher-jdk.jdi.gmk
@@ -27,5 +27,4 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jdb, \
MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-jdk.jlink.gmk b/make/launcher/Launcher-jdk.jlink.gmk
index 9e61edeb2c8..df2173996d7 100644
--- a/make/launcher/Launcher-jdk.jlink.gmk
+++ b/make/launcher/Launcher-jdk.jlink.gmk
@@ -27,21 +27,18 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jimage,\
MAIN_CLASS := jdk.tools.jimage.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES, \
))
$(eval $(call SetupBuildLauncher, jlink,\
MAIN_CLASS := jdk.tools.jlink.internal.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT \
- -XX:+DisableHotswapAgent, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jmod,\
MAIN_CLASS := jdk.tools.jmod.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jshell.gmk b/make/launcher/Launcher-jdk.jshell.gmk
index 7287f8f998a..349eb88e9eb 100644
--- a/make/launcher/Launcher-jdk.jshell.gmk
+++ b/make/launcher/Launcher-jdk.jshell.gmk
@@ -27,6 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jshell, \
MAIN_CLASS := jdk.internal.jshell.tool.JShellToolProvider, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jstatd.gmk b/make/launcher/Launcher-jdk.jstatd.gmk
index e1657910c67..e9286d63094 100644
--- a/make/launcher/Launcher-jdk.jstatd.gmk
+++ b/make/launcher/Launcher-jdk.jstatd.gmk
@@ -27,7 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jstatd, \
MAIN_CLASS := sun.tools.jstatd.Jstatd, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
# Hook to include the corresponding custom file, if present.
diff --git a/make/launcher/Launcher-jdk.pack.gmk b/make/launcher/Launcher-jdk.pack.gmk
index 64bbbb7c949..a93fd2a9017 100644
--- a/make/launcher/Launcher-jdk.pack.gmk
+++ b/make/launcher/Launcher-jdk.pack.gmk
@@ -28,7 +28,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, pack200, \
MAIN_MODULE := java.base, \
MAIN_CLASS := com.sun.java.util.jar.pack.Driver, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
################################################################################
diff --git a/make/launcher/Launcher-jdk.rmic.gmk b/make/launcher/Launcher-jdk.rmic.gmk
index b8a55900b0e..d60c3d9b60b 100644
--- a/make/launcher/Launcher-jdk.rmic.gmk
+++ b/make/launcher/Launcher-jdk.rmic.gmk
@@ -27,6 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, rmic, \
MAIN_CLASS := sun.rmi.rmic.Main, \
- JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
index bd39f8595b2..82311e69fd6 100644
--- a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
+++ b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
@@ -27,7 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT \
- -XX:+DisableHotswapAgent, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES, \
))
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index c5635bb8537..d7fee6a8c95 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4310,11 +4310,17 @@ void Arguments::setup_hotswap_agent() {
if (DumpSharedSpaces)
return;
- if (!AllowEnhancedClassRedefinition)
+ if (HotswapAgent == NULL || strcmp(HotswapAgent, "disabled") == 0)
return;
+ // Force AllowEnhancedClassRedefinition if HA is enabled
+ AllowEnhancedClassRedefinition = true;
+
+ bool ha_fatjar = strcmp(HotswapAgent, "fatjar") == 0;
+ bool ha_core = strcmp(HotswapAgent, "core") == 0;
+
// Set HotswapAgent
- if (!DisableHotswapAgent) {
+ if (ha_fatjar || ha_core) {
char ext_path_str[JVM_MAXPATHLEN];
@@ -4333,23 +4339,27 @@ void Arguments::setup_hotswap_agent() {
}
}
if (ext_path_length < JVM_MAXPATHLEN - 10) {
- jio_snprintf(ext_path_str + ext_path_length, sizeof(ext_path_str) - ext_path_length,
- "%shotswap%shotswap-agent.jar", os::file_separator(), os::file_separator());
- }
-
- int fd = ::open(ext_path_str, O_RDONLY);
- if (fd >= 0) {
- os::close(fd);
- size_t length = strlen(ext_path_str) + 1;
- char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
- jio_snprintf(options, length, "%s", ext_path_str);
- add_init_agent("instrument", ext_path_str, false);
- jio_fprintf(defaultStream::output_stream(), "Starting HotswapAgent '%s'\n", ext_path_str);
- }
-// else
-// {
-// jio_fprintf(defaultStream::error_stream(), "HotswapAgent not found on path:'%s'\n", ext_path_str);
-// }
+ if (ha_fatjar) {
+ jio_snprintf(ext_path_str + ext_path_length, sizeof(ext_path_str) - ext_path_length,
+ "%shotswap%shotswap-agent.jar", os::file_separator(), os::file_separator());
+ } else {
+ jio_snprintf(ext_path_str + ext_path_length, sizeof(ext_path_str) - ext_path_length,
+ "%shotswap%shotswap-agent-core.jar", os::file_separator(), os::file_separator());
+ }
+ int fd = ::open(ext_path_str, O_RDONLY);
+ if (fd >= 0) {
+ os::close(fd);
+ size_t length = strlen(ext_path_str) + 1;
+ char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
+ jio_snprintf(options, length, "%s", ext_path_str);
+ add_init_agent("instrument", ext_path_str, false);
+ jio_fprintf(defaultStream::output_stream(), "Starting HotswapAgent '%s'\n", ext_path_str);
+ }
+ else
+ {
+ jio_fprintf(defaultStream::error_stream(), "HotswapAgent not found on path:'%s'!\n", ext_path_str);
+ }
+ }
}
// TODO: open it only for org.hotswap.agent module
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
index 16d8030fd1c..94044c4831c 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
@@ -199,6 +199,26 @@ public:
}
};
+class JVMFlagConstraint_ccstr : public JVMFlagConstraint {
+ JVMFlagConstraintFunc_ccstr _constraint;
+ const ccstr* _ptr;
+
+public:
+ // the "name" argument must be a string literal
+ JVMFlagConstraint_ccstr(const char* name, const ccstr* ptr,
+ JVMFlagConstraintFunc_ccstr func,
+ ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+
+ JVMFlag::Error apply(bool verbose) {
+ ccstr value = *_ptr;
+ return _constraint(value, verbose);
+ }
+
+ JVMFlag::Error apply_ccstr(ccstr value, bool verbose) {
+ return _constraint(value, verbose);
+ }
+};
+
// No constraint emitting
void emit_constraint_no(...) { /* NOP */ }
@@ -239,6 +259,9 @@ void emit_constraint_size_t(const char* name, const size_t* ptr, JVMFlagConstrai
void emit_constraint_double(const char* name, const double* ptr, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) {
JVMFlagConstraintList::add(new JVMFlagConstraint_double(name, ptr, func, type));
}
+void emit_constraint_ccstr(const char* name, ccstr* ptr, JVMFlagConstraintFunc_ccstr func, JVMFlagConstraint::ConstraintType type) {
+ JVMFlagConstraintList::add(new JVMFlagConstraint_ccstr(name, ptr, func, type));
+}
// Generate code to call emit_constraint_xxx function
#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
index 9c27f1db955..b644f7b817a 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
@@ -47,6 +47,7 @@ typedef JVMFlag::Error (*JVMFlagConstraintFunc_uintx)(uintx value, bool verbose)
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_size_t)(size_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_double)(double value, bool verbose);
+typedef JVMFlag::Error (*JVMFlagConstraintFunc_ccstr)(ccstr value, bool verbose);
class JVMFlagConstraint : public CHeapObj<mtArguments> {
public:
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
index 6559d4252f0..21afac72a2e 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
@@ -140,3 +140,13 @@ JVMFlag::Error ThreadLocalHandshakesConstraintFunc(bool value, bool verbose) {
}
return JVMFlag::SUCCESS;
}
+
+JVMFlag::Error HotswapAgentConstraintFunc(char const* value, bool verbose) {
+ if (value != NULL) {
+ if (strcmp("disabled", value) != 0 && strcmp("fatjar", value) != 0 && strcmp("core", value) != 0 && strcmp("external", value) != 0) {
+ JVMFlag::printError(verbose, "HotswapAgent(%s) must be one of disabled,fatjar,core or external.\n", value);
+ return JVMFlag::VIOLATES_CONSTRAINT;
+ }
+ }
+ return JVMFlag::SUCCESS;
+}
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
index 8763b83fd37..c9ed15a89e1 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
@@ -46,5 +46,6 @@ JVMFlag::Error PerfDataSamplingIntervalFunc(intx value, bool verbose);
JVMFlag::Error ThreadLocalHandshakesConstraintFunc(bool value, bool verbose);
+JVMFlag::Error HotswapAgentConstraintFunc(char const* value, bool verbose);
#endif /* SHARE_VM_RUNTIME_JVMFLAGCONSTRAINTSRUNTIME_HPP */
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index d4453de1ff5..8c41f0af888 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -2686,8 +2686,16 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
"Allow enhanced class redefinition beyond swapping method " \
"bodies") \
\
- product(bool, DisableHotswapAgent, DISABLED_HOTSWAP_AGENT, \
- "Disable integrated Hotswap Agent (HotswapVM only)")
+ product(ccstr, HotswapAgent, "disabled", \
+ "Specify HotswapAgent image to be used." \
+ "disabled: hotswap agent is disabled (default)" \
+ "fatjar: full HA. Use integrated hotswap-agent.jar" \
+ "core: core HA. Use integrated hotswap-agent-core.jar" \
+ "external: external HA. use external HA, open required JDK " \
+ "modules.") \
+ constraint(HotswapAgentConstraintFunc, AfterErgo)
+
+
#define VM_FLAGS(develop, \
develop_pd, \
product, \
--
2.23.0

View File

@@ -0,0 +1,333 @@
From f279999a412cc87c6f4a7eed7e1e2ad34655b4fe Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Mon, 8 Mar 2021 02:22:54 +0700
Subject: [PATCH 26/28] Support for redefinition of Well Known classses
(java.*,jdk.*, sun.*)
---
src/hotspot/share/ci/ciKlass.hpp | 1 +
src/hotspot/share/ci/ciObjectFactory.cpp | 34 +++++++++++
src/hotspot/share/ci/ciObjectFactory.hpp | 6 ++
.../share/classfile/systemDictionary.cpp | 10 +++
.../share/classfile/systemDictionary.hpp | 2 +
src/hotspot/share/classfile/vmSymbols.hpp | 2 +
src/hotspot/share/compiler/compileBroker.cpp | 11 ++++
src/hotspot/share/memory/universe.cpp | 8 +++
src/hotspot/share/memory/universe.hpp | 3 +
.../prims/jvmtiEnhancedRedefineClasses.cpp | 61 ++++++++++++++++++-
.../prims/jvmtiEnhancedRedefineClasses.hpp | 2 +
11 files changed, 139 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/ci/ciKlass.hpp b/src/hotspot/share/ci/ciKlass.hpp
index 896f489453a..c610c365aba 100644
--- a/src/hotspot/share/ci/ciKlass.hpp
+++ b/src/hotspot/share/ci/ciKlass.hpp
@@ -129,6 +129,7 @@ public:
void print_name_on(outputStream* st);
const char* external_name() const;
+ Klass* new_version() { return get_Klass()->new_version(); }
};
#endif // SHARE_VM_CI_CIKLASS_HPP
diff --git a/src/hotspot/share/ci/ciObjectFactory.cpp b/src/hotspot/share/ci/ciObjectFactory.cpp
index 66bbe835e7b..107c16fa5cf 100644
--- a/src/hotspot/share/ci/ciObjectFactory.cpp
+++ b/src/hotspot/share/ci/ciObjectFactory.cpp
@@ -70,7 +70,10 @@ GrowableArray<ciMetadata*>* ciObjectFactory::_shared_ci_metadata = NULL;
ciSymbol* ciObjectFactory::_shared_ci_symbols[vmSymbols::SID_LIMIT];
int ciObjectFactory::_shared_ident_limit = 0;
volatile bool ciObjectFactory::_initialized = false;
+volatile bool ciObjectFactory::_reinitialize_wk_klasses = false;
+// TODO: review...
+Arena* ciObjectFactory::_initial_arena = NULL;
// ------------------------------------------------------------------
// ciObjectFactory::ciObjectFactory
@@ -112,6 +115,7 @@ void ciObjectFactory::initialize() {
// compiler thread that initializes the initial ciObjectFactory which
// creates the shared ciObjects that all later ciObjectFactories use.
Arena* arena = new (mtCompiler) Arena(mtCompiler);
+ ciObjectFactory::_initial_arena = arena;
ciEnv initial(arena);
ciEnv* env = ciEnv::current();
env->_factory->init_shared_objects();
@@ -120,6 +124,36 @@ void ciObjectFactory::initialize() {
}
+// (DCEVM) wk classes could be modified
+void ciObjectFactory::reinitialize_wk_classes() {
+ ASSERT_IN_VM;
+ JavaThread* thread = JavaThread::current();
+ HandleMark handle_mark(thread);
+
+ // This Arena is long lived and exists in the resource mark of the
+ // compiler thread that initializes the initial ciObjectFactory which
+ // creates the shared ciObjects that all later ciObjectFactories use.
+ // Arena* arena = new (mtCompiler) Arena(mtCompiler);
+ ciEnv initial(ciObjectFactory::_initial_arena);
+ ciEnv* env = ciEnv::current();
+ env->_factory->do_reinitialize_wk_classes();
+ _reinitialize_wk_klasses = false;
+}
+
+// (DCEVM) wk classes could be modified
+void ciObjectFactory::do_reinitialize_wk_classes() {
+#define WK_KLASS_DEFN(name, ignore_s, opt) \
+ if (ciEnv::_##name != NULL && ciEnv::_##name->new_version() != NULL) { \
+ int old_ident = ciEnv::_##name->ident(); \
+ ciEnv::_##name = get_metadata(SystemDictionary::name())->as_instance_klass(); \
+ ciEnv::_##name->compute_nonstatic_fields(); \
+ ciEnv::_##name->set_ident(old_ident); \
+ }
+
+ WK_KLASSES_DO(WK_KLASS_DEFN)
+#undef WK_KLASS_DEFN
+}
+
void ciObjectFactory::init_shared_objects() {
_next_ident = 1; // start numbering CI objects at 1
diff --git a/src/hotspot/share/ci/ciObjectFactory.hpp b/src/hotspot/share/ci/ciObjectFactory.hpp
index 3e9d48c4cdc..79059f6e2e8 100644
--- a/src/hotspot/share/ci/ciObjectFactory.hpp
+++ b/src/hotspot/share/ci/ciObjectFactory.hpp
@@ -41,9 +41,11 @@ class ciObjectFactory : public ResourceObj {
private:
static volatile bool _initialized;
+ static volatile bool _reinitialize_wk_klasses;
static GrowableArray<ciMetadata*>* _shared_ci_metadata;
static ciSymbol* _shared_ci_symbols[];
static int _shared_ident_limit;
+ static Arena* _initial_arena;
Arena* _arena;
GrowableArray<ciMetadata*>* _ci_metadata;
@@ -89,10 +91,14 @@ private:
ciInstance* get_unloaded_instance(ciInstanceKlass* klass);
static int compare_cimetadata(ciMetadata** a, ciMetadata** b);
+ void do_reinitialize_wk_classes();
public:
static bool is_initialized() { return _initialized; }
+ static bool is_reinitialize_wk_klasses() { return _reinitialize_wk_klasses; }
+ static void set_reinitialize_wk_klasses() { _reinitialize_wk_klasses = true; }
static void initialize();
+ static void reinitialize_wk_classes();
void init_shared_objects();
void remove_symbols();
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 789b5fb1e6d..25e577a664c 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1983,6 +1983,16 @@ bool SystemDictionary::is_well_known_klass(Symbol* class_name) {
}
#endif
+bool SystemDictionary::update_well_known_klass(InstanceKlass* old_klass, InstanceKlass* new_klass) {
+ for (int id = FIRST_WKID; id < WKID_LIMIT; id++) {
+ if (well_known_klass((WKID) id) == old_klass) {
+ *well_known_klass_addr((WKID)id) = new_klass;
+ return true;
+ }
+ }
+ return false;
+}
+
bool SystemDictionary::resolve_wk_klass(WKID id, int init_opt, TRAPS) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
int info = wk_init_info[id - FIRST_WKID];
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 1dbbffa197f..4220978a025 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -467,6 +467,8 @@ public:
static bool is_well_known_klass(Symbol* class_name);
#endif
+ static bool update_well_known_klass(InstanceKlass* new_klass, InstanceKlass* old_klass);
+
// Enhanced class redefinition
static void remove_from_hierarchy(InstanceKlass* k);
static void update_constraints_after_redefinition();
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index 2409af9b06e..daaa8d12375 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -355,6 +355,8 @@
template(exit_method_name, "exit") \
template(add_method_name, "add") \
template(remove_method_name, "remove") \
+ template(registerNatives_method_name, "registerNatives") \
+ template(initIDs_method_name, "initIDs") \
template(parent_name, "parent") \
template(threads_name, "threads") \
template(groups_name, "groups") \
diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp
index 765b8ffa4dc..25271feb41f 100644
--- a/src/hotspot/share/compiler/compileBroker.cpp
+++ b/src/hotspot/share/compiler/compileBroker.cpp
@@ -1877,6 +1877,17 @@ void CompileBroker::compiler_thread_loop() {
if (method()->number_of_breakpoints() == 0) {
// Compile the method.
if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
+
+ // TODO: review usage of CompileThread_lock (DCEVM)
+ if (ciObjectFactory::is_reinitialize_wk_klasses())
+ {
+ ASSERT_IN_VM;
+ MutexLocker only_one (CompileThread_lock, thread);
+ if (ciObjectFactory::is_reinitialize_wk_klasses()) {
+ ciObjectFactory::reinitialize_wk_classes();
+ }
+ }
+
invoke_compiler_on_method(task);
thread->start_idle_timer();
} else {
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 3dc4cc1323c..6b88271b5ef 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -1030,6 +1030,14 @@ void Universe::initialize_known_methods(TRAPS) {
vmSymbols::doStackWalk_signature(), false, CHECK);
}
+void Universe::reinitialize_loader_addClass_method(TRAPS) {
+ // Set up method for registering loaded classes in class loader vector
+ initialize_known_method(_loader_addClass_cache,
+ SystemDictionary::ClassLoader_klass(),
+ "addClass",
+ vmSymbols::class_void_signature(), false, CHECK);
+}
+
void universe2_init() {
EXCEPTION_MARK;
Universe::genesis(CATCH);
diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp
index 742dada0e8f..d1af82b5fa7 100644
--- a/src/hotspot/share/memory/universe.hpp
+++ b/src/hotspot/share/memory/universe.hpp
@@ -349,6 +349,9 @@ class Universe: AllStatic {
// Function to initialize these
static void initialize_known_methods(TRAPS);
+ // Enhanced class redefinition
+ static void reinitialize_loader_addClass_method(TRAPS);
+
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index f4bde7504c8..80d4e68ccae 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -497,6 +497,16 @@ void VM_EnhancedRedefineClasses::doit() {
redefine_single_class(_new_classes->at(i), thread);
}
+ // Update possible redefinition of well-known classes (like ClassLoader)
+ for (int i = 0; i < _new_classes->length(); i++) {
+ InstanceKlass* cur = _new_classes->at(i);
+ if (cur->old_version() != NULL && SystemDictionary::update_well_known_klass(InstanceKlass::cast(cur->old_version()), cur))
+ {
+ log_trace(redefine, class, obsolete, metadata)("Well known class updated %s", cur->external_name());
+ ciObjectFactory::set_reinitialize_wk_klasses();
+ }
+ }
+
// Deoptimize all compiled code that depends on this class (do only once, because it clears whole cache)
// if (_max_redefinition_flags > Klass::ModifyClass) {
flush_dependent_code(NULL, thread);
@@ -672,12 +682,56 @@ void VM_EnhancedRedefineClasses::doit() {
_timer_vm_op_doit.stop();
}
+void VM_EnhancedRedefineClasses::reinitializeJDKClasses() {
+ if (!_new_classes->is_empty()) {
+ ResourceMark rm(Thread::current());
+
+ for (int i = 0; i < _new_classes->length(); i++) {
+ InstanceKlass* cur = _new_classes->at(i);
+
+ if (cur->name()->starts_with("java/") || cur->name()->starts_with("jdk/") || cur->name()->starts_with("sun/")) {
+
+ if (cur == SystemDictionary::ClassLoader_klass()) {
+ // ClassLoader.addClass method is cached in Universe, we must redefine
+ Universe::reinitialize_loader_addClass_method(Thread::current());
+ log_trace(redefine, class, obsolete, metadata)("Reinitialize ClassLoade addClass method cache.");
+ }
+
+ // naive assumptions that only JDK classes has native static "registerNative" and "initIDs" methods
+ int end;
+ Symbol* signature = vmSymbols::registerNatives_method_name();
+ int midx = cur->find_method_by_name(signature, &end);
+ if (midx == -1) {
+ signature = vmSymbols::initIDs_method_name();
+ midx = cur->find_method_by_name(signature, &end);
+ }
+ Method* m = NULL;
+ if (midx != -1) {
+ m = cur->methods()->at(midx);
+ }
+ if (m != NULL && m->is_static() && m->is_native()) {
+ // call static registerNative if present
+ JavaValue result(T_VOID);
+ JavaCalls::call_static(&result,
+ cur,
+ signature,
+ vmSymbols::void_method_signature(),
+ Thread::current());
+ log_trace(redefine, class, obsolete, metadata)("Reregister natives of JDK class %s", cur->external_name());
+ }
+ }
+ }
+ }
+}
+
// Cleanup - runs in JVM thread
// - free used memory
// - end GC
void VM_EnhancedRedefineClasses::doit_epilogue() {
VM_GC_Operation::doit_epilogue();
+ reinitializeJDKClasses();
+
if (_new_classes != NULL) {
delete _new_classes;
}
@@ -1589,7 +1643,12 @@ void VM_EnhancedRedefineClasses::check_methods_and_mark_as_obsolete() {
// obsolete methods need a unique idnum so they become new entries in
// the jmethodID cache in InstanceKlass
- assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
+ if (old_method->method_idnum() != new_method->method_idnum()) {
+ log_error(redefine, class, normalize)
+ ("Method not matched: %d != %d old: %s = new: %s", old_method->method_idnum(), new_method->method_idnum(),
+ old_method->name_and_sig_as_C_string(), new_method->name_and_sig_as_C_string());
+ // assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
+ }
// u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
// if (num != ConstMethod::UNSET_IDNUM) {
// old_method->set_method_idnum(num);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 4c0412d343d..79ea17b0d47 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -141,6 +141,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
void flush_dependent_code(InstanceKlass* k_h, TRAPS);
+ void reinitializeJDKClasses();
+
static void check_class(InstanceKlass* k_oop, TRAPS);
static void dump_methods();
--
2.23.0

View File

@@ -0,0 +1,27 @@
From 416d06e7e5f3517e9303b0b5a705888e4db740bd Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 19 Mar 2021 19:13:38 +0100
Subject: [PATCH 27/28] JBR-3458: Skip dynamic proxy classes based on
com.sun.proxy
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 80d4e68ccae..10c375d601c 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -689,7 +689,8 @@ void VM_EnhancedRedefineClasses::reinitializeJDKClasses() {
for (int i = 0; i < _new_classes->length(); i++) {
InstanceKlass* cur = _new_classes->at(i);
- if (cur->name()->starts_with("java/") || cur->name()->starts_with("jdk/") || cur->name()->starts_with("sun/")) {
+ if ((cur->name()->starts_with("java/") || cur->name()->starts_with("jdk/") || cur->name()->starts_with("sun/"))
+ && cur->name()->index_of_at(0, "$$") == -1) { // skip dynamic proxies
if (cur == SystemDictionary::ClassLoader_klass()) {
// ClassLoader.addClass method is cached in Universe, we must redefine
--
2.23.0

View File

@@ -0,0 +1,79 @@
From 88e0325768b074607f5f9edfbb7f8e4a76159942 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 20 Mar 2021 20:51:08 +0100
Subject: [PATCH 28/28] JBR-3459: Fix race condition in
ClassLoaderDataGraph::classes_do
InstanceKlass in ClassLoaderData can be uninitialized when
ClassLoaderDataGraph::classes_do is called. Using
ClassLoaderDataGraph::dictionary_classes_do is safe but problem is still
persisting with anonymous classes.
---
src/hotspot/share/classfile/classLoaderData.cpp | 10 ++++++++++
src/hotspot/share/classfile/classLoaderData.hpp | 4 ++++
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 13 +++++++++++--
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 4e06b09e7d5..f319cca3b2b 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1166,6 +1166,16 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
}
}
+void ClassLoaderDataGraph::anonymous_classes_do(KlassClosure* klass_closure) {
+ Thread* thread = Thread::current();
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ if (cld->is_anonymous()) {
+ Handle holder(thread, cld->holder_phantom());
+ cld->classes_do(klass_closure);
+ }
+ }
+}
+
void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
Thread* thread = Thread::current();
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp
index 16711dca237..b10fafa01e5 100644
--- a/src/hotspot/share/classfile/classLoaderData.hpp
+++ b/src/hotspot/share/classfile/classLoaderData.hpp
@@ -108,6 +108,10 @@ class ClassLoaderDataGraph : public AllStatic {
// for redefinition. These classes are removed during the next class unloading.
// Walking the ClassLoaderDataGraph also includes anonymous classes.
static void classes_do(KlassClosure* klass_closure);
+
+ // Enhanced class redefinition
+ static void anonymous_classes_do(KlassClosure* klass_closure);
+
static void classes_do(void f(Klass* const));
static void methods_do(void f(Method*));
static void modules_do(void f(ModuleEntry*));
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 10c375d601c..5de5f78aea0 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -2130,8 +2130,17 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
AffectedKlassClosure closure(_affected_klasses);
// Updated in j10, from original SystemDictionary::classes_do
- ClassLoaderDataGraph::classes_do(&closure);
- //ClassLoaderDataGraph::dictionary_classes_do(&closure);
+ // 0. we can't use ClassLoaderDataGraph::classes_do since classes can be uninitialized in cld,
+ // fully initialized class is in system dictionary
+ // ClassLoaderDataGraph::classes_do(&closure);
+
+ // 1. Scan over dictionaries
+ ClassLoaderDataGraph::dictionary_classes_do(&closure);
+
+ // 2. Anonymous class is not in dictionary, we have to iterate anonymous cld directly, but there is race cond...
+ // TODO: review ... anonymous class is added to cld before InstanceKlass initialization,
+ // find out how to check if the InstanceKlass is initialized
+ ClassLoaderDataGraph::anonymous_classes_do(&closure);
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
--
2.23.0

View File

@@ -1352,6 +1352,10 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
return NULL;
}
void * os::dll_load_utf8(const char *filename, char *ebuf, int ebuflen) {
return os::dll_load(filename, ebuf, ebuflen);
}
void* os::dll_lookup(void* handle, const char* name) {
void* res = dlsym(handle, name);
return res;

View File

@@ -1521,6 +1521,10 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
}
#endif // !__APPLE__
void * os::dll_load_utf8(const char *filename, char *ebuf, int ebuflen) {
return os::dll_load(filename, ebuf, ebuflen);
}
void* os::get_default_process_handle() {
#ifdef __APPLE__
// MacOS X needs to use RTLD_FIRST instead of RTLD_LAZY

View File

@@ -1944,6 +1944,10 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
return NULL;
}
void * os::dll_load_utf8(const char *filename, char *ebuf, int ebuflen) {
return os::dll_load(filename, ebuf, ebuflen);
}
void * os::Linux::dlopen_helper(const char *filename, char *ebuf,
int ebuflen) {
void * result = ::dlopen(filename, RTLD_LAZY);

View File

@@ -1679,6 +1679,10 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
return NULL;
}
void * os::dll_load_utf8(const char *filename, char *ebuf, int ebuflen) {
return os::dll_load(filename, ebuf, ebuflen);
}
void* os::dll_lookup(void* handle, const char* name) {
return dlsym(handle, name);
}

View File

@@ -1355,25 +1355,26 @@ static int _print_module(const char* fname, address base_address,
}
static errno_t convert_to_UTF16(char const* source_str, UINT source_encoding, LPWSTR* dest_utf16_str) {
const int flag_source_str_is_null_terminated = -1;
const int flag_estimate_chars_count = 0;
int utf16_chars_count_estimated = MultiByteToWideChar(source_encoding,
MB_ERR_INVALID_CHARS,
source_str, flag_source_str_is_null_terminated,
NULL, flag_estimate_chars_count);
if (utf16_chars_count_estimated == 0) {
const int len_estimated = MultiByteToWideChar(source_encoding,
MB_ERR_INVALID_CHARS,
source_str,
-1, // source is null-terminated
NULL,
0); // estimate characters count
if (len_estimated == 0) {
// Probably source_str contains characters that cannot be represented in the source_encoding given.
*dest_utf16_str = NULL;
return EINVAL;
}
*dest_utf16_str = NEW_C_HEAP_ARRAY(WCHAR, utf16_chars_count_estimated, mtInternal);
*dest_utf16_str = NEW_C_HEAP_ARRAY(WCHAR, len_estimated, mtInternal);
int utf16_chars_count_real = MultiByteToWideChar(source_encoding,
MB_ERR_INVALID_CHARS,
source_str, flag_source_str_is_null_terminated,
*dest_utf16_str, utf16_chars_count_estimated);
assert(utf16_chars_count_real == utf16_chars_count_estimated, "length already checked above");
const int len_real = MultiByteToWideChar(source_encoding,
MB_ERR_INVALID_CHARS,
source_str,
-1, // source is null-terminated
*dest_utf16_str, len_estimated);
assert(len_real == len_estimated, "length already checked above");
return ERROR_SUCCESS;
}
@@ -1391,24 +1392,26 @@ static errno_t convert_UTF8_to_UTF16(char const* utf8_str, LPWSTR* utf16_str) {
// Unless the platform encoding is UTF-8, not all characters in the source string can be represented in the dest string.
// The function succeeds in this case anyway and just replaces these with a certain character.
static errno_t convert_UTF16_to_platform(LPWSTR source_utf16_str, char*& dest_str) {
const int flag_source_str_is_null_terminated = -1;
const int flag_estimate_chars_count = 0;
int chars_count_estimated = WideCharToMultiByte(CP_ACP,
0,
source_utf16_str, flag_source_str_is_null_terminated,
NULL, flag_estimate_chars_count, NULL, NULL);
if (chars_count_estimated == 0) {
const int len_estimated = WideCharToMultiByte(CP_ACP,
0,
source_utf16_str,
-1, // source is null-terminated
NULL,
0, // estimate characters count
NULL, NULL);
if (len_estimated == 0) {
dest_str = NULL;
return EINVAL;
}
dest_str = NEW_C_HEAP_ARRAY(CHAR, chars_count_estimated, mtInternal);
dest_str = NEW_C_HEAP_ARRAY(CHAR, len_estimated, mtInternal);
int chars_count_real = WideCharToMultiByte(CP_ACP,
0,
source_utf16_str, flag_source_str_is_null_terminated,
dest_str, chars_count_estimated, NULL, NULL);
assert(chars_count_real == chars_count_estimated, "length already checked above");
const int len_real = WideCharToMultiByte(CP_ACP,
0,
source_utf16_str,
-1, // source is null-terminated
dest_str, len_estimated, NULL, NULL);
assert(len_real == len_estimated, "length already checked above");
return ERROR_SUCCESS;
}
@@ -1435,7 +1438,7 @@ public:
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
// The name given is in UTF-8.
void * os::dll_load(const char *utf8_name, char *ebuf, int ebuflen) {
void * os::dll_load_utf8(const char *utf8_name, char *ebuf, int ebuflen) {
LPWSTR utf16_name = NULL;
errno_t err = convert_UTF8_to_UTF16(utf8_name, &utf16_name);
MemoryReleaserW release_utf16_name(utf16_name);
@@ -1564,6 +1567,122 @@ void * os::dll_load(const char *utf8_name, char *ebuf, int ebuflen) {
return NULL;
}
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
log_info(os)("attempting shared library load of %s", name);
void * result = LoadLibrary(name);
if (result != NULL) {
Events::log(NULL, "Loaded shared library %s", name);
// Recalculate pdb search path if a DLL was loaded successfully.
SymbolEngine::recalc_search_path();
log_info(os)("shared library load of %s was successful", name);
return result;
}
DWORD errcode = GetLastError();
// Read system error message into ebuf
// It may or may not be overwritten below (in the for loop and just above)
lasterror(ebuf, (size_t) ebuflen);
ebuf[ebuflen - 1] = '\0';
Events::log(NULL, "Loading shared library %s failed, error code %lu", name, errcode);
log_info(os)("shared library load of %s failed, error code %lu", name, errcode);
if (errcode == ERROR_MOD_NOT_FOUND) {
strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1);
ebuf[ebuflen - 1] = '\0';
return NULL;
}
// Parsing dll below
// If we can read dll-info and find that dll was built
// for an architecture other than Hotspot is running in
// - then print to buffer "DLL was built for a different architecture"
// else call os::lasterror to obtain system error message
int fd = ::open(name, O_RDONLY | O_BINARY, 0);
if (fd < 0) {
return NULL;
}
uint32_t signature_offset;
uint16_t lib_arch = 0;
bool failed_to_get_lib_arch =
( // Go to position 3c in the dll
(os::seek_to_file_offset(fd, IMAGE_FILE_PTR_TO_SIGNATURE) < 0)
||
// Read location of signature
(sizeof(signature_offset) !=
(os::read(fd, (void*)&signature_offset, sizeof(signature_offset))))
||
// Go to COFF File Header in dll
// that is located after "signature" (4 bytes long)
(os::seek_to_file_offset(fd,
signature_offset + IMAGE_FILE_SIGNATURE_LENGTH) < 0)
||
// Read field that contains code of architecture
// that dll was built for
(sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch))))
);
::close(fd);
if (failed_to_get_lib_arch) {
// file i/o error - report os::lasterror(...) msg
return NULL;
}
typedef struct {
uint16_t arch_code;
char* arch_name;
} arch_t;
static const arch_t arch_array[] = {
{IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},
{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}
};
#if (defined _M_AMD64)
static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64;
#elif (defined _M_IX86)
static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386;
#else
#error Method os::dll_load requires that one of following \
is defined :_M_AMD64 or _M_IX86
#endif
// Obtain a string for printf operation
// lib_arch_str shall contain string what platform this .dll was built for
// running_arch_str shall string contain what platform Hotspot was built for
char *running_arch_str = NULL, *lib_arch_str = NULL;
for (unsigned int i = 0; i < ARRAY_SIZE(arch_array); i++) {
if (lib_arch == arch_array[i].arch_code) {
lib_arch_str = arch_array[i].arch_name;
}
if (running_arch == arch_array[i].arch_code) {
running_arch_str = arch_array[i].arch_name;
}
}
assert(running_arch_str,
"Didn't find running architecture code in arch_array");
// If the architecture is right
// but some other error took place - report os::lasterror(...) msg
if (lib_arch == running_arch) {
return NULL;
}
if (lib_arch_str != NULL) {
::_snprintf(ebuf, ebuflen - 1,
"Can't load %s-bit .dll on a %s-bit platform",
lib_arch_str, running_arch_str);
} else {
// don't know what architecture this dll was build for
::_snprintf(ebuf, ebuflen - 1,
"Can't load this .dll (machine code=0x%x) on a %s-bit platform",
lib_arch, running_arch_str);
}
return NULL;
}
void os::print_dll_info(outputStream *st) {
st->print_cr("Dynamic libraries:");
get_loaded_modules_info(_print_module, (void *)st);

View File

@@ -4810,6 +4810,30 @@ bool Compile::randomized_select(int count) {
return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count);
}
Node* Compile::narrow_value(BasicType bt, Node* value, const Type* type, PhaseGVN* phase, bool transform_res) {
if (type != NULL && phase->type(value)->higher_equal(type)) {
return value;
}
Node* result = NULL;
if (bt == T_BYTE) {
result = phase->transform(new LShiftINode(value, phase->intcon(24)));
result = new RShiftINode(result, phase->intcon(24));
} else if (bt == T_BOOLEAN) {
result = new AndINode(value, phase->intcon(0xFF));
} else if (bt == T_CHAR) {
result = new AndINode(value,phase->intcon(0xFFFF));
} else {
assert(bt == T_SHORT, "unexpected narrow type");
result = phase->transform(new LShiftINode(value, phase->intcon(16)));
result = new RShiftINode(result, phase->intcon(16));
}
if (transform_res) {
result = phase->transform(result);
}
return result;
}
CloneMap& Compile::clone_map() { return _clone_map; }
void Compile::set_clone_map(Dict* d) { _clone_map._dict = d; }

View File

@@ -1380,6 +1380,7 @@ class Compile : public Phase {
#ifdef ASSERT
bool _type_verify_symmetry;
#endif
static Node* narrow_value(BasicType bt, Node* value, const Type* type, PhaseGVN* phase, bool transform_res);
};
#endif // SHARE_VM_OPTO_COMPILE_HPP

View File

@@ -462,16 +462,17 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
if (val == mem) {
values.at_put(j, mem);
} else if (val->is_Store()) {
#if INCLUDE_SHENANDOAHGC
Node* n = val->in(MemNode::ValueIn);
#if INCLUDE_SHENANDOAHGC
if (UseShenandoahGC) {
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
n = bs->step_over_gc_barrier(n);
}
values.at_put(j, n);
#else
values.at_put(j, val->in(MemNode::ValueIn));
#endif
if (is_subword_type(ft)) {
n = Compile::narrow_value(ft, n, phi_type, &_igvn, true);
}
values.at_put(j, n);
} else if(val->is_Proj() && val->in(0) == alloc) {
values.at_put(j, _igvn.zerocon(ft));
} else if (val->is_Phi()) {

View File

@@ -1995,12 +1995,14 @@ uint LoadNode::match_edge(uint idx) const {
// with the value stored truncated to a byte. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) ) {
Node *result = phase->transform( new LShiftINode(value, phase->intcon(24)) );
return new RShiftINode(result, phase->intcon(24));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_BYTE, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
@@ -2030,8 +2032,12 @@ const Type* LoadBNode::Value(PhaseGVN* phase) const {
Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem, phase);
if (value && !phase->type(value)->higher_equal(_type))
return new AndINode(value, phase->intcon(0xFF));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_BOOLEAN, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
}
@@ -2057,11 +2063,15 @@ const Type* LoadUBNode::Value(PhaseGVN* phase) const {
// with the value stored truncated to a char. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadUSNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) )
return new AndINode(value,phase->intcon(0xFFFF));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_CHAR, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
}
@@ -2087,12 +2097,14 @@ const Type* LoadUSNode::Value(PhaseGVN* phase) const {
// with the value stored truncated to a short. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadSNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) ) {
Node *result = phase->transform( new LShiftINode(value, phase->intcon(16)) );
return new RShiftINode(result, phase->intcon(16));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_SHORT, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);

View File

@@ -2618,19 +2618,18 @@ void Parse::do_one_bytecode() {
case Bytecodes::_i2b:
// Sign extend
a = pop();
a = _gvn.transform( new LShiftINode(a,_gvn.intcon(24)) );
a = _gvn.transform( new RShiftINode(a,_gvn.intcon(24)) );
push( a );
a = Compile::narrow_value(T_BYTE, a, NULL, &_gvn, true);
push(a);
break;
case Bytecodes::_i2s:
a = pop();
a = _gvn.transform( new LShiftINode(a,_gvn.intcon(16)) );
a = _gvn.transform( new RShiftINode(a,_gvn.intcon(16)) );
push( a );
a = Compile::narrow_value(T_SHORT, a, NULL, &_gvn, true);
push(a);
break;
case Bytecodes::_i2c:
a = pop();
push( _gvn.transform( new AndINode(a,_gvn.intcon(0xFFFF)) ) );
a = Compile::narrow_value(T_CHAR, a, NULL, &_gvn, true);
push(a);
break;
case Bytecodes::_i2f:

View File

@@ -1227,7 +1227,7 @@ JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID,
HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
jobject obj = NULL;
DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
instanceOop i = alloc_object(clazz, CHECK_NULL);
obj = JNIHandles::make_local(env, i);

View File

@@ -3451,7 +3451,7 @@ JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))
{
ThreadToNativeFromVM ttnfvm(thread);
Thread::WXWriteVerifier wx_write;
load_result = os::dll_load(name, ebuf, sizeof ebuf);
load_result = os::dll_load_utf8(name, ebuf, sizeof ebuf);
}
if (load_result == NULL) {
char msg[1024];

View File

@@ -646,6 +646,7 @@ class os: AllStatic {
// same architecture as HotSpot is running on
// in case of an error NULL is returned and an error message is stored in ebuf
static void* dll_load(const char *name, char *ebuf, int ebuflen);
static void* dll_load_utf8(const char *name, char *ebuf, int ebuflen);
// lookup symbol in a shared library
static void* dll_lookup(void* handle, const char* name);

View File

@@ -346,15 +346,15 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load0
if (!initIDs(env))
return JNI_FALSE;
char cname_buf[128];
char * cname = getUTF(env, name, cname_buf, sizeof(cname_buf));
if (cname == 0)
return JNI_FALSE;
handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname);
const char * utf8_name = GetStringUTF8Chars(env, name);
if (utf8_name == NULL)
return JNI_FALSE;
handle = isBuiltin ? procHandle : JVM_LoadLibrary(utf8_name);
if (handle) {
JNI_OnLoad_t JNI_OnLoad;
// TODO:
JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle,
isBuiltin ? cname : NULL,
isBuiltin ? utf8_name: NULL,
JNI_TRUE);
if (JNI_OnLoad) {
JavaVM *jvm;
@@ -379,7 +379,7 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load0
char msg[256];
jio_snprintf(msg, sizeof(msg),
"unsupported JNI version 0x%08X required by %s",
jniVersion, cname);
jniVersion, utf8_name);
JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg);
if (!isBuiltin) {
JVM_UnloadLibrary(handle);
@@ -400,9 +400,7 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load0
loaded = JNI_TRUE;
done:
if (cname != NULL && cname != cname_buf) {
free(cname);
}
ReleaseStringUTF8Chars(env, name, utf8_name);
return loaded;
}

View File

@@ -693,8 +693,8 @@ static jmethodID String_getBytes_ID; /* String.getBytes(enc) */
static jfieldID String_coder_ID; /* String.coder */
static jfieldID String_value_ID; /* String.value */
static jboolean isJNUEncodingSupported = JNI_FALSE;
static jboolean jnuEncodingSupported(JNIEnv *env) {
static jboolean isJNUEncodingSupported = JNI_FALSE;
jboolean exe;
if (isJNUEncodingSupported == JNI_TRUE) {
return JNI_TRUE;
@@ -875,14 +875,37 @@ GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
return JNU_GetStringPlatformChars(env, jstr, isCopy);
}
static const char* getStringBytes(JNIEnv *env, jstring jstr) {
static inline jstring getUTF8String(JNIEnv *env) {
static jstring utf8Str = NULL; /* Java String "UTF-8" */
if (utf8Str == NULL) {
jstring utf8TempStr = (*env)->NewStringUTF(env, "UTF-8");
if (utf8TempStr == NULL) {
return NULL;
}
utf8Str = (jstring)(*env)->NewGlobalRef(env, utf8TempStr);
(*env)->DeleteLocalRef(env, utf8TempStr);
}
return utf8Str;
}
/* Convert the given Java string into a null-terminated byte sequence according
* to the platform encoding (if needUTF8 is false) or to UTF-8 encoding (if
* needUTF8 is true).
*/
static const char* getStringBytes(JNIEnv *env, jstring jstr, jboolean needUTF8) {
char *result = NULL;
jbyteArray hab = 0;
if ((*env)->EnsureLocalCapacity(env, 2) < 0)
return 0;
if (jnuEncodingSupported(env)) {
if (needUTF8) {
if (getUTF8String(env) == NULL)
return NULL;
hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, getUTF8String(env));
} else if (!needUTF8 && jnuEncodingSupported(env)) {
hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
} else {
jmethodID mid;
@@ -923,7 +946,8 @@ getStringUTF8(JNIEnv *env, jstring jstr)
int ri;
jbyte coder = (*env)->GetByteField(env, jstr, String_coder_ID);
if (coder != java_lang_String_LATIN1) {
return getStringBytes(env, jstr);
const jboolean forceUTF8 = (fastEncoding != FAST_UTF_8);
return getStringBytes(env, jstr, forceUTF8);
}
if ((*env)->EnsureLocalCapacity(env, 2) < 0) {
return NULL;
@@ -966,6 +990,18 @@ getStringUTF8(JNIEnv *env, jstring jstr)
return result;
}
JNIEXPORT const char *
GetStringUTF8Chars(JNIEnv *env, jstring jstr)
{
return getStringUTF8(env, jstr);
}
JNIEXPORT void
ReleaseStringUTF8Chars(JNIEnv* env, jstring jstr, const char *str)
{
free((void *)str);
}
JNIEXPORT const char * JNICALL
JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
{
@@ -985,7 +1021,7 @@ JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
JNU_ThrowInternalError(env, "platform encoding not initialized");
return 0;
} else
return getStringBytes(env, jstr);
return getStringBytes(env, jstr, JNI_FALSE /* Need platform encoding */);
}
JNIEXPORT void JNICALL

View File

@@ -126,6 +126,13 @@ NewStringPlatform(JNIEnv *env, const char *str);
JNIEXPORT const char *
GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
/* Convert the Java string to UTF-8 (not "modified UTF-8") */
JNIEXPORT const char *
GetStringUTF8Chars(JNIEnv *env, jstring jstr);
JNIEXPORT void
ReleaseStringUTF8Chars(JNIEnv* env, jstring jstr, const char *str);
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str);

View File

@@ -424,4 +424,19 @@ public class Application {
((CPlatformWindow)platformWindow).toggleFullScreen();
}
public void requestEnterFullScreen(final Window window) {
final Object peer = AWTAccessor.getComponentAccessor().getPeer(window);
if (!(peer instanceof LWWindowPeer)) return;
Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow();
if (!(platformWindow instanceof CPlatformWindow)) return;
((CPlatformWindow)platformWindow).enterFullScreen();
}
public void requestLeaveFullScreen(final Window window) {
final Object peer = AWTAccessor.getComponentAccessor().getPeer(window);
if (!(peer instanceof LWWindowPeer)) return;
Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow();
if (!(platformWindow instanceof CPlatformWindow)) return;
((CPlatformWindow)platformWindow).leaveFullScreen();
}
}

View File

@@ -67,8 +67,10 @@ final class FullScreenHandler {
}
static FullScreenHandler getHandlerFor(final RootPaneContainer window) {
final Object value = window.getRootPane().getClientProperty(CLIENT_PROPERTY);
if (value instanceof FullScreenHandler) return (FullScreenHandler)value;
if (window != null && window.getRootPane() != null) {
final Object value = window.getRootPane().getClientProperty(CLIENT_PROPERTY);
if (value instanceof FullScreenHandler) return (FullScreenHandler)value;
}
return null;
}

View File

@@ -369,15 +369,20 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
}
AWTToolkit.latestPerformKeyEquivalentEvent = event;
NSUInteger modFlags = [event modifierFlags] &
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
// Workaround for JBR-3544
// When tabbing mode is on, macOS sends "Ctrl N" and "Cmd N" when "Ctrl Opt N" and "Cmd Opt N" are pressed
if ([event keyCode] == 45 && ((modFlags == NSControlKeyMask) || (modFlags == NSCommandKeyMask))) {
return NO;
}
// if IM is active key events should be ignored
if (![self hasMarkedText] && !fInPressAndHold) {
[self deliverJavaKeyEventHelper: event];
}
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
// because Cocoa calls performKeyEquivalent twice for these keystrokes
NSUInteger modFlags = [event modifierFlags] &
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
if (modFlags == NSCommandKeyMask) {
NSString *eventChars = [event charactersIgnoringModifiers];
if ([eventChars length] == 1) {
@@ -785,7 +790,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (id)getAxData:(JNIEnv*)env
{
jobject jcomponent = [self awtComponent:env];
id ax = [[[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] platformAxElement] autorelease];
id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
(*env)->DeleteLocalRef(env, jcomponent);
return ax;
}
@@ -882,7 +887,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
NSString *selectedText = [self accessibleSelectedText];
NSString *selectedText = [self accessibilitySelectedText];
if (selectedText) return self;
}
@@ -895,7 +900,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
if ([types containsObject:NSStringPboardType])
{
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
return [pboard setString:[self accessibilitySelectedText] forType:NSStringPboardType];
}
if ([types containsObject:NSRTFDPboardType])

View File

@@ -5,6 +5,3 @@
@interface JavaCellAccessibility : JavaComponentAccessibility
@end
@interface PlatformAxCell : PlatformAxElement
@end

View File

@@ -5,13 +5,7 @@
@implementation JavaCellAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxCell";
}
@end
@implementation PlatformAxCell
// NSAccessibilityElement protocol methods
- (NSAccessibilityRole)accessibilityRole {
return NSAccessibilityCellRole;;
@@ -20,15 +14,15 @@
- (NSArray *)accessibilityChildren {
NSArray *children = [super accessibilityChildren];
if (children == NULL) {
NSString *javaRole = [[self javaComponent] javaRole];
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:[self javaComponent]
accessible:[[self javaComponent] accessible]
NSString *javaRole = [self javaRole];
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:self
accessible:self->fAccessible
role:javaRole
index:[[self javaComponent] index]
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:[[self javaComponent] view]
withView:self->fView
isWrapped:YES];
return [NSArray arrayWithObject:newChild.platformAxElement];
return [NSArray arrayWithObject:newChild];
} else {
return children;
}

View File

@@ -3,10 +3,8 @@
#import "JavaComponentAccessibility.h"
@interface JavaColumnAccessibility : JavaComponentAccessibility
@end
@interface PlatformAxColumn : PlatformAxElement
@property(readonly) NSUInteger columnNumberInTable;
@end

View File

@@ -8,19 +8,11 @@
#import "JavaTableAccessibility.h"
#import "ThreadUtilities.h"
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
@implementation JavaColumnAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxColumn";
}
@end
@implementation PlatformAxColumn
// NSAccessibilityElement protocol methods
- (NSAccessibilityRole)accessibilityRole {
return NSAccessibilityColumnRole;
@@ -30,8 +22,9 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
NSArray *children = [super accessibilityChildren];
if (children == NULL) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
if ([[[self accessibilityParent] javaComponent] accessible] == NULL) return nil;
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaComponent] accessible], [[[self accessibilityParent] javaComponent] component], JAVA_AX_ALL_CHILDREN, NO);
JavaComponentAccessibility *parent = [self accessibilityParent];
if (parent->fAccessible == NULL) return nil;
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, JAVA_AX_ALL_CHILDREN, NO);
if (jchildrenAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
@@ -39,8 +32,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
NSUInteger childIndex = [self columnNumberInTable];
JavaColumnAccessibility *selfRow = [self javaComponent];
int inc = [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount] * 2;
int inc = [(JavaTableAccessibility *)[self accessibilityParent] accessibleColCount] * 2;
NSInteger i = childIndex * 2;
for(NSInteger i; i < arrayLen; i += inc)
{
@@ -54,13 +46,13 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
(*env)->DeleteLocalRef(env, jkey);
}
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:selfRow
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:self
withEnv:env
withAccessible:jchild
withIndex:childIndex
withView:[selfRow view]
withView:self->fView
withJavaRole:childJavaRole];
[childrenCells addObject:[child autorelease].platformAxElement];
[childrenCells addObject:[child autorelease]];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);
@@ -75,7 +67,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
}
- (NSUInteger)columnNumberInTable {
return [[self javaComponent] index];
return self->fIndex;
}
@end

View File

@@ -3,10 +3,4 @@
#import "JavaComponentAccessibility.h"
@interface JavaComboBoxAccessibility : JavaComponentAccessibility
@property(readonly) NSString *accessibleSelectedText;
@end
@interface PlatformAxComboBox : PlatformAxElement
@end

View File

@@ -12,11 +12,9 @@ static const char* ACCESSIBLE_JCOMBOBOX_NAME = "javax.swing.JComboBox$Accessible
@implementation JavaComboBoxAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxComboBox";
}
// NSAccessibilityElement protocol methods
- (NSString *)accessibleSelectedText {
- (id)accessibilityValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
if (axContext == NULL) return nil;
@@ -41,11 +39,3 @@ static const char* ACCESSIBLE_JCOMBOBOX_NAME = "javax.swing.JComboBox$Accessible
}
@end
@implementation PlatformAxComboBox
- (id)accessibilityValue {
return [(JavaComboBoxAccessibility *) [self javaComponent] accessibleSelectedText];
}
@end

View File

@@ -14,38 +14,7 @@
@class JavaComponentAccessibility;
@protocol JavaComponentProvider
@property (nonatomic, retain) JavaComponentAccessibility *javaComponent;
@end
@interface PlatformAxElement : NSAccessibilityElement <JavaComponentProvider>
// begin of NSAccessibility protocol methods
- (BOOL)isAccessibilityElement;
- (NSString *)accessibilityLabel;
- (NSArray *)accessibilityChildren;
- (NSArray *)accessibilitySelectedChildren;
- (NSRect)accessibilityFrame;
- (id)accessibilityParent;
- (BOOL)isAccessibilityEnabled;
- (id)accessibilityApplicationFocusedUIElement;
- (id)getAccessibilityWindow;
// end of NSAccessibility protocol methods
@end
@protocol PlatformAxElementProvider
@required
- (NSString *)getPlatformAxElementClassName;
@property (nonatomic, retain) PlatformAxElement *platformAxElement;
@end
@interface JavaComponentAccessibility : NSObject <PlatformAxElementProvider> {
@interface JavaComponentAccessibility : NSAccessibilityElement {
NSView *fView;
NSObject *fParent;
@@ -103,24 +72,10 @@
- (BOOL)isSelectable:(JNIEnv *)env;
- (BOOL)isVisible:(JNIEnv *)env;
- (NSSize)getSize;
- (NSRect)getBounds;
- (id)getFocusedElement;
@property(readonly) int accessibleIndexOfParent;
@property(readonly) BOOL accessibleEnabled;
@property(readwrite) BOOL accessibleFocused;
@property(readonly) NSNumber *accessibleMaxValue;
@property(readonly) NSNumber *accessibleMinValue;
@property(readonly) id accessibleOrientation;
@property(readonly) NSValue *accessiblePosition;
@property(readonly) NSString *accessibleRole;
@property(readonly) NSString *accessibleRoleDescription;
@property(readonly) id accessibleParent;
@property(readwrite, copy) NSNumber *accessibleSelected;
@property(readonly) id accessibleValue;;
@property(readonly) NSMutableDictionary *getActions;
- (id)accessibleHitTest:(NSPoint)point;
- (void)getActionsWithEnv:(JNIEnv *)env;
- (BOOL)accessiblePerformAction:(NSAccessibilityActionName)actionName;

View File

@@ -55,24 +55,6 @@ static void RaiseMustOverrideException(NSString *method)
@implementation JavaComponentAccessibility
- (NSString *)getPlatformAxElementClassName
{
return @"PlatformAxElement";
}
@synthesize platformAxElement;
- (id)init {
self = [super init];
if (self) {
NSString *className = [self getPlatformAxElementClassName];
if (className == nil) className = @"PlatformAxElement";
self.platformAxElement = [[NSClassFromString(className) alloc] init];
self.platformAxElement.javaComponent = self;
}
return self;
}
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
{
self = [self init];
@@ -138,47 +120,43 @@ static void RaiseMustOverrideException(NSString *method)
[fView release];
fView = nil;
if (self.platformAxElement != self) {
[self.platformAxElement dealloc];
}
[super dealloc];
}
- (void)postValueChanged
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilityValueChangedNotification);
NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification);
}
- (void)postSelectedTextChanged
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilitySelectedTextChangedNotification);
NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
}
- (void)postSelectionChanged
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilitySelectedChildrenChangedNotification);
NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
}
- (void)postMenuOpened
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuOpenedNotification);
NSAccessibilityPostNotification(self, (NSString *)kAXMenuOpenedNotification);
}
- (void)postMenuClosed
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuClosedNotification);
NSAccessibilityPostNotification(self, (NSString *)kAXMenuClosedNotification);
}
- (void)postMenuItemSelected
{
AWT_ASSERT_APPKIT_THREAD;
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuItemSelectedNotification);
NSAccessibilityPostNotification(self, (NSString *)kAXMenuItemSelectedNotification);
}
- (BOOL)isEqual:(id)anObject
@@ -267,7 +245,7 @@ static void RaiseMustOverrideException(NSString *method)
withAccessible:NULL
withIndex:index.unsignedIntValue
withView:[parent view]
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
withJavaRole:JavaAccessibilityIgnore]];
}
return [NSArray arrayWithArray:children];
} else if (whichChildren == JAVA_AX_ALL_CHILDREN) {
@@ -279,7 +257,7 @@ static void RaiseMustOverrideException(NSString *method)
withAccessible:NULL
withIndex:i
withView:[parent view]
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
withJavaRole:JavaAccessibilityIgnore]];
}
return [NSArray arrayWithArray:children];
} else {
@@ -288,7 +266,7 @@ static void RaiseMustOverrideException(NSString *method)
withAccessible:NULL
withIndex:whichChildren
withView:[parent view]
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
withJavaRole:JavaAccessibilityIgnore]];
}
}
if (parent->fAccessible == NULL) return nil;
@@ -330,7 +308,7 @@ static void RaiseMustOverrideException(NSString *method)
}
}
[children addObject:child.platformAxElement];
[children addObject:child];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);
@@ -498,7 +476,7 @@ static void RaiseMustOverrideException(NSString *method)
- (BOOL)isMenu
{
id role = [self accessibleRole];
NSString *role = [self accessibilityRole];
return [role isEqualToString:NSAccessibilityMenuBarRole] || [role isEqualToString:NSAccessibilityMenuRole] || [role isEqualToString:NSAccessibilityMenuItemRole];
}
@@ -541,52 +519,9 @@ static void RaiseMustOverrideException(NSString *method)
return size;
}
- (NSRect)getBounds
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
// NSAccessibility wants the bottom left point of the object in
// bottom left based screen coords
// Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
NSSize size = getAxComponentSize(env, axComponent, fComponent);
NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent);
(*env)->DeleteLocalRef(env, axComponent);
point.y += size.height;
// Now make it into Cocoa screen coords.
point.y = [[[[self view] window] screen] frame].size.height - point.y;
return NSMakeRect(point.x, point.y, size.width, size.height);
}
- (id)getFocusedElement
{
static JNF_STATIC_MEMBER_CACHE(jm_getFocusOwner, sjc_CAccessibility, "getFocusOwner", "(Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
JNIEnv *env = [ThreadUtilities getJNIEnv];
id value = nil;
NSWindow* hostWindow = [[self->fView window] retain];
jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
[hostWindow release];
if (focused != NULL) {
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
value = ((JavaComponentAccessibility *)value).platformAxElement;
}
(*env)->DeleteLocalRef(env, focused);
}
if (value == nil) {
value = [self platformAxElement];
}
#ifdef JAVA_AX_DEBUG
NSLog(@"%s: %@", __FUNCTION__, value);
#endif
return value;
}
- (jobject)accessible {
@@ -609,11 +544,8 @@ static void RaiseMustOverrideException(NSString *method)
return fNSRole;
}
- (NSUInteger)accessibilityIndexOfChild:(id)child {
if ([child isKindOfClass:[PlatformAxElement class]]) {
child = [child javaComponent];
}
- (NSUInteger)accessibilityIndexOfChild:(id)child
{
jint returnValue = JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv],
sjm_getAccessibleIndexInParent,
[child accessible],
@@ -625,257 +557,6 @@ static void RaiseMustOverrideException(NSString *method)
return (int)JNFCallStaticIntMethod ([ThreadUtilities getJNIEnv], sjm_getAccessibleIndexInParent, fAccessible, fComponent);
}
- (BOOL)accessibleEnabled {
static JNF_STATIC_MEMBER_CACHE(jm_isEnabled, sjc_CAccessibility, "isEnabled", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z");
JNIEnv* env = [ThreadUtilities getJNIEnv];
NSNumber *value = [NSNumber numberWithBool:JNFCallStaticBooleanMethod(env, jm_isEnabled, fAccessible, fComponent)]; // AWT_THREADING Safe (AWTRunLoop)
if (value == nil) {
NSLog(@"WARNING: %s called on component that has no accessible component: %@", __FUNCTION__, self);
return NO;
}
return [value boolValue];
}
- (BOOL)accessibleFocused {
JNIEnv* env = [ThreadUtilities getJNIEnv];
// According to javadoc, a component that is focusable will return true from isFocusTraversable,
// as well as having AccessibleState.FOCUSABLE in its AccessibleStateSet.
// We use the former heuristic; if the component focus-traversable, add a focused attribute
// See also initializeAttributeNamesWithEnv:
if (JNFCallStaticBooleanMethod(env, sjm_isFocusTraversable, fAccessible, fComponent)) { // AWT_THREADING Safe (AWTRunLoop)
return YES;
}
return NO;
}
- (void)setAccessibleFocused:(BOOL)accessibleFocused {
static JNF_STATIC_MEMBER_CACHE(jm_requestFocus, sjc_CAccessibility, "requestFocus", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V");
if (accessibleFocused) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
JNFCallStaticVoidMethod(env, jm_requestFocus, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
}
}
- (NSNumber *)accessibleMaxValue {
static JNF_STATIC_MEMBER_CACHE(jm_getMaximumAccessibleValue, sjc_CAccessibility, "getMaximumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
}
- (NSNumber *)accessibleMinValue {
static JNF_STATIC_MEMBER_CACHE(jm_getMinimumAccessibleValue, sjc_CAccessibility, "getMinimumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
}
- (id)accessibleOrientation {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
// cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
if (isVertical(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityVerticalOrientationValue;
}
if (isHorizontal(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityHorizontalOrientationValue;
}
(*env)->DeleteLocalRef(env, axContext);
return nil;
}
- (NSValue *)accessiblePosition {
NSRect bounds = [self getBounds];
return [NSValue valueWithPoint:NSMakePoint(bounds.origin.x, bounds.origin.y)];
}
- (NSString *)accessibleRole {
if (fNSRole == nil) {
NSString *javaRole = [self javaRole];
fNSRole = [sRoles objectForKey:javaRole];
// The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
// JComboBox behavior currently relies on this. However this is not the
// proper mapping for a JPopupMenu so fix that.
if ([[self parent] isKindOfClass:[JavaComponentAccessibility class]] &&
[javaRole isEqualToString:@"popupmenu"] &&
![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
fNSRole = NSAccessibilityMenuRole;
}
if (fNSRole == nil) {
// this component has assigned itself a custom AccessibleRole not in the sRoles array
fNSRole = javaRole;
}
[fNSRole retain];
}
return fNSRole;
}
- (NSString *)accessibleRoleDescription {
// first ask AppKit for its accessible role description for a given AXRole
NSString *value = NSAccessibilityRoleDescription([self accessibleRole], nil);
if (value == nil) {
// query java if necessary
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleRoleDisplayString, sjc_CAccessibility, "getAccessibleRoleDisplayString", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent);
if (axRole != NULL) {
value = JNFJavaToNSString(env, axRole);
(*env)->DeleteLocalRef(env, axRole);
} else {
value = @"unknown";
}
}
return value;
}
- (id)accessibleParent {
id parent = [self parent];
if ([parent isKindOfClass:[JavaComponentAccessibility class]]) {
return NSAccessibilityUnignoredAncestor(((JavaComponentAccessibility *)parent).platformAxElement);
}
return (id)fView;
}
- (NSNumber *)accessibleSelected {
return [NSNumber numberWithBool:[self isSelected:[ThreadUtilities getJNIEnv]]];
}
- (void)setAccessibleSelected:(NSNumber *)accessibleSelected {
JNIEnv* env = [ThreadUtilities getJNIEnv];
if ([self isSelectable:env]) {
static JNF_STATIC_MEMBER_CACHE( jm_requestSelection,
sjc_CAccessibility,
"requestSelection",
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;Z)V");
JNFCallStaticVoidMethod(env, jm_requestSelection, fAccessible, fComponent, [accessibleSelected boolValue]); // AWT_THREADING Safe (AWTRunLoop)
}
}
- (id)accessibleValue {
static JNF_STATIC_MEMBER_CACHE(jm_getCurrentAccessibleValue, sjc_CAccessibility, "getCurrentAccessibleValue", "(Ljavax/accessibility/AccessibleValue;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
// Need to handle popupmenus differently.
//
// At least for now don't handle combo box menus.
// This may change when later fixing issues which currently
// exist for combo boxes, but for now the following is only
// for JPopupMenus, not for combobox menus.
id parent = [self parent];
if ( [[self javaRole] isEqualToString:@"popupmenu"] &&
![[parent javaRole] isEqualToString:@"combobox"] ) {
NSArray *children =
[JavaComponentAccessibility childrenOfParent:self
withEnv:env
withChildrenCode:JAVA_AX_ALL_CHILDREN
allowIgnored:YES];
if ([children count] > 0) {
// handle case of AXMenuItem
// need to ask menu what is selected
NSArray *selectedChildrenOfMenu =
[(PlatformAxElement *)[self platformAxElement] accessibilitySelectedChildren];
JavaComponentAccessibility *selectedMenuItem =
[[selectedChildrenOfMenu objectAtIndex:0] javaComponent];
if (selectedMenuItem != nil) {
jobject itemValue =
JNFCallStaticObjectMethod( env,
sjm_getAccessibleName,
selectedMenuItem->fAccessible,
selectedMenuItem->fComponent ); // AWT_THREADING Safe (AWTRunLoop)
if (itemValue == NULL) {
return nil;
}
NSString* itemString = JNFJavaToNSString(env, itemValue);
(*env)->DeleteLocalRef(env, itemValue);
return itemString;
} else {
return nil;
}
}
}
// ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value
// a text value is taken care of in JavaTextAccessibility
// cmcnote should coalesce these calls into one java call
NSNumber *num = nil;
jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue != NULL) {
jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent);
if (str != NULL) {
num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, str);
}
(*env)->DeleteLocalRef(env, axValue);
}
if (num == nil) {
num = [NSNumber numberWithInt:0];
}
return num;
}
- (id)accessibleHitTest:(NSPoint)point {
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_Container, "java/awt/Container");
static JNF_STATIC_MEMBER_CACHE(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;");
// Make it into java screen coords
point.y = [[[[self view] window] screen] frame].size.height - point.y;
jobject jparent = fComponent;
id value = nil;
if (JNFIsInstanceOf(env, jparent, &jc_Container)) {
jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop)
if (jaccessible != NULL) {
value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
value = ((JavaComponentAccessibility *)value).platformAxElement;
(*env)->DeleteLocalRef(env, jaccessible);
}
}
if (value == nil) {
value = [self platformAxElement];
}
if (![value isAccessibilityElement]) {
value = NSAccessibilityUnignoredAncestor(value);
}
#ifdef JAVA_AX_DEBUG
NSLog(@"%s: %@", __FUNCTION__, value);
#endif
return value;
}
- (void)getActionsWithEnv:(JNIEnv *)env {
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleAction, sjc_CAccessibility, "getAccessibleAction", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;");
@@ -935,11 +616,7 @@ static void RaiseMustOverrideException(NSString *method)
return [NSArray arrayWithArray:fActionSElectors];
}
@end
@implementation PlatformAxElement
@synthesize javaComponent;
// NSAccessibilityElement protocol methods
- (BOOL)isAccessibilityElement
{
@@ -950,7 +627,7 @@ static void RaiseMustOverrideException(NSString *method)
{
// RaiseMustOverrideException(@"accessibilityLabel");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, [[self javaComponent] accessible], [[self javaComponent] component]);
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, self->fAccessible, self->fComponent);
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
@@ -959,7 +636,7 @@ static void RaiseMustOverrideException(NSString *method)
- (NSString *)accessibilityHelp {
// RaiseMustOverrideException(@"accessibilityLabel");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, [[self javaComponent] accessible], [[self javaComponent] component]);
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, self->fAccessible, self->fComponent);
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
@@ -968,7 +645,7 @@ static void RaiseMustOverrideException(NSString *method)
- (NSArray *)accessibilityChildren
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self.javaComponent
NSArray *children = [JavaComponentAccessibility childrenOfParent:self
withEnv:env
withChildrenCode:JAVA_AX_ALL_CHILDREN
allowIgnored:([[self accessibilityRole] isEqualToString:NSAccessibilityListRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityTableRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole])
@@ -982,7 +659,7 @@ static void RaiseMustOverrideException(NSString *method)
- (NSArray *)accessibilitySelectedChildren
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *selectedChildren = [JavaComponentAccessibility childrenOfParent:self.javaComponent
NSArray *selectedChildren = [JavaComponentAccessibility childrenOfParent:self
withEnv:env
withChildrenCode:JAVA_AX_SELECTED_CHILDREN
allowIgnored:([[self accessibilityRole] isEqualToString:NSAccessibilityListRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityTableRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole])
@@ -995,7 +672,7 @@ static void RaiseMustOverrideException(NSString *method)
- (NSArray *)accessibilityVisibleChildren {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self.javaComponent
NSArray *children = [JavaComponentAccessibility childrenOfParent:self
withEnv:env
withChildrenCode:JAVA_AX_VISIBLE_CHILDREN
allowIgnored:([[self accessibilityRole] isEqualToString:NSAccessibilityListRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityTableRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole])
@@ -1008,117 +685,360 @@ static void RaiseMustOverrideException(NSString *method)
- (NSRect)accessibilityFrame
{
return [self.javaComponent getBounds];
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
// NSAccessibility wants the bottom left point of the object in
// bottom left based screen coords
// Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
NSSize size = getAxComponentSize(env, axComponent, fComponent);
NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent);
(*env)->DeleteLocalRef(env, axComponent);
point.y += size.height;
// Now make it into Cocoa screen coords.
point.y = [[[[self view] window] screen] frame].size.height - point.y;
return NSMakeRect(point.x, point.y, size.width, size.height);
}
- (id)accessibilityParent
{
return [(JavaComponentAccessibility *) [self javaComponent] accessibleParent];
id parent = [self parent];
if ([parent isKindOfClass:[JavaComponentAccessibility class]]) {
return NSAccessibilityUnignoredAncestor(((JavaComponentAccessibility *)parent));
}
return (id)fView;
}
- (BOOL)isAccessibilityEnabled
{
return [(JavaComponentAccessibility *) [self javaComponent] accessibleEnabled];
static JNF_STATIC_MEMBER_CACHE(jm_isEnabled, sjc_CAccessibility, "isEnabled", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z");
JNIEnv* env = [ThreadUtilities getJNIEnv];
NSNumber *value = [NSNumber numberWithBool:JNFCallStaticBooleanMethod(env, jm_isEnabled, fAccessible, fComponent)]; // AWT_THREADING Safe (AWTRunLoop)
if (value == nil) {
NSLog(@"WARNING: %s called on component that has no accessible component: %@", __FUNCTION__, self);
return NO;
}
return [value boolValue];
}
- (id)accessibilityApplicationFocusedUIElement {
return [self.javaComponent getFocusedElement];
- (id)accessibilityApplicationFocusedUIElement
{
return [self accessibilityFocusedUIElement];
}
- (id)accessibilityWindow {
return [self.javaComponent window];
- (id)accessibilityWindow
{
return [self window];
}
- (void)setAccessibilityParent:(id)accessibilityParent {
[[self javaComponent] setParent:accessibilityParent];
- (void)setAccessibilityParent:(id)accessibilityParent
{
[self setParent:accessibilityParent];
}
- (NSUInteger)accessibilityIndexOfChild:(id)child {
return [[self javaComponent] accessibilityIndexOfChild:child];
- (NSAccessibilityRole)accessibilityRole
{
if (fNSRole == nil) {
NSString *javaRole = [self javaRole];
fNSRole = [sRoles objectForKey:javaRole];
// The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
// JComboBox behavior currently relies on this. However this is not the
// proper mapping for a JPopupMenu so fix that.
if ([[self parent] isKindOfClass:[JavaComponentAccessibility class]] &&
[javaRole isEqualToString:@"popupmenu"] &&
![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
fNSRole = NSAccessibilityMenuRole;
}
if (fNSRole == nil) {
// this component has assigned itself a custom AccessibleRole not in the sRoles array
fNSRole = javaRole;
}
[fNSRole retain];
}
return fNSRole;
}
- (NSAccessibilityRole)accessibilityRole {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleRole];
- (NSString *)accessibilityRoleDescription
{
// first ask AppKit for its accessible role description for a given AXRole
NSString *value = NSAccessibilityRoleDescription([self accessibilityRole], nil);
if (value == nil) {
// query java if necessary
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleRoleDisplayString, sjc_CAccessibility, "getAccessibleRoleDisplayString", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent);
if (axRole != NULL) {
value = JNFJavaToNSString(env, axRole);
(*env)->DeleteLocalRef(env, axRole);
} else {
value = @"unknown";
}
}
return value;
}
- (NSString *)accessibilityRoleDescription {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleRoleDescription];
- (BOOL)isAccessibilityFocused
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
// According to javadoc, a component that is focusable will return true from isFocusTraversable,
// as well as having AccessibleState.FOCUSABLE in its AccessibleStateSet.
// We use the former heuristic; if the component focus-traversable, add a focused attribute
// See also initializeAttributeNamesWithEnv:
if (JNFCallStaticBooleanMethod(env, sjm_isFocusTraversable, fAccessible, fComponent)) { // AWT_THREADING Safe (AWTRunLoop)
return YES;
}
return NO;
}
- (BOOL)isAccessibilityFocused {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleFocused];
- (void)setAccessibilityFocused:(BOOL)accessibilityFocused
{
static JNF_STATIC_MEMBER_CACHE(jm_requestFocus, sjc_CAccessibility, "requestFocus", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V");
if (accessibilityFocused) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
JNFCallStaticVoidMethod(env, jm_requestFocus, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
}
}
- (void)setAccessibilityFocused:(BOOL)accessibilityFocused {
[(JavaComponentAccessibility *) [self javaComponent] setAccessibleFocused:accessibilityFocused];
- (NSInteger)accessibilityIndex
{
return [self index];
}
- (NSInteger)accessibilityIndex {
return [[self javaComponent] index];
- (id)accessibilityMaxValue
{
static JNF_STATIC_MEMBER_CACHE(jm_getMaximumAccessibleValue, sjc_CAccessibility, "getMaximumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
}
- (id)accessibilityMaxValue {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleMaxValue];
- (id)accessibilityMinValue
{
static JNF_STATIC_MEMBER_CACHE(jm_getMinimumAccessibleValue, sjc_CAccessibility, "getMinimumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
}
- (id)accessibilityMinValue {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleMinValue];
- (NSAccessibilityOrientation)accessibilityOrientation
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
// cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
if (isVertical(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityVerticalOrientationValue;
}
if (isHorizontal(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityHorizontalOrientationValue;
}
(*env)->DeleteLocalRef(env, axContext);
return nil;
}
- (NSAccessibilityOrientation)accessibilityOrientation {
return (NSAccessibilityOrientation)[(JavaComponentAccessibility *) [self javaComponent] accessibleOrientation];
- (NSPoint)accessibilityActivationPoint
{
NSRect bounds = [self accessibilityFrame];
return NSMakePoint(bounds.origin.x, bounds.origin.y);
}
- (NSPoint)accessibilityActivationPoint {
return [[(JavaComponentAccessibility *) [self javaComponent] accessiblePosition] pointValue];
- (BOOL)isAccessibilitySelected
{
return [self isSelected:[ThreadUtilities getJNIEnv]];
}
- (BOOL)isAccessibilitySelected {
return [[(JavaComponentAccessibility *) [self javaComponent] accessibleSelected] boolValue];
- (void)setAccessibilitySelected:(BOOL)accessibilitySelected
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
if ([self isSelectable:env]) {
static JNF_STATIC_MEMBER_CACHE( jm_requestSelection,
sjc_CAccessibility,
"requestSelection",
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;Z)V");
JNFCallStaticVoidMethod(env, jm_requestSelection, fAccessible, fComponent, accessibilitySelected); // AWT_THREADING Safe (AWTRunLoop)
}
}
- (void)setAccessibilitySelected:(BOOL)accessibilitySelected {
[(JavaComponentAccessibility *) [self javaComponent] setAccessibleSelected:[NSNumber numberWithBool:accessibilitySelected]];
- (id)accessibilityValue
{
static JNF_STATIC_MEMBER_CACHE(jm_getCurrentAccessibleValue, sjc_CAccessibility, "getCurrentAccessibleValue", "(Ljavax/accessibility/AccessibleValue;Ljava/awt/Component;)Ljava/lang/Number;");
JNIEnv* env = [ThreadUtilities getJNIEnv];
// Need to handle popupmenus differently.
//
// At least for now don't handle combo box menus.
// This may change when later fixing issues which currently
// exist for combo boxes, but for now the following is only
// for JPopupMenus, not for combobox menus.
id parent = [self parent];
if ( [[self javaRole] isEqualToString:@"popupmenu"] &&
![[parent javaRole] isEqualToString:@"combobox"] ) {
NSArray *children =
[JavaComponentAccessibility childrenOfParent:self
withEnv:env
withChildrenCode:JAVA_AX_ALL_CHILDREN
allowIgnored:YES];
if ([children count] > 0) {
// handle case of AXMenuItem
// need to ask menu what is selected
NSArray *selectedChildrenOfMenu =
[self accessibilitySelectedChildren];
JavaComponentAccessibility *selectedMenuItem =
[selectedChildrenOfMenu objectAtIndex:0];
if (selectedMenuItem != nil) {
jobject itemValue =
JNFCallStaticObjectMethod( env,
sjm_getAccessibleName,
selectedMenuItem->fAccessible,
selectedMenuItem->fComponent ); // AWT_THREADING Safe (AWTRunLoop)
if (itemValue == NULL) {
return nil;
}
NSString* itemString = JNFJavaToNSString(env, itemValue);
(*env)->DeleteLocalRef(env, itemValue);
return itemString;
} else {
return nil;
}
}
}
// ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value
// a text value is taken care of in JavaTextAccessibility
// cmcnote should coalesce these calls into one java call
NSNumber *num = nil;
jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axValue != NULL) {
jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent);
if (str != NULL) {
num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, str);
}
(*env)->DeleteLocalRef(env, axValue);
}
if (num == nil) {
num = [NSNumber numberWithInt:0];
}
return num;
}
- (id)accessibilityValue {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleValue];
}
- (id)accessibilityHitTest:(NSPoint)point
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
- (id)accessibilityHitTest:(NSPoint)point {
return [(JavaComponentAccessibility *) [self javaComponent] accessibleHitTest:point];
static JNF_CLASS_CACHE(jc_Container, "java/awt/Container");
static JNF_STATIC_MEMBER_CACHE(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;");
// Make it into java screen coords
point.y = [[[[self view] window] screen] frame].size.height - point.y;
jobject jparent = fComponent;
id value = nil;
if (JNFIsInstanceOf(env, jparent, &jc_Container)) {
jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop)
if (jaccessible != NULL) {
value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
(*env)->DeleteLocalRef(env, jaccessible);
}
}
if (value == nil) {
value = self;
}
if (![value isAccessibilityElement]) {
value = NSAccessibilityUnignoredAncestor(value);
}
#ifdef JAVA_AX_DEBUG
NSLog(@"%s: %@", __FUNCTION__, value);
#endif
return value;
}
- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector {
if ([sAllActionSelectores containsObject:NSStringFromSelector(selector)] &&
![[(JavaComponentAccessibility *) [self javaComponent] actionSelectores] containsObject:NSStringFromSelector(selector)]) {
![[self actionSelectores] containsObject:NSStringFromSelector(selector)]) {
return NO;
}
return [super isAccessibilitySelectorAllowed:selector];
}
- (BOOL)accessibilityPerformPick {
return [(JavaComponentAccessibility *) [self javaComponent] accessiblePerformAction:NSAccessibilityPickAction];
return [self accessiblePerformAction:NSAccessibilityPickAction];
}
- (BOOL)accessibilityPerformPress {
return [(JavaComponentAccessibility *) [self javaComponent] accessiblePerformAction:NSAccessibilityPressAction];
return [self accessiblePerformAction:NSAccessibilityPressAction];
}
- (BOOL)accessibilityPerformShowMenu {
return [(JavaComponentAccessibility *) [self javaComponent] accessiblePerformAction:NSAccessibilityShowMenuAction];
return [self accessiblePerformAction:NSAccessibilityShowMenuAction];
}
- (BOOL)accessibilityPerformDecrement {
return [(JavaComponentAccessibility *) [self javaComponent] accessiblePerformAction:NSAccessibilityDecrementAction];
return [self accessiblePerformAction:NSAccessibilityDecrementAction];
}
- (BOOL)accessibilityPerformIncrement {
return [(JavaComponentAccessibility *) [self javaComponent] accessiblePerformAction:NSAccessibilityIncrementAction];
return [self accessiblePerformAction:NSAccessibilityIncrementAction];
}
- (id)accessibilityFocusedUIElement {
return [[self javaComponent] getFocusedElement];
static JNF_STATIC_MEMBER_CACHE(jm_getFocusOwner, sjc_CAccessibility, "getFocusOwner", "(Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
JNIEnv *env = [ThreadUtilities getJNIEnv];
id value = nil;
NSWindow* hostWindow = [[self->fView window] retain];
jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
[hostWindow release];
if (focused != NULL) {
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
}
(*env)->DeleteLocalRef(env, focused);
}
if (value == nil) {
value = self;
}
#ifdef JAVA_AX_DEBUG
NSLog(@"%s: %@", __FUNCTION__, value);
#endif
return value;
}
@end

View File

@@ -2,8 +2,5 @@
#import "JavaComponentAccessibility.h"
@interface JavaListAccessibility : JavaComponentAccessibility
@end
@interface PlatformAxList : PlatformAxElement <NSAccessibilityList>
@interface JavaListAccessibility : JavaComponentAccessibility <NSAccessibilityList>
@end

View File

@@ -6,14 +6,7 @@
@implementation JavaListAccessibility
- (NSString *)getPlatformAxElementClassName
{
return @"PlatformAxList";
}
@end
@implementation PlatformAxList
// NSAccessibilityElement protocol methods
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows {
return [self accessibilityChildren];

View File

@@ -2,8 +2,5 @@
#import "JavaComponentAccessibility.h"
@interface JavaListRowAccessibility : JavaComponentAccessibility
@end
@interface PlatformAxListRow : PlatformAxElement <NSAccessibilityRow>
@interface JavaListRowAccessibility : JavaComponentAccessibility <NSAccessibilityRow>
@end

View File

@@ -11,13 +11,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
@implementation JavaListRowAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxListRow";
}
@end
@implementation PlatformAxListRow
// NSAccessibilityElement protocol methods
- (NSAccessibilityRole)accessibilityRole {
return NSAccessibilityRowRole;;
@@ -26,14 +20,14 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
- (NSArray *)accessibilityChildren {
NSArray *children = [super accessibilityChildren];
if (children == NULL) {
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:[self javaComponent]
accessible:[[self javaComponent] accessible]
role:[[self javaComponent] javaRole]
index:[[self javaComponent] index]
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:self
accessible:self->fAccessible
role:self->fJavaRole
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:[[self javaComponent] view]
withView:self->fView
isWrapped:YES];
return [NSArray arrayWithObject:[newChild autorelease].platformAxElement];
return [NSArray arrayWithObject:[newChild autorelease]];
} else {
return children;
}

View File

@@ -2,28 +2,9 @@
#import "JavaStaticTextAccessibility.h"
@interface JavaNavigableTextAccessibility : JavaStaticTextAccessibility
@interface JavaNavigableTextAccessibility : JavaStaticTextAccessibility <NSAccessibilityNavigableStaticText>
// protocol methods
- (NSValue *)accessibleBoundsForRange:(NSRange)range;
- (NSNumber *)accessibleLineForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForLine:(NSInteger)line;
- (NSString *)accessibleStringForRange:(NSRange)range;
- (NSValue *)accessibleRangeForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForPosition:(NSPoint)point;
@property(readonly) NSString *accessibleSelectedText;
@property(readonly) NSValue *accessibleSelectedTextRange;
@property(readonly) NSNumber *accessibleNumberOfCharacters;
@property(readonly) NSNumber *accessibleInsertionPointLineNumber;
@property(readonly) BOOL accessibleIsValueSettable;
@property(readonly) BOOL accessibleIsPasswordText;
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText;
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange;
@end
@interface PlatformAxNavigableText : PlatformAxStaticText <NSAccessibilityNavigableStaticText>
@end

View File

@@ -12,11 +12,75 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
@implementation JavaNavigableTextAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxNavigableText";
- (BOOL)accessibleIsValueSettable {
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (NSString *)accessibleValue {
- (BOOL)accessibleIsPasswordText {
return [[self javaRole] isEqualToString:@"passwordtext"];
}
// NSAccessibilityElement protocol methods
- (NSRect)accessibilityFrameForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return NSMakeRect(0, 0, 0, 0);
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return NSMakeRect(0, 0, 0, 0);
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return bounds;
}
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return row;
}
- (NSRange)accessibilityRangeForLine:(NSInteger)line {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, line); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return NSRangeFromString(@"");
return [javaConvertIntArrayToNSRangeValue(env, axTextRange) rangeValue];
}
- (NSString *)accessibilityStringForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
- (id)accessibilityValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
@@ -38,80 +102,40 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
return string;
}
- (NSValue *)accessibleBoundsForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return nil;
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
NSValue *result = [NSValue valueWithRect:bounds];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return result;
- (NSAccessibilitySubrole)accessibilitySubrole {
if ([self accessibleIsPasswordText]) {
return NSAccessibilitySecureTextFieldSubrole;
}
return nil;
}
- (NSNumber *)accessibleLineForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (NSValue *)accessibleRangeForLine:(NSInteger)line {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, line); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env,axTextRange);
}
- (NSString *)accessibleStringForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
- (NSValue *)accessibleRangeForIndex:(NSInteger)index {
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
if (axTextRange == NULL) return NSRangeFromString(@"");
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
return [javaConvertIntArrayToNSRangeValue(env, axTextRange) rangeValue];
}
- (NSValue *)accessibleRangeForPosition:(NSPoint)point {
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:self.javaRole];
}
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I");
jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop)
if (charIndex == -1) return nil;
if (charIndex == -1) return NSRangeFromString(@"");
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
return [NSValue valueWithRange:range];
return range;
}
- (NSString *)accessibleSelectedText {
- (NSString *)accessibilitySelectedText {
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
@@ -121,57 +145,41 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
return str;
}
- (NSValue *)accessibleSelectedTextRange {
- (NSRange)accessibilitySelectedTextRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
if (axTextRange == NULL) return NSRangeFromString(@"");
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
return [javaConvertIntArrayToNSRangeValue(env, axTextRange) rangeValue];
}
- (NSNumber *)accessibleNumberOfCharacters {
- (NSInteger)accessibilityNumberOfCharacters {
// cmcnote: should coalesce these two calls - radr://3951923
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
NSInteger num = getAxTextCharCount(env, axText, fComponent);
(*env)->DeleteLocalRef(env, axText);
return num;
}
- (NSNumber *)accessibleInsertionPointLineNumber {
- (NSInteger)accessibilityInsertionPointLineNumber {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
return row;
}
- (BOOL)accessibleIsValueSettable {
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (BOOL)accessibleIsPasswordText {
return [[self javaRole] isEqualToString:@"passwordtext"];
}
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText {
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jstring jstringValue = JNFNSToJavaString(env, accessibilitySelectedText);
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop)
}
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange {
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange {
jint startIndex = accessibilitySelectedTextRange.location;
jint endIndex = startIndex + accessibilitySelectedTextRange.length;
@@ -180,73 +188,6 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop)
}
@end
@implementation PlatformAxNavigableText
- (NSRect)accessibilityFrameForRange:(NSRange)range {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleBoundsForRange:range] rectValue];
}
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleLineForIndex:index] integerValue];
}
- (NSRange)accessibilityRangeForLine:(NSInteger)line {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForLine:line] rangeValue];
}
- (NSString *)accessibilityStringForRange:(NSRange)range {
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleStringForRange:range];
}
- (id)accessibilityValue {
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleValue];
}
- (NSAccessibilitySubrole)accessibilitySubrole {
if ([(JavaNavigableTextAccessibility *) [self javaComponent] accessibleIsPasswordText]) {
return NSAccessibilitySecureTextFieldSubrole;
}
return nil;
}
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForIndex:index] rangeValue];
}
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:[self javaComponent].javaRole];
}
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForPosition:point] rangeValue];
}
- (NSString *)accessibilitySelectedText {
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSelectedText];
}
- (NSRange)accessibilitySelectedTextRange {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSelectedTextRange] rangeValue];
}
- (NSInteger)accessibilityNumberOfCharacters {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleNumberOfCharacters] integerValue];
}
- (NSInteger)accessibilityInsertionPointLineNumber {
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleInsertionPointLineNumber] integerValue];
}
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSetSelectedText:accessibilitySelectedText];
}
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange {
[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSetSelectedTextRange:accessibilitySelectedTextRange];
}
- (BOOL)isAccessibilityEdited {
return YES;
}

View File

@@ -4,8 +4,5 @@
// This is a tree representation. See: https://developer.apple.com/documentation/appkit/nsoutlineview
@interface JavaOutlineAccessibility : JavaListAccessibility
@end
@interface PlatformAxOutline : PlatformAxList <NSAccessibilityOutline>
@interface JavaOutlineAccessibility : JavaListAccessibility <NSAccessibilityOutline>
@end

View File

@@ -5,13 +5,7 @@
@implementation JavaOutlineAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxOutline";
}
@end
@implementation PlatformAxOutline
// NSAccessibilityElement protocol methods
- (NSString *)accessibilityLabel
{

View File

@@ -5,10 +5,6 @@
@interface JavaOutlineRowAccessibility : JavaListRowAccessibility
@property(readwrite) int accessibleLevel;
- (jobject) currentAccessibleWithENV:(JNIEnv *)env;
@end
@interface PlatformAxOutlineRow : PlatformAxListRow
@end

View File

@@ -11,59 +11,51 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessi
@implementation JavaOutlineRowAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxOutlineRow";
}
@synthesize accessibleLevel;
- (jobject) currentAccessibleWithENV:(JNIEnv *)env {
// NSAccessibilityElement protocol methods
- (NSArray *)accessibilityChildren {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject jAxContext = getAxContext(env, fAccessible, fComponent);
if (jAxContext == NULL) return nil;
JNFClassInfo clsInfo;
clsInfo.name = [JNFObjectClassName(env, getAxContext(env, fAccessible, fComponent)) UTF8String];
clsInfo.name = [JNFObjectClassName(env, jAxContext) UTF8String];
clsInfo.cls = (*env)->GetObjectClass(env, jAxContext);
JNF_MEMBER_CACHE(jm_getCurrentComponent, clsInfo, "getCurrentComponent", "()Ljava/awt/Component;");
jobject newComponent = JNFCallObjectMethod(env, jAxContext, jm_getCurrentComponent);
(*env)->DeleteLocalRef(env, jAxContext);
jobject currentAccessible = NULL;
if (newComponent != NULL) {
jobject newAccessible = JNFCallStaticObjectMethod(env, sjm_getCAccessible, newComponent);
currentAccessible = JNFCallStaticObjectMethod(env, sjm_getCAccessible, newComponent);
(*env)->DeleteLocalRef(env, newComponent);
if (newAccessible != NULL) {
return newAccessible;
} else {
return NULL;
}
} else {
return NULL;
return nil;
}
}
@end
@implementation PlatformAxOutlineRow
- (NSArray *)accessibilityChildren {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject currentAccessible = [(JavaOutlineRowAccessibility *) [self javaComponent] currentAccessibleWithENV:env];
if (currentAccessible == NULL) {
return nil;
}
JavaComponentAccessibility *currentElement = [JavaComponentAccessibility createWithAccessible:currentAccessible withEnv:env withView:[[self javaComponent] view] isCurrent:YES];
JavaComponentAccessibility *currentElement = [JavaComponentAccessibility createWithAccessible:currentAccessible withEnv:env withView:self->fView isCurrent:YES];
NSArray *children = [JavaComponentAccessibility childrenOfParent:currentElement withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] == 0) {
return [NSArray arrayWithObject:[JavaComponentAccessibility createWithParent:[self javaComponent] accessible:[[self javaComponent] accessible] role:[[self javaComponent] javaRole] index:[[self javaComponent] index] withEnv:env withView:[[self javaComponent] view] isWrapped:YES].platformAxElement];
return [NSArray arrayWithObject:[JavaComponentAccessibility createWithParent:self
accessible:self->fAccessible
role:self->fJavaRole
index:self->fIndex
withEnv:env
withView:self->fView
isWrapped:YES]];
} else {
return children;
}
}
- (NSInteger)accessibilityDisclosureLevel {
return [(JavaOutlineRowAccessibility *) [self javaComponent] accessibleLevel];
return [self accessibleLevel];
}
- (BOOL)isAccessibilityDisclosed {
return isExpanded([ThreadUtilities getJNIEnv], [[self javaComponent] axContextWithEnv:[ThreadUtilities getJNIEnv]], [[self javaComponent] component]);
return isExpanded([ThreadUtilities getJNIEnv], [self axContextWithEnv:[ThreadUtilities getJNIEnv]], self->fComponent);
}
- (NSAccessibilitySubrole)accessibilitySubrole {

View File

@@ -3,12 +3,4 @@
#import "JavaComponentAccessibility.h"
@interface JavaScrollAreaAccessibility : JavaComponentAccessibility
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleVerticalScrollBar;
@property(readonly) id accessibleHorizontalScrollBar;
@end
@interface PlatformAxScrollArea : PlatformAxElement
@end

View File

@@ -7,11 +7,9 @@
@implementation JavaScrollAreaAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxScrollArea";
}
// NSAccessibilityElement protocol methods
- (NSArray *)accessibleContents {
- (NSArray *)accessibilityContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
@@ -19,7 +17,7 @@
NSMutableArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
// The scroll bars are in the children. children less the scroll bars is the contents
for (PlatformAxElement *aElement in children) {
for (id aElement in children) {
if (![[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *) contents addObject:aElement];
@@ -29,7 +27,7 @@
return [NSArray arrayWithArray:contents];
}
- (id)accessibleVerticalScrollBar {
- (id)accessibilityVerticalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
@@ -40,7 +38,7 @@
id aElement;
while ((aElement = [enumerator nextObject])) {
if ([[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaComponent] axContextWithEnv:env];
jobject elementAxContext = [aElement axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
@@ -52,7 +50,7 @@
return nil;
}
- (id)accessibleHorizontalScrollBar {
- (id)accessibilityHorizontalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
@@ -63,7 +61,7 @@
NSEnumerator *enumerator = [children objectEnumerator];
while ((aElement = [enumerator nextObject])) {
if ([[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaComponent] axContextWithEnv:env];
jobject elementAxContext = [aElement axContextWithEnv:env];
if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
@@ -76,19 +74,3 @@
}
@end
@implementation PlatformAxScrollArea
- (NSArray *)accessibilityContents {
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleContents];
}
- (id)accessibilityVerticalScrollBar {
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleVerticalScrollBar];
}
- (id)accessibilityHorizontalScrollBar {
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleHorizontalScrollBar];
}
@end

View File

@@ -2,18 +2,11 @@
#import "JavaComponentAccessibility.h"
@interface JavaStaticTextAccessibility : JavaComponentAccessibility
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array);
@property(readonly) NSString *accessibleValue;
@property(readonly) NSValue *accessibleVisibleCharacterRange;
@end
@interface PlatformAxStaticText : PlatformAxElement <NSAccessibilityStaticText>
@interface JavaStaticTextAccessibility : JavaComponentAccessibility <NSAccessibilityStaticText>
@end

View File

@@ -12,11 +12,9 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
@implementation JavaStaticTextAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxStaticText";
}
// NSAccessibilityElement protocol methods
- (NSString *)accessibleValue {
- (id)accessibilityValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
@@ -28,23 +26,6 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
return @"";
}
- (NSValue *)accessibleVisibleCharacterRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
@end
@implementation PlatformAxStaticText
- (id)accessibilityValue {
return [(JavaStaticTextAccessibility *) [self javaComponent] accessibleValue];
}
- (NSRect)accessibilityFrame {
return [super accessibilityFrame];
}
@@ -54,7 +35,12 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
}
- (NSRange)accessibilityVisibleCharacterRange {
return [[(JavaStaticTextAccessibility *) [self javaComponent] accessibleVisibleCharacterRange] rangeValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return NSRangeFromString(@"");
return [javaConvertIntArrayToNSRangeValue(env, axTextRange) rangeValue];
}
@end

View File

@@ -10,10 +10,6 @@
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
@property(readonly) jobject tabGroup;
@property(readonly) id accessibleValue;
- (void)performPressAction;
@end
@interface PlatformAxTabButton : PlatformAxElement
@end

View File

@@ -10,10 +10,6 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
@implementation JavaTabButtonAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabButton";
}
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole {
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
@@ -36,7 +32,20 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
return fTabGroupAxContext;
}
- (id)accessibleValue {
- (void)performPressAction {
JNIEnv *env = [ThreadUtilities getJNIEnv];
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[action perform];
[action release];
}
// NSAccessibilityElement protocol methods
- (NSAccessibilitySubrole)accessibilitySubrole {
return NSAccessibilityTabButtonSubrole;
}
- (id)accessibilityValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
@@ -49,27 +58,8 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
return val;
}
- (void)performPressAction {
JNIEnv *env = [ThreadUtilities getJNIEnv];
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[action perform];
[action release];
}
@end
@implementation PlatformAxTabButton
- (NSAccessibilitySubrole)accessibilitySubrole {
return NSAccessibilityTabButtonSubrole;
}
- (id)accessibilityValue {
return [(JavaTabButtonAccessibility *) [self javaComponent] accessibleValue];
}
- (BOOL)accessibilityPerformPress {
[(JavaTabButtonAccessibility *) [self javaComponent] performPressAction];
[self performPressAction];
return YES;
}

View File

@@ -10,12 +10,6 @@
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
@property(readonly) NSArray *accessibleTabs;
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleValue;
@property(readonly) NSInteger numTabs;
@end
@interface PlatformAxTabGroup : PlatformAxElement
@end

View File

@@ -10,11 +10,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
@implementation JavaTabGroupAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabGroup";
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext {
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext {
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
@@ -26,10 +22,10 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
JavaComponentAccessibility *aTab;
NSInteger i;
for (i = 0; i < _numTabs; i++) {
aTab = [(PlatformAxElement *) [tabs objectAtIndex:i] javaComponent];
aTab = [tabs objectAtIndex:i];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return [aTab platformAxElement];
return aTab;
}
}
(*env)->DeleteLocalRef(env, selAccessible);
@@ -63,7 +59,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaComponentAccessibility *tab = [[[JavaTabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:[tab platformAxElement]];
[tabs addObject:tab];
tabIndex++;
}
(*env)->DeleteLocalRef(env, jtabsAndRoles);
@@ -72,15 +68,21 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
// Contents are the children of the selected tab.
PlatformAxElement *currentTab = [self currentTabWithEnv:env withAxContext:axContext];
JavaComponentAccessibility *currentTab = [self currentTabWithEnv:env withAxContext:axContext];
if (currentTab == nil) return nil;
NSArray *contents = [JavaComponentAccessibility childrenOfParent:[currentTab javaComponent] withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
NSArray *contents = [JavaComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
if ([contents count] <= 0) return nil;
return contents;
}
- (NSArray *)accessibleTabs {
- (NSInteger)numTabs {
return _numTabs;
}
// NSAccessibilityElement protocol methods
- (NSArray *)accessibilityTabs {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
@@ -88,7 +90,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
return tabs;
}
- (NSArray *) accessibleContents {
- (NSArray *)accessibilityContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
@@ -96,7 +98,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
return cont;
}
-(id) accessibleValue {
- (id)accessibilityValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id val = [self currentTabWithEnv:env withAxContext:axContext];
@@ -104,26 +106,6 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
return val;
}
- (NSInteger)numTabs {
return _numTabs;
}
@end
@implementation PlatformAxTabGroup
- (NSArray *)accessibilityTabs {
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleTabs];
}
- (NSArray *)accessibilityContents {
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleContents];
}
- (id)accessibilityValue {
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleValue];
}
- (NSArray *)accessibilityChildren {
//children = AXTabs + AXContents
NSArray *tabs = [self accessibilityTabs];
@@ -141,19 +123,19 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [(JavaTabGroupAccessibility *) [self javaComponent] axContextWithEnv:env];
jobject axContext = [self axContextWithEnv:env];
//children = AXTabs + AXContents
NSArray *children = [(JavaTabGroupAccessibility *) [self javaComponent] tabButtonsWithEnv:env
NSArray *children = [self tabButtonsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:index
allowIgnored:NO]; // first look at the tabs
if ([children count] > 0) {
result = children;
} else {
children= [(JavaTabGroupAccessibility *) [self javaComponent] contentsWithEnv:env
children= [self contentsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:(index-[(JavaTabGroupAccessibility *) [self javaComponent] numTabs])
withTabCode:(index-[self numTabs])
allowIgnored:NO];
if ([children count] > 0) {
result = children;
@@ -172,7 +154,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, [[self javaComponent] index], [[self javaComponent] component]);
setAxContextSelection(env, axContext, self->fIndex, self->fComponent);
(*env)->DeleteLocalRef(env, axContext);
}

View File

@@ -2,7 +2,7 @@
#import "JavaComponentAccessibility.h"
@interface JavaTableAccessibility : JavaComponentAccessibility
@interface JavaTableAccessibility : JavaComponentAccessibility <NSAccessibilityTable>
@property(readonly) int accessibleRowCount;
@property(readonly) int accessibleColCount;
@@ -13,6 +13,3 @@
- (int) accessibleColumnAtIndex:(int)index;
@end
@interface PlatformAxTable : PlatformAxElement <NSAccessibilityTable>
@end

View File

@@ -17,10 +17,6 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
@implementation JavaTableAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTable";
}
- (int)accessibleRowCount {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
@@ -132,9 +128,7 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
return isAccessibleChildSelected;
}
@end
@implementation PlatformAxTable
// NSAccessibilityElement protocol methods
- (NSArray *)accessibilityChildren {
NSArray *children = [super accessibilityChildren];
@@ -166,29 +160,29 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
}
- (nullable NSArray *)accessibilityColumns {
int colCount = [(JavaTableAccessibility *) [self javaComponent] accessibleColCount];
int colCount = [self accessibleColCount];
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:colCount];
for (int i = 0; i < colCount; i++) {
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaComponent]
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:self
withEnv:[ThreadUtilities getJNIEnv]
withAccessible:NULL
withIndex:i
withView:[[self javaComponent] view]
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
withView:self->fView
withJavaRole:JavaAccessibilityIgnore]];
}
return [NSArray arrayWithArray:columns];
}
- (nullable NSArray *)accessibilitySelectedColumns {
NSArray<NSNumber *> *indexes = [(JavaTableAccessibility *) [self javaComponent] selectedAccessibleColumns];
NSArray<NSNumber *> *indexes = [self selectedAccessibleColumns];
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:[indexes count]];
for (NSNumber *i in indexes) {
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaComponent]
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:self
withEnv:[ThreadUtilities getJNIEnv]
withAccessible:NULL
withIndex:i.unsignedIntValue
withView:[[self javaComponent] view]
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
withView:self->fView
withJavaRole:JavaAccessibilityIgnore]];
}
return [NSArray arrayWithArray:columns];
}

View File

@@ -2,10 +2,7 @@
#import "JavaComponentAccessibility.h"
@interface JavaTableRowAccessibility : JavaComponentAccessibility
@end
@interface PlatformAxTableRow : PlatformAxElement <NSAccessibilityRow>
@interface JavaTableRowAccessibility : JavaComponentAccessibility <NSAccessibilityRow>
@property(readonly) NSUInteger rowNumberInTable;

View File

@@ -12,13 +12,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
@implementation JavaTableRowAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTableRow";
}
@end
@implementation PlatformAxTableRow
// NSAccessibilityElement protocol methods
- (NSAccessibilityRole)accessibilityRole {
return NSAccessibilityRowRole;
@@ -32,17 +26,17 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
NSArray *children = [super accessibilityChildren];
if (children == NULL) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
if ([[[self accessibilityParent] javaComponent] accessible] == NULL) return nil;
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaComponent] accessible], [[[self accessibilityParent] javaComponent] component], JAVA_AX_ALL_CHILDREN, NO);
JavaComponentAccessibility *parent = [self accessibilityParent];
if (parent->fAccessible == NULL) return nil;
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, JAVA_AX_ALL_CHILDREN, NO);
if (jchildrenAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount];
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *)parent accessibleColCount];
NSInteger i = childIndex * 2;
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount] * 2;
JavaTableRowAccessibility *selfRow = [self javaComponent];
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *)parent accessibleColCount] * 2;
for(i; i < n; i+=2)
{
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
@@ -55,13 +49,13 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
(*env)->DeleteLocalRef(env, jkey);
}
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:selfRow
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:self
withEnv:env
withAccessible:jchild
withIndex:childIndex
withView:[selfRow view]
withView:self->fView
withJavaRole:childJavaRole];
[childrenCells addObject:[child autorelease].platformAxElement];
[childrenCells addObject:[child autorelease]];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);
@@ -97,7 +91,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
}
- (NSUInteger)rowNumberInTable {
return [[self javaComponent] index];
return self->fIndex;
}
- (NSRect)accessibilityFrame {

View File

@@ -210,6 +210,7 @@ public class MetalRootPaneUI extends BasicRootPaneUI
* @param parent The parent of the JRootPane
*/
private void installWindowListeners(JRootPane root, Component parent) {
if (parent == null) return;
if (parent instanceof Window) {
window = (Window)parent;
}

View File

@@ -376,8 +376,6 @@ public abstract class GraphicsPrimitive {
}
}
GraphicsPrimitiveMgr.setTraceFlags(traceflags);
if (verbose) {
System.err.print("GraphicsPrimitive logging ");
if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {

View File

@@ -68,6 +68,11 @@ public final class GraphicsPrimitiveMgr {
CustomComponent.register();
GeneralRenderer.register();
registerNativeLoops();
// Note: grab traceflags from GraphicsPrimitive rather than have GraphicsPrimitive set our flags
// in order to follow the static initialization order of these two classes. Else we run into a
// check-and-egg problem and end up with static fields not completely initialized at the time
// some primitives are constructed and these appear to have no methodSignature's.
setTraceFlags(GraphicsPrimitive.traceflags);
}
private static class PrimitiveSpec {

View File

@@ -1405,10 +1405,10 @@ OGLTR_DrawGlyphList(JNIEnv *env, OGLContext *oglc, OGLSDOps *dstOps,
jboolean ok;
GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(NEXT_LONG(images));
if (ginfo == NULL) {
if (ginfo == NULL || ginfo == (void*) -1) {
// this shouldn't happen, but if it does we'll just break out...
J2dRlsTraceLn(J2D_TRACE_ERROR,
"OGLTR_DrawGlyphList: glyph info is null");
J2dRlsTraceLn1(J2D_TRACE_ERROR,
"OGLTR_DrawGlyphList: glyph info is %d", ginfo);
break;
}

View File

@@ -37,6 +37,7 @@
#include "awt_GraphicsEnv.h"
#include <dlfcn.h>
#include <time.h>
#ifndef HEADLESS
@@ -1116,9 +1117,9 @@ X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {
}
}
static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
static XImage * X11SD_GetImageReal(JNIEnv *env, X11SDOps *xsdo,
SurfaceDataBounds *bounds,
jint lockFlags)
jint lockFlags, jboolean* usedXGetImage)
{
int x, y, w, h, maxWidth, maxHeight;
int scan;
@@ -1175,12 +1176,14 @@ static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
}
if (img == NULL) {
img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);
if (usedXGetImage != NULL) *usedXGetImage = True;
if (img != NULL) {
img->obdata = NULL;
}
}
#else
img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);
if (usedXGetImage != NULL) *usedXGetImage = True;
#endif /* MITSHM */
if (img == NULL) {
SurfaceDataBounds temp;
@@ -1280,6 +1283,177 @@ static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
return img;
}
static jboolean isDisplayLocal() {
static jboolean isLocal = True;
static jboolean isLocalSet = False;
if (!isLocalSet) {
isLocalSet = True;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jboolean sawException = JNI_FALSE;
jobject ge = JNU_CallStaticMethodByName(env, &sawException, "java/awt/GraphicsEnvironment",
"getLocalGraphicsEnvironment", "()Ljava/awt/GraphicsEnvironment;").l;
CHECK_NULL_RETURN(ge, True);
if (!sawException) {
jclass sgeCls = (*env)->FindClass(env, "sun/java2d/SunGraphicsEnvironment");
CHECK_NULL_RETURN(sgeCls, True);
if ((*env)->IsInstanceOf(env, ge, sgeCls)) {
isLocal = JNU_CallMethodByName(env, NULL, ge, "isDisplayLocal", "()Z").z;
}
}
}
return isLocal;
}
// Auxiliary data structure to keep info when faking XGetImage() calls
struct X11GetImageInfo {
unsigned long bgPixel;
};
// All the possible settings for the "remote.x11.workaround" property.
#define WORKAROUND_PROPERTY_NAME "remote.x11.workaround"
// Corresponds to property value "false" and means that the workaround will not be used at all
#define WORKAROUND_DONT_USE 0
// Corresponds to property value "true" and forces the workaround to be used even if not needed or not useful
#define WORKAROUND_USE 1
// This is the default setting and is used when the property wasn't specified or is neither "true" nor "false".
// Enables the workaround only when XGetImage() calls become "slow", but once enabled, never switches
// the workaround off.
#define WORKAROUND_AUTO 2
// Returns one of WORKAROUND_... values based on "remote.x11.workaround" VM property.
// The default is WORKAROUND_AUTO.
static int getRemoteX11WorkaroundProperty() {
int ret = WORKAROUND_AUTO;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jstring name = (*env)->NewStringUTF(env, WORKAROUND_PROPERTY_NAME);
CHECK_NULL_RETURN(name, ret);
jstring jPropValue = JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "getProperty",
"(Ljava/lang/String;)Ljava/lang/String;", name).l;
if (jPropValue != NULL) {
const char * utf8string = (*env)->GetStringUTFChars(env, jPropValue, NULL);
if (utf8string != NULL) {
if (strcmp(utf8string, "true") == 0) {
ret = WORKAROUND_USE;
} else if (strcmp(utf8string, "false") == 0){
ret = WORKAROUND_DONT_USE;
}
}
(*env)->ReleaseStringUTFChars(env, jPropValue, utf8string);
}
(*env)->DeleteLocalRef(env, name);
return ret;
}
// Verifies if the workaround for slow XGetImage() performance needs to be used based on the image given and
// the difference between start and finish times.
// Collects the information necessary for the workaround to work into the 'info' output argument.
// Returns False - use workaround, True - use real XGetImage().
static jboolean shouldUseRealGetImage(int workaroundPropertyValue,
XImage* img,
const struct timespec* timeStart,
const struct timespec* timeFinish,
struct X11GetImageInfo* info) {
static int timesCalled = 0;
if (timesCalled <= 4) {
timesCalled++;
// Skip first several calls because these aren't representative (showing the splash screen, etc).
return True;
}
// NB: local X server time varies between 0 (most of the time) and 40ms (rarely). Remote X server times naturally
// vary wildly.
const long long timeMillis = (timeFinish->tv_sec - timeStart->tv_sec)*1000
+ (timeFinish->tv_nsec - timeStart->tv_nsec)/1000000;
const jboolean considerWorkaround = (workaroundPropertyValue == WORKAROUND_USE || timeMillis > 20);
if (considerWorkaround) {
if (img != NULL && img->data != NULL && img->width > 3 && img->height > 3) {
unsigned long px1 = XGetPixel(img, 0, 0);
unsigned long px2 = XGetPixel(img, 1, 1);
unsigned long px3 = XGetPixel(img, 2, 2);
if (px1 == px2 && px2 == px3) {
// Consider this one to be a good candidate for the background pixel because a short diagonal
// of this image has the same color.
info->bgPixel = px1;
if (workaroundPropertyValue == WORKAROUND_USE) {
fprintf(stderr, "[JetBrains Runtime] Switched off alpha compositing of images because "
"-D" WORKAROUND_PROPERTY_NAME "=true was specified.\n");
} else {
fprintf(stderr, "[JetBrains Runtime] Detected slow X11, switched off alpha compositing of images. "
"Control with -D" WORKAROUND_PROPERTY_NAME "={true|false|auto}.\n");
}
return False;
}
}
}
return True;
}
// Paints every pixel of the given image with the given color.
static inline void paintImageWithColor(XImage* img, unsigned long bgColor) {
if (img != NULL && img->data != NULL) {
for(int y = 0; y < img->height; y++) {
for(int x = 0; x < img->width; x++) {
XPutPixel(img, x, y, bgColor);
}
}
}
}
// Overrides "real" X11SD_GetImage() in order to measure performance and decide whether a workaround for slow
// remote X11 is needed. In that case, routes the call to a "fake" XGetImage() that merely creates an empty image
// with a background obtained from one of the "slow", but real XGetImage() calls.
static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
SurfaceDataBounds *bounds,
jint lockFlags) {
static struct X11GetImageInfo info = { 0 };
static int workaroundPropertyValue = WORKAROUND_DONT_USE;
static jboolean useRealGetImage = True;
static jboolean isFirstTime = True;
if (isFirstTime) {
isFirstTime = False;
workaroundPropertyValue = getRemoteX11WorkaroundProperty();
if (workaroundPropertyValue != WORKAROUND_USE && isDisplayLocal()) {
// Even if we detect XGetImage() slowness, switching to a fake one will not improve the performance of a
// local X11 connection. Switch to "don't use" for the local one unless we are forced to use by
// the VM property.
workaroundPropertyValue = WORKAROUND_DONT_USE;
}
}
XImage *resImg = NULL;
if (useRealGetImage) {
struct timespec timeStart, timeFinish;
jboolean usedXGetImage = False;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeStart);
resImg = X11SD_GetImageReal(env, xsdo, bounds, lockFlags, &usedXGetImage);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeFinish);
if (workaroundPropertyValue != WORKAROUND_DONT_USE && usedXGetImage) {
useRealGetImage = shouldUseRealGetImage(workaroundPropertyValue, resImg, &timeStart, &timeFinish, &info);
}
} else {
const jint fakeLockFlags = 0; // forces creation of a new image instead of fetching it with XGetImage()
resImg = X11SD_GetImageReal(env, xsdo, bounds, fakeLockFlags, NULL);
paintImageWithColor(resImg, info.bgPixel);
}
return resImg;
}
void X11SD_DisposeOrCacheXImage(XImage * image) {
/* REMIND: might want to check if the new image worth caching. */
/* Cache only shared images. Passed image is assumed to be non-null. */

View File

@@ -1968,8 +1968,8 @@ MsgRouting AwtWindow::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
if ((m_minSize.x == 0) && (m_minSize.y == 0)) {
return r;
}
lpmmi->ptMinTrackSize.x = m_minSize.x;
lpmmi->ptMinTrackSize.y = m_minSize.y;
lpmmi->ptMinTrackSize.x = ScaleUpX(m_minSize.x);
lpmmi->ptMinTrackSize.y = ScaleUpY(m_minSize.y);
return mrConsume;
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2021, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8261812
* @summary C2 compilation fails with assert(!had_error) failed: bad dominance
*
* @run main/othervm -XX:-BackgroundCompilation TestValAtSafepointOverflowsInt
*
*/
public class TestValAtSafepointOverflowsInt {
private static volatile int volatileField;
public static void main(String[] args) {
for (int i = 0; i < 20_000; i++) {
testByte(true, false);
testByte(false, false);
testShort(true, false);
testShort(false, false);
testChar(true, false);
testChar(false, false);
}
testByte(true, true);
testShort(true, true);
testChar(true, true);
}
private static Object testByte(boolean flag, boolean flag2) {
int i;
// loop to delay constant folding
for (i = 0; i < 9; i++) {
}
C obj = new C();
if (flag) {
obj.byteField = (byte)(1 << i);
} else {
obj.byteField = (byte)(1 << (i+1));
}
// Phi for byte here for uncommon trap in never taken path below
// Phi inputs don't fit in a byte. Phi transfomed to top.
if (flag2) {
return obj;
}
return null;
}
private static Object testShort(boolean flag, boolean flag2) {
int i;
for (i = 0; i < 17; i++) {
}
C obj = new C();
if (flag) {
obj.shortField = (short)(1 << i);
} else {
obj.shortField = (short)(1 << (i+1));
}
if (flag2) {
return obj;
}
return null;
}
private static Object testChar(boolean flag, boolean flag2) {
int i;
for (i = 0; i < 17; i++) {
}
C obj = new C();
if (flag) {
obj.charField = (char)(1 << i);
} else {
obj.charField = (char)(1 << (i+1));
}
if (flag2) {
return obj;
}
return null;
}
static class C {
byte byteField;
short shortField;
char charField;
}
}

View File

@@ -1,17 +1,25 @@
/*
* Copyright 2021 JetBrains s.r.o.
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* http://www.apache.org/licenses/LICENSE-2.0
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Files;
@@ -25,19 +33,15 @@ public class LoadLibraryUnicode {
static native int giveANumber();
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-omega-\u03c9";
// Use non-Latin characters from basic (\u1889) and supplementary (\uD844\uDDD9) Unicode planes
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-supp-\uD844\uDDD9";
private static String toPlatformLibraryName(String name) {
return (Platform.isWindows() ? "" : "lib") + name + "." + Platform.sharedLibraryExt();
}
public static void verifySystemLoad() throws Exception {
String osDependentLibraryFileName = null;
if (Platform.isLinux()) {
osDependentLibraryFileName = "libLoadLibraryUnicode.so";
} else if (Platform.isOSX()) {
osDependentLibraryFileName = "libLoadLibraryUnicode.dylib";
} else if (Platform.isWindows()) {
osDependentLibraryFileName = "LoadLibraryUnicode.dll";
} else {
throw new Error("Unsupported OS");
}
final String osDependentLibraryFileName = toPlatformLibraryName("LoadLibraryUnicode");
String testNativePath = LoadLibraryUnicodeTest.getSystemProperty("test.nativepath");
Path origLibraryPath = Paths.get(testNativePath).resolve(osDependentLibraryFileName);

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2000-2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary SFNS italic font inclination on macOS
* @requires os.family == "mac"
*/
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
public class SFNSItalicTest {
/**
* 0.2 is a default inclination for italic fonts, see {@link sun.font.CFont#createStrike}
*/
private static final double TARGET_INCLINATION = 0.2;
private static final double TARGET_INCLINATION_ERROR = 0.01;
private static final char SYMBOL = 'I';
private static final Font FONT = new Font(".SFNS-Regular", Font.ITALIC, 16);
private static final int IMAGE_WIDTH = 20;
private static final int IMAGE_HEIGHT = 20;
private static final int GLYPH_X = 6;
private static final int GLYPH_Y = 16;
public static void main(String[] args) throws Exception {
BufferedImage image = createImage();
double inclination = getInclination(image);
if (inclination < TARGET_INCLINATION - TARGET_INCLINATION_ERROR ||
inclination > TARGET_INCLINATION + TARGET_INCLINATION_ERROR) {
File file = new File( "SFNS-italic.png");
ImageIO.write(image, "PNG", file);
throw new RuntimeException("Incorrect inclination. Expected: " + TARGET_INCLINATION + "+-" +
TARGET_INCLINATION_ERROR + ", Actual: " + inclination + ", see " + file);
}
}
private static BufferedImage createImage() {
BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
g.setColor(Color.white);
g.setFont(FONT);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(String.valueOf(SYMBOL), GLYPH_X, GLYPH_Y);
g.dispose();
return image;
}
private static double getInclination(BufferedImage image) {
List<Point2D> points = new ArrayList<>(IMAGE_HEIGHT);
double mx = 0, my = 0;
for (int y = 0; y < image.getHeight(); y++) {
double totalWeight = 0;
double weightedX = 0;
for (int x = 0; x < image.getWidth(); x++) {
double weight = (image.getRGB(x, y) & 0xFF) / 255.0;
weightedX += x * weight;
totalWeight += weight;
}
double x = weightedX / totalWeight;
if (Double.isFinite(x)) {
mx += x;
my += y;
points.add(new Point2D.Double(x, y));
}
}
mx /= points.size();
my /= points.size();
double xySum = 0;
double y2Sum = 0;
for (Point2D p : points) {
xySum += (p.getX() - mx) * (p.getY() - my);
y2Sum += Math.pow(p.getY() - my, 2);
}
return -xySum / y2Sum;
}
}

View File

@@ -66,6 +66,12 @@ public class TestTitledBorderLeak {
System.err.println("TOTAL_TITLEDBORDER != weakRefArrTB.size()");
}
Thread.sleep(3000);
SwingUtilities.invokeAndWait(() -> {
for (int i = 0; i < TOTAL_TITLEDBORDER; i++) {
frame[i].setVisible(false);
}
});
Thread.sleep(3000);
SwingUtilities.invokeAndWait(() -> {
for (int i = 0; i < TOTAL_TITLEDBORDER; i++) {
frame[i].dispose();

View File

@@ -6,6 +6,7 @@ import org.cef.browser.CefMessageRouter;
import org.cef.handler.CefLoadHandlerAdapter;
import org.cef.callback.CefQueryCallback;
import org.cef.handler.CefMessageRouterHandlerAdapter;
import org.cef.network.CefRequest.TransitionType;
import javax.swing.*;
import java.awt.event.WindowAdapter;
@@ -17,7 +18,6 @@ import java.util.concurrent.TimeUnit;
/**
* @test
* @key headful
* @requires (os.arch == "amd64" | os.arch == "x86_64" | (os.arch == "aarch64" & os.family == "mac"))
* @summary Regression test for JBR-2430. The test checks that JS Query is handled in 2nd opened browser.
* @run main/othervm HandleJSQueryTest
*/
@@ -32,10 +32,10 @@ public class HandleJSQueryTest {
try {
SwingUtilities.invokeLater(firstBrowser::initUI);
firstLatch.await(3, TimeUnit.SECONDS);
firstLatch.await(10, TimeUnit.SECONDS);
SwingUtilities.invokeLater(secondBrowser::initUI);
secondLatch.await(3, TimeUnit.SECONDS);
secondLatch.await(10, TimeUnit.SECONDS);
if (CefBrowserFrame.callbackCounter < 2) {
throw new RuntimeException("Test FAILED. JS Query was not handled in 2nd opened browser");
@@ -54,8 +54,8 @@ public class HandleJSQueryTest {
class CefBrowserFrame extends JFrame {
static int callbackCounter;
static int browserNumber;
static volatile int callbackCounter;
static volatile int browserNumber;
private final JBCefBrowser browser = new JBCefBrowser();
@@ -86,9 +86,13 @@ class CefBrowserFrame extends JFrame {
browser.getCefClient().addMessageRouter(msgRouter);
browser.getCefClient().addLoadHandler(new CefLoadHandlerAdapter() {
@Override
public void onLoadStart(CefBrowser browser, CefFrame frame, TransitionType transitionType) {
System.out.println("onLoadStart: Browser " + browserNumber);
}
@Override
public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) {
System.out.println("Browser " + browserNumber + " is loaded.");
System.out.println("onLoadEnd: Browser " + browserNumber);
String jsFunc = "cef_query_" + browserNumber;
String jsQuery = "window." + jsFunc + "({request: '" + jsFunc + "'});";
browser.executeJavaScript(jsQuery, "", 0);

View File

@@ -43,7 +43,7 @@ fi
curdir=$(pwd)
cd ${TESTSRC}
${TESTJAVA}/bin/javac -d ${TESTCLASSES} HandleJSQueryTest.java
${TESTJAVA}/bin/javac -d ${TESTCLASSES} JBCefApp.java JBCefBrowser.java HandleJSQueryTest.java
cd $curdir
i=0

View File

@@ -143,7 +143,6 @@ java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java
java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8203047 macosx-all,linux-all,windows-all
java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html 8073636 macosx-all
java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all,linux-all,windows-all
java/awt/FileDialog/8003399/bug8003399.java 8198334 windows-all
java/awt/FileDialog/FileDialogIconTest/FileDialogIconTest.java 8160558 windows-all
java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.html 8202882 linux-all
java/awt/FileDialog/ModalFocus/FileDialogModalFocusTest.java 8194751 linux-all,macosx-all
@@ -248,12 +247,12 @@ java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java
java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8158801,8049405 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java 8158801,8049405 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 8158801,6986109 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java 8158801 windows-all,macosx-all,linux-all
@@ -281,8 +280,6 @@ java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java
java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all,macosx-all,linux-all
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 6986109 windows-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405 macosx-all,windows-all
java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java 8049405 generic-all
java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java 8049405 generic-all
java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java 8194045 generic-all
@@ -641,6 +638,7 @@ java/awt/event/ComponentEvent/MovedResizedTwiceTest/MovedResizedTwiceTest.java
java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java 6618538 generic-all
java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all
java/awt/event/KeyEvent/CorrectTime/CorrectTime.java 6626492 generic-all
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java 8233568 macosx-all
java/awt/event/KeyEvent/DeadKey/DeadKeySystemAssertionDialog.java 8194045 generic-all
java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java 8169476 windows-all,linux-all,macosx-all
java/awt/event/KeyEvent/ExtendedModifiersTest/ExtendedModifiersTest.java 8129778 generic-all
@@ -699,9 +697,9 @@ java/awt/xembed/server/RunTestXEmbed.java
sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all
sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all
# Fedora & ArchLinux (Wayland)
# Fedora & ArchLinux (Wayland) & Ubuntu 21.04
sun/java2d/AcceleratedXORModeTest.java JBR-3167 linux-5.10.12-200.fc33.x86_64,linux-5.11.6-arch1-1
sun/java2d/ClassCastExceptionForInvalidSurface.java JBR-3167 linux-5.10.12-200.fc33.x86_64,linux-5.11.6-arch1-1
sun/java2d/ClassCastExceptionForInvalidSurface.java JBR-3167 linux-all
sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 8022403 generic-all
sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all
@@ -839,14 +837,13 @@ com/sun/nio/sctp/SctpChannel/SocketOptionTests.java
sun/security/lib/cacerts/VerifyCACerts.java 8240268 generic-all
sun/security/pkcs11/ec/TestKeyFactory.java 8026976 generic-all
sun/security/pkcs11/Secmod/AddTrustedCert.java 8180837 generic-all
sun/security/pkcs11/tls/TestKeyMaterial.java 8180837 generic-all
sun/security/pkcs11/KeyStore/SecretKeysBasic.sh 8209398 generic-all
security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all
security/infra/java/security/cert/CertPathValidator/certification/GlobalSignR6CA.java 8249176 generic-all
security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java 8237888 generic-all
security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 8243543 generic-all
security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 8263059 generic-all
security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 8248899 generic-all
############################################################################
@@ -1235,6 +1232,7 @@ tools/jlink/JLink2Test.java
tools/jlink/JLinkNegativeTest.java nobug windows-6.1 fails on Windows 7 only
tools/jlink/JLinkPluginsTest.java nobug windows-6.1 fails on Windows 7 only
tools/jlink/JLinkPostProcessingTest.java nobug windows-6.1 fails on Windows 7 only
tools/jlink/JLinkReproducibleTest.java 8258945 linux-all,macosx-all
tools/jlink/NativeTest.java nobug windows-6.1 fails on Windows 7 only
tools/jlink/basic/AllModulePath.java nobug windows-6.1 fails on Windows 7 only
tools/jlink/basic/BasicTest.java nobug windows-6.1 fails on Windows 7 only