Compare commits

...

5 Commits

Author SHA1 Message Date
Vladimir Dvorak
e2b67bb46d JBR-5183 clean DCEVM code separation in standard jdk code + typo fix 2023-04-05 18:55:36 +02:00
Nikita Gubarkov
1ff4742c50 JBR-5238 Disable AwtWindow::CheckWindowDPIChange() hack on Aero Snap. 2023-04-05 16:54:19 +03:00
Vladimir Dvorak
a70ed21975 JBR-5464 Fix native method registration 2023-04-04 19:44:04 +02:00
Dmitry Batrak
4b8f93d782 JBR-5458 Exception at dialog closing
(cherry picked from commit acde759572)
2023-03-31 21:10:24 +03:00
Nikita Gubarkov
e808f12ee4 JBR-5414 Add awt.lock.fair system property for enabling fair awtLock().
(cherry picked from commit aa24f103e8446da65d65e14ea75a4cff94a1d8fa)
2023-03-30 23:30:43 +03:00
8 changed files with 127 additions and 46 deletions

View File

@@ -113,7 +113,9 @@ 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;
if (AllowEnhancedClassRedefinition) {
ciObjectFactory::_initial_arena = arena;
}
ciEnv initial(arena);
ciEnv* env = ciEnv::current();
env->_factory->init_shared_objects();

View File

@@ -4,7 +4,7 @@
*
* 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) replace old_class by new class in dictionary.
* 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

View File

@@ -716,37 +716,10 @@ 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/"))
&& cur->name()->index_of_at(0, "$$", (int) strlen("$$")) == -1) { // skip dynamic proxies
if (cur == vmClasses::ClassLoader_klass()) {
// ClassLoader.addClass method is cached in Universe, we must redefine
Universe::reinitialize_loader_addClass_method(JavaThread::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 = nullptr;
if (midx != -1) {
m = cur->methods()->at(midx);
}
if (m != nullptr && 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(),
JavaThread::current());
log_trace(redefine, class, obsolete, metadata)("Reregister natives of JDK class %s", cur->external_name());
}
if (cur == vmClasses::ClassLoader_klass()) {
// ClassLoader.addClass method is cached in Universe, we must redefine
Universe::reinitialize_loader_addClass_method(JavaThread::current());
log_trace(redefine, class, obsolete, metadata)("Reinitialize ClassLoade addClass method cache.");
}
}
}
@@ -1720,7 +1693,7 @@ void VM_EnhancedRedefineClasses::check_methods_and_mark_as_obsolete() {
// removed.
// It expects only to be used during the VM_EnhancedRedefineClasses op (a safepoint).
//
// This class is used after the new methods have been installed in "the_class".
// This class is used after the new methods have been installed in "new_class".
//
// So, for example, the following must be handled. Where 'm' is a method and
// a number followed by an underscore is a prefix.
@@ -1736,7 +1709,7 @@ void VM_EnhancedRedefineClasses::check_methods_and_mark_as_obsolete() {
//
class TransferNativeFunctionRegistration {
private:
InstanceKlass* the_class;
InstanceKlass* new_class;
int prefix_count;
char** prefixes;
@@ -1751,7 +1724,7 @@ class TransferNativeFunctionRegistration {
Symbol* signature) {
TempNewSymbol name_symbol = SymbolTable::probe(name_str, (int)name_len);
if (name_symbol != nullptr) {
Method* method = the_class->lookup_method(name_symbol, signature);
Method* method = new_class->lookup_method(name_symbol, signature);
if (method != nullptr) {
// Even if prefixed, intermediate methods must exist.
if (method->is_native()) {
@@ -1814,10 +1787,10 @@ class TransferNativeFunctionRegistration {
public:
// Construct a native method transfer processor for this class.
TransferNativeFunctionRegistration(InstanceKlass* _the_class) {
TransferNativeFunctionRegistration(InstanceKlass* _new_class) {
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
the_class = _the_class;
new_class = _new_class;
prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
}
@@ -1841,8 +1814,8 @@ class TransferNativeFunctionRegistration {
};
// Don't lose the association between a native method and its JNI function.
void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(InstanceKlass* the_class) {
TransferNativeFunctionRegistration transfer(the_class);
void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(InstanceKlass* new_class) {
TransferNativeFunctionRegistration transfer(new_class);
transfer.transfer_registrations(_deleted_methods, _deleted_methods_length);
transfer.transfer_registrations(_matching_old_methods, _matching_methods_length);
}
@@ -1981,7 +1954,7 @@ void VM_EnhancedRedefineClasses::redefine_single_class(Thread *current, Instance
_any_class_has_resolved_methods = the_class->has_resolved_methods() || _any_class_has_resolved_methods;
transfer_old_native_function_registrations(the_class);
transfer_old_native_function_registrations(new_class);
// JSR-292 support

View File

@@ -135,7 +135,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// marking methods as old and/or obsolete
void check_methods_and_mark_as_obsolete();
void transfer_old_native_function_registrations(InstanceKlass* the_class);
void transfer_old_native_function_registrations(InstanceKlass* new_class);
void redefine_single_class(Thread* current, InstanceKlass* new_class_oop);

View File

@@ -231,7 +231,9 @@ public abstract class SunToolkit extends Toolkit
* }
*/
private static final ReentrantLock AWT_LOCK = new ReentrantLock();
@SuppressWarnings("removal")
private static final ReentrantLock AWT_LOCK = new ReentrantLock(
AccessController.doPrivileged(new GetBooleanAction("awt.lock.fair")));
private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition();
public interface AwtLockListener {

View File

@@ -1731,7 +1731,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
modalBlocker = d;
if (isReparented() || ENABLE_REPARENTING_CHECK && XWM.isNonReparentingWM()) {
if (isReparented() ||
ENABLE_REPARENTING_CHECK && XWM.isNonReparentingWM() ||
!ENABLE_REPARENTING_CHECK && isMapped()) {
addToTransientFors(blockerPeer, javaToplevels);
} else {
delayedModalBlocking = true;
@@ -1742,7 +1744,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
modalBlocker = null;
if (isReparented() || ENABLE_REPARENTING_CHECK && XWM.isNonReparentingWM()) {
if (isReparented() ||
ENABLE_REPARENTING_CHECK && XWM.isNonReparentingWM() ||
!ENABLE_REPARENTING_CHECK && isMapped()) {
if (FULL_MODAL_TRANSIENTS_CHAIN || haveCommonAncestor(target, d)) {
removeFromTransientFors();
}

View File

@@ -386,6 +386,20 @@ void AwtWindow::RepositionSecurityWarning(JNIEnv *env)
MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) {
WINDOWPOS * wp = (WINDOWPOS *)windowPos;
// There's no good way to detect partial maximization (e.g. Aero Snap),
// but by inspecting SWP_* flags we can guess it and reset
// prevScaleRec to neutralize the CheckWindowDPIChange logic.
// Here are the flags, observed on Windows 11 for reference:
// Restore/maximize: SWP_NOZORDER | SWP_DRAWFRAME
// Partial Aero Snap: SWP_NOZORDER | SWP_NOREPOSITION
// DPI change (new screen): SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS
if (!(wp->flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE)) &&
prevScaleRec.screen != -1 && prevScaleRec.screen != m_screenNum) {
prevScaleRec.screen = -1;
prevScaleRec.scaleX = -1.0f;
prevScaleRec.scaleY = -1.0f;
}
// Reposition the warning window
if (IsUntrusted() && warningWindow != NULL) {
if (wp->flags & SWP_HIDEWINDOW) {
@@ -2330,7 +2344,7 @@ void AwtWindow::CheckWindowDPIChange() {
if (prevScaleRec.screen != -1 && prevScaleRec.screen != m_screenNum) {
Devices::InstanceAccess devices;
AwtWin32GraphicsDevice *device = devices->GetDevice(m_screenNum);
if (device && !::IsZoomed(GetHWnd())) {
if (device) {
if (prevScaleRec.scaleX != device->GetScaleX()
|| prevScaleRec.scaleY != device->GetScaleY()) {
RECT rect;

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2023 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* @test
* @summary Regression test for JBR-5458 Exception at dialog closing
* @key headful
*/
public class UndecoratedDialogInTransientsChain {
private static Robot robot;
private static JFrame frame;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeLater(UndecoratedDialogInTransientsChain::initUI);
robot.delay(1000);
clickAtCenter();
robot.delay(2000);
clickAtCenter();
robot.delay(1000);
if (frame.isDisplayable()) {
throw new IllegalStateException("Frame should have been closed");
}
} finally {
SwingUtilities.invokeAndWait(UndecoratedDialogInTransientsChain::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("UndecoratedDialogInTransientsChain");
JButton b1 = new JButton("Close");
b1.addActionListener(e -> frame.dispose());
frame.add(b1);
frame.setBounds(200, 200, 400, 400);
frame.setVisible(true);
JDialog d = new JDialog(frame, "Dialog", true);
JButton b2 = new JButton("Close");
b2.addActionListener(e -> {
JDialog d2 = new JDialog(frame);
d2.setUndecorated(true);
d2.setVisible(true);
robot.delay(1000); // wait for the window to be realized natively
d2.dispose();
d.dispose();
});
d.add(b2);
d.setBounds(300, 300, 200, 200);
d.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
private static void clickAtCenter() {
robot.mouseMove(400, 400);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
}