mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-25 10:49:41 +01:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2a2572f78 | ||
|
|
7b992c7cd7 | ||
|
|
8678f41971 | ||
|
|
752c0e5a49 | ||
|
|
3ea7913eaf | ||
|
|
9b4f72ad18 | ||
|
|
d5fa37b63f | ||
|
|
6a42bb54bd | ||
|
|
3b03c698ce | ||
|
|
a56060d465 | ||
|
|
97ddad2e99 | ||
|
|
01ea54d751 | ||
|
|
cad1ad4ba1 | ||
|
|
c0be778e20 | ||
|
|
0b659fef1b | ||
|
|
e62fb2762f | ||
|
|
90fff7bb1e | ||
|
|
f117b0e8ff | ||
|
|
5a2da540da | ||
|
|
23a7dbd486 | ||
|
|
104ef7a512 | ||
|
|
55c667055e | ||
|
|
bc024f9af1 | ||
|
|
dbcbc5cf36 | ||
|
|
19aa9c5ab2 | ||
|
|
4038661a40 | ||
|
|
f3f243e15e | ||
|
|
967eca8d1d | ||
|
|
c011487364 | ||
|
|
e90312b97a | ||
|
|
3cc4c7947b | ||
|
|
92948257a6 | ||
|
|
fcd5fd2fe9 |
@@ -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 {
|
||||
|
||||
@@ -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 @@
|
||||
|
||||
@@ -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 @@
|
||||
|
||||
@@ -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
|
||||
|
||||
---
|
||||
|
||||
@@ -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 @@
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
---
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
---
|
||||
|
||||
@@ -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 ++
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 ++-
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 +-
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
---
|
||||
@@ -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
|
||||
|
||||
---
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
78
jb/project/tools/patches/dcevm/0023-Code-cleanup.patch
Normal file
78
jb/project/tools/patches/dcevm/0023-Code-cleanup.patch
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -5,6 +5,3 @@
|
||||
@interface JavaCellAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxCell : PlatformAxElement
|
||||
@end
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaColumnAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxColumn : PlatformAxElement
|
||||
|
||||
@property(readonly) NSUInteger columnNumberInTable;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,10 +3,4 @@
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaComboBoxAccessibility : JavaComponentAccessibility
|
||||
|
||||
@property(readonly) NSString *accessibleSelectedText;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxComboBox : PlatformAxElement
|
||||
@end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,8 +2,5 @@
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaListAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxList : PlatformAxElement <NSAccessibilityList>
|
||||
@interface JavaListAccessibility : JavaComponentAccessibility <NSAccessibilityList>
|
||||
@end
|
||||
|
||||
@@ -6,14 +6,7 @@
|
||||
|
||||
@implementation JavaListAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName
|
||||
{
|
||||
return @"PlatformAxList";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxList
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows {
|
||||
return [self accessibilityChildren];
|
||||
|
||||
@@ -2,8 +2,5 @@
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaListRowAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxListRow : PlatformAxElement <NSAccessibilityRow>
|
||||
@interface JavaListRowAccessibility : JavaComponentAccessibility <NSAccessibilityRow>
|
||||
@end
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,13 +5,7 @@
|
||||
|
||||
@implementation JavaOutlineAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxOutline";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxOutline
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
@interface JavaOutlineRowAccessibility : JavaListRowAccessibility
|
||||
|
||||
@property(readwrite) int accessibleLevel;
|
||||
- (jobject) currentAccessibleWithENV:(JNIEnv *)env;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxOutlineRow : PlatformAxListRow
|
||||
@end
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaTableRowAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxTableRow : PlatformAxElement <NSAccessibilityRow>
|
||||
@interface JavaTableRowAccessibility : JavaComponentAccessibility <NSAccessibilityRow>
|
||||
|
||||
@property(readonly) NSUInteger rowNumberInTable;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -376,8 +376,6 @@ public abstract class GraphicsPrimitive {
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsPrimitiveMgr.setTraceFlags(traceflags);
|
||||
|
||||
if (verbose) {
|
||||
System.err.print("GraphicsPrimitive logging ");
|
||||
if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
104
test/jdk/java/awt/font/Italic/SFNSItalicTest.java
Normal file
104
test/jdk/java/awt/font/Italic/SFNSItalicTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user