OpenJDK / jdk / jdk
changeset 55817:e95f52891ce5
Merge
author | valeriep |
---|---|
date | Thu, 25 Jul 2019 21:51:13 +0000 |
parents | 445c32471dc6 ecc6e394475f |
children | dd6d424909dc |
files | src/java.desktop/unix/native/libawt_xawt/awt/multi_font.c src/java.desktop/unix/native/libawt_xawt/awt/multi_font.h src/jdk.jsobject/share/classes/jdk/internal/netscape/javascript/spi/JSObjectProvider.java |
diffstat | 171 files changed, 3545 insertions(+), 2263 deletions(-) [+] |
line wrap: on
line diff
--- a/src/demo/share/jfc/SwingSet2/TreeDemo.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/demo/share/jfc/SwingSet2/TreeDemo.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,7 +74,7 @@ public JScrollPane createTree() { DefaultMutableTreeNode top = new DefaultMutableTreeNode(getString("TreeDemo.music")); - DefaultMutableTreeNode catagory = null ; + DefaultMutableTreeNode category = null; DefaultMutableTreeNode artist = null; DefaultMutableTreeNode record = null; @@ -94,12 +94,12 @@ char linetype = line.charAt(0); switch(linetype) { case 'C': - catagory = new DefaultMutableTreeNode(line.substring(2)); - top.add(catagory); + category = new DefaultMutableTreeNode(line.substring(2)); + top.add(category); break; case 'A': - if(catagory != null) { - catagory.add(artist = new DefaultMutableTreeNode(line.substring(2))); + if(category != null) { + category.add(artist = new DefaultMutableTreeNode(line.substring(2))); } break; case 'R':
--- a/src/demo/share/jfc/SwingSet2/resources/tree.txt Thu Jul 25 02:16:49 2019 +0000 +++ b/src/demo/share/jfc/SwingSet2/resources/tree.txt Thu Jul 25 21:51:13 2019 +0000 @@ -8,7 +8,7 @@ # A = Artist / Composer # # R = Record / Style # # S = Song Name / Composition # -# C = Catagory # +# C = Category # # # ################################################################################ C Classical @@ -195,49 +195,49 @@ A The Beatles R A Hard Day's Night S A Hard Day's Night -S I Should Have Known Better -S If I Fell -S I'm Happy Just To Dance With You -S And I Love Her -S Tell Me Why -S Can't Buy Me Love -S Any Time At All -S I'll Cry Instead -S Things We Said Today -S When I Get Home -S You Can't Do That +S I Should Have Known Better +S If I Fell +S I'm Happy Just To Dance With You +S And I Love Her +S Tell Me Why +S Can't Buy Me Love +S Any Time At All +S I'll Cry Instead +S Things We Said Today +S When I Get Home +S You Can't Do That R Beatles For Sale -S No Reply -S I'm a Loser -S Baby's In Black -S Rock And Roll Music -S I'll Follow the Sun -S Mr. Moonlight -S Kansas City/Hey Hey Hey Hey -S Eight Days a Week -S Words Of Love -S Honey Don't -S Every Little Thing -S I Don't Want To Spoil the Party -S What You're Doing -S Everybody's Trying To Be My Baby +S No Reply +S I'm a Loser +S Baby's In Black +S Rock And Roll Music +S I'll Follow the Sun +S Mr. Moonlight +S Kansas City/Hey Hey Hey Hey +S Eight Days a Week +S Words Of Love +S Honey Don't +S Every Little Thing +S I Don't Want To Spoil the Party +S What You're Doing +S Everybody's Trying To Be My Baby R Help! -S Help! -S The Night Before -S You've Got To Hide Your Love Away -S I Need You -S Another Girl -S You're Going To Lose That Girl -S Ticket To Ride -S Act Naturally -S It's Only Love -S You Like Me Too Much -S Tell Me What You See -S I've Just Seen a Face -S Yesterday -S Dizzy Miss Lizzie +S Help! +S The Night Before +S You've Got To Hide Your Love Away +S I Need You +S Another Girl +S You're Going To Lose That Girl +S Ticket To Ride +S Act Naturally +S It's Only Love +S You Like Me Too Much +S Tell Me What You See +S I've Just Seen a Face +S Yesterday +S Dizzy Miss Lizzie R Rubber Soul -S Drive My Car +S Drive My Car S Norwegian Wood S You Won't See Me S Nowhere Man @@ -245,27 +245,27 @@ S The Word S Michelle S What Goes On? -S Girl -S I'm Looking Through You -S In My Life -S Wait -S If I Needed Someone -S Run For Your Life +S Girl +S I'm Looking Through You +S In My Life +S Wait +S If I Needed Someone +S Run For Your Life R Revolver -S Taxman -S Rigby -S I'm Only Sleeping -S For You To -S Here There And Everywhere +S Taxman +S Rigby +S I'm Only Sleeping +S For You To +S Here There And Everywhere S Yellow Submarine -S She Said She Said -S Good Day Sunshine -S And Your Bird Can Sing -S For No One -S Doctor Robert -S I Want To Tell You -S Got To Get You Into My Life -S Tomorrow Never Knows +S She Said She Said +S Good Day Sunshine +S And Your Bird Can Sing +S For No One +S Doctor Robert +S I Want To Tell You +S Got To Get You Into My Life +S Tomorrow Never Knows R Sgt. Pepper's Lonely Hearts Club Band S Sgt. Pepper's Lonely Hearts Club Band S With a Little Help From My Friends @@ -554,35 +554,35 @@ S What A Life A Komeda R Plan 714 Till -S Fuego De La Vida -S Herbamore -S Som I Fjol +S Fuego De La Vida +S Herbamore +S Som I Fjol S En Spricka I Taket R Genius Of -S More Is More -S Fire -S Rocket Plane (Music On The Moon) -S Boogie Woogie/Rock 'N' Roll -S Disko -S Top Star -S Light O' My Life -S If -S Frolic -S In Orbit -S Arbogast +S More Is More +S Fire +S Rocket Plane (Music On The Moon) +S Boogie Woogie/Rock 'N' Roll +S Disko +S Top Star +S Light O' My Life +S If +S Frolic +S In Orbit +S Arbogast S New New No R What Makes It Go -S Binario -S It's Alright, Baby -S Curious -S Cul de Sac -S Living Things -S Flabbergast -S Campfire -S Happyment -S Our Hospitality -S Focus -S A Simple Formality +S Binario +S It's Alright, Baby +S Curious +S Cul de Sac +S Living Things +S Flabbergast +S Campfire +S Happyment +S Our Hospitality +S Focus +S A Simple Formality A Steve Miller Band R Circle Of Love S Heart Like A Wheel
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Jul 25 21:51:13 2019 +0000 @@ -2040,17 +2040,6 @@ bind(L_fallthrough); } -void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, - Register temp_reg, - Label& wrong_method_type) { - assert_different_registers(mtype_reg, mh_reg, temp_reg); - // Compare method type against that of the receiver. - load_heap_oop(temp_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg), mh_reg, - noreg, noreg, false, IS_NOT_NULL); - cmpd(CCR0, temp_reg, mtype_reg); - bne(CCR0, wrong_method_type); -} - RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot, Register temp_reg, int extra_slot_offset) {
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu Jul 25 21:51:13 2019 +0000 @@ -565,8 +565,6 @@ Label* L_slow_path = NULL); // Method handle support (JSR 292). - void check_method_handle_type(Register mtype_reg, Register mh_reg, Register temp_reg, Label& wrong_method_type); - RegisterOrConstant argument_offset(RegisterOrConstant arg_slot, Register temp_reg, int extra_slot_offset = 0); // Biased locking support
--- a/src/hotspot/share/asm/assembler.cpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/share/asm/assembler.cpp Thu Jul 25 21:51:13 2019 +0000 @@ -218,85 +218,6 @@ } } -struct DelayedConstant { - typedef void (*value_fn_t)(); - BasicType type; - intptr_t value; - value_fn_t value_fn; - // This limit of 20 is generous for initial uses. - // The limit needs to be large enough to store the field offsets - // into classes which do not have statically fixed layouts. - // (Initial use is for method handle object offsets.) - // Look for uses of "delayed_value" in the source code - // and make sure this number is generous enough to handle all of them. - enum { DC_LIMIT = 20 }; - static DelayedConstant delayed_constants[DC_LIMIT]; - static DelayedConstant* add(BasicType type, value_fn_t value_fn); - bool match(BasicType t, value_fn_t cfn) { - return type == t && value_fn == cfn; - } - static void update_all(); -}; - -DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT]; -// Default C structure initialization rules have the following effect here: -// = { { (BasicType)0, (intptr_t)NULL }, ... }; - -DelayedConstant* DelayedConstant::add(BasicType type, - DelayedConstant::value_fn_t cfn) { - for (int i = 0; i < DC_LIMIT; i++) { - DelayedConstant* dcon = &delayed_constants[i]; - if (dcon->match(type, cfn)) - return dcon; - if (dcon->value_fn == NULL) { - dcon->value_fn = cfn; - dcon->type = type; - return dcon; - } - } - // If this assert is hit (in pre-integration testing!) then re-evaluate - // the comment on the definition of DC_LIMIT. - guarantee(false, "too many delayed constants"); - return NULL; -} - -void DelayedConstant::update_all() { - for (int i = 0; i < DC_LIMIT; i++) { - DelayedConstant* dcon = &delayed_constants[i]; - if (dcon->value_fn != NULL && dcon->value == 0) { - typedef int (*int_fn_t)(); - typedef address (*address_fn_t)(); - switch (dcon->type) { - case T_INT: dcon->value = (intptr_t) ((int_fn_t) dcon->value_fn)(); break; - case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break; - default: break; - } - } - } -} - -RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) { - intptr_t val = (intptr_t) (*value_fn)(); - if (val != 0) return val + offset; - return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); -} -RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) { - intptr_t val = (intptr_t) (*value_fn)(); - if (val != 0) return val + offset; - return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); -} -intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) { - DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn); - return &dcon->value; -} -intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) { - DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn); - return &dcon->value; -} -void AbstractAssembler::update_delayed_values() { - DelayedConstant::update_all(); -} - void AbstractAssembler::block_comment(const char* comment) { if (sect() == CodeBuffer::SECT_INSTS) { code_section()->outer()->block_comment(offset(), comment);
--- a/src/hotspot/share/classfile/javaClasses.cpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/share/classfile/javaClasses.cpp Thu Jul 25 21:51:13 2019 +0000 @@ -4547,9 +4547,6 @@ // BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String and java_lang_Class) // earlier inside SystemDictionary::resolve_well_known_classes() BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS); - - // generated interpreter code wants to know about the offsets we just computed: - AbstractAssembler::update_delayed_values(); } #if INCLUDE_CDS
--- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp Thu Jul 25 21:51:13 2019 +0000 @@ -79,6 +79,16 @@ inline void do_oop_work(T* p); }; +class ShenandoahEvacUpdateOopStorageRootsClosure : public BasicOopIterateClosure { +private: + ShenandoahHeap* _heap; + Thread* _thread; +public: + inline ShenandoahEvacUpdateOopStorageRootsClosure(); + inline void do_oop(oop* p); + inline void do_oop(narrowOop* p); +}; + #ifdef ASSERT class ShenandoahAssertNotForwardedClosure : public OopClosure { private:
--- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp Thu Jul 25 21:51:13 2019 +0000 @@ -107,6 +107,31 @@ do_oop_work(p); } +ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsClosure() : + _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { +} + +void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + + oop obj = RawAccess<>::oop_load(p); + if (! CompressedOops::is_null(obj)) { + if (_heap->in_collection_set(obj)) { + shenandoah_assert_marked(p, obj); + oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (oopDesc::equals_raw(resolved, obj)) { + resolved = _heap->evacuate_object(obj, _thread); + } + + Atomic::cmpxchg(resolved, p, obj); + } + } +} + +void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(narrowOop* p) { + ShouldNotReachHere(); +} + #ifdef ASSERT template <class T> void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jul 25 02:16:49 2019 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jul 25 21:51:13 2019 +0000 @@ -1593,12 +1593,19 @@ void work(uint worker_id) { ShenandoahEvacOOMScope oom; - ShenandoahEvacuateUpdateRootsClosure cl; - CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong); - - _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl); - _cld_roots.cld_do(&clds); - _weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl); + { + // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration + // may race against OopStorage::release() calls. + ShenandoahEvacUpdateOopStorageRootsClosure cl; + _jni_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl); + _weak_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl); + } + + { + ShenandoahEvacuateUpdateRootsClosure cl; + CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong); + _cld_roots.cld_do(&clds); + } } };
--- a/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/SubSystem.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/SubSystem.java Thu Jul 25 21:51:13 2019 +0000 @@ -132,7 +132,7 @@ retval = Long.parseLong(strval); } catch (NumberFormatException e) { // For some properties (e.g. memory.limit_in_bytes) we may overflow the range of signed long. - // In this case, return Long.max + // In this case, return Long.MAX_VALUE BigInteger b = new BigInteger(strval); if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { return Long.MAX_VALUE;
--- a/src/java.base/macosx/native/libjava/java_props_macosx.c Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/macosx/native/libjava/java_props_macosx.c Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. 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 @@ -91,18 +91,22 @@ if (hyphenPos == NULL || // languageString contains ISO639 only, e.g., "en" languageString + langStrLen - hyphenPos == 5) { // ISO639-ScriptCode, e.g., "en-Latn" - CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), - localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding()); - char *underscorePos = strrchr(localeString, '_'); - char *region = NULL; + CFLocaleRef cflocale = CFLocaleCopyCurrent(); + if (cflocale != NULL) { + CFStringGetCString(CFLocaleGetIdentifier(cflocale), + localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding()); + char *underscorePos = strrchr(localeString, '_'); + char *region = NULL; - if (underscorePos != NULL) { - region = underscorePos + 1; - } + if (underscorePos != NULL) { + region = underscorePos + 1; + } - if (region != NULL) { - strcat(languageString, "-"); - strcat(languageString, region); + if (region != NULL) { + strcat(languageString, "-"); + strcat(languageString, region); + } + CFRelease(cflocale); } } @@ -112,12 +116,19 @@ default: { - if (!CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), - localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { + CFLocaleRef cflocale = CFLocaleCopyCurrent(); + if (cflocale != NULL) { + if (!CFStringGetCString(CFLocaleGetIdentifier(cflocale), + localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { + CFRelease(cflocale); + return NULL; + } + + retVal = localeString; + CFRelease(cflocale); + } else { return NULL; } - - retVal = localeString; } break; }
--- a/src/java.base/windows/classes/sun/nio/ch/Iocp.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/Iocp.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. 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 @@ -317,7 +317,7 @@ myGroupAndInvokeCount.resetInvokeCount(); // wait for I/O completion event - // A error here is fatal (thread will not be replaced) + // An error here is fatal (thread will not be replaced) replaceMe = false; try { getQueuedCompletionStatus(port, ioResult);
--- a/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. 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 @@ -143,7 +143,6 @@ // simulate the failure of all pending I/O operations. for (Long ov: pendingIoMap.keySet()) { PendingFuture<?,?> result = pendingIoMap.get(ov); - assert !result.isDone(); // make I/O port aware of the stale OVERLAPPED structure Iocp iocp = (Iocp)((Groupable)result.channel()).group();
--- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. 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 @@ -228,7 +228,6 @@ @Override public void run() { long overlapped = 0L; - boolean pending = false; try { begin(); @@ -242,7 +241,6 @@ overlapped); if (n == IOStatus.UNAVAILABLE) { // I/O is pending - pending = true; return; } // acquired lock immediately @@ -253,9 +251,9 @@ // lock failed or channel closed removeFromFileLockTable(fli); result.setFailure(toIOException(x)); + if (overlapped != 0L) + ioCache.remove(overlapped); } finally { - if (!pending && overlapped != 0L) - ioCache.remove(overlapped); end(); } @@ -448,13 +446,12 @@ } catch (Throwable x) { // failed to initiate read result.setFailure(toIOException(x)); + if (overlapped != 0L) + ioCache.remove(overlapped); } finally { - if (!pending) { + if (!pending) // release resources - if (overlapped != 0L) - ioCache.remove(overlapped); releaseBufferIfSubstituted(); - } end(); } @@ -628,9 +625,9 @@ result.setFailure(toIOException(x)); // release resources + releaseBufferIfSubstituted(); if (overlapped != 0L) ioCache.remove(overlapped); - releaseBufferIfSubstituted(); } finally { end();
--- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousFileChannelImpl.c Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousFileChannelImpl.c Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. 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 @@ -115,7 +115,7 @@ if (error == ERROR_IO_PENDING) { return IOS_UNAVAILABLE; } - JNU_ThrowIOExceptionWithLastError(env, "WriteFile failed"); + JNU_ThrowIOExceptionWithLastError(env, "LockFile failed"); return IOS_THROWN; } return 0;
--- a/src/java.desktop/unix/classes/sun/awt/X11/XFontPeer.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFontPeer.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. 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 @@ -22,31 +22,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package sun.awt.X11; import sun.awt.PlatformFont; -import java.awt.GraphicsEnvironment; -public class XFontPeer extends PlatformFont { +final class XFontPeer extends PlatformFont { - /* - * XLFD name for XFontSet. - */ - private String xfsname; - - static { - if (!GraphicsEnvironment.isHeadless()) { - initIDs(); - } - } - - /** - * Initialize JNI field and method IDs for fields that may be - accessed from C. - */ - private static native void initIDs(); - - public XFontPeer(String name, int style){ + XFontPeer(final String name, final int style) { super(name, style); }
--- a/src/java.desktop/unix/native/common/awt/awt_Font.c Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.desktop/unix/native/common/awt/awt_Font.c Thu Jul 25 21:51:13 2019 +0000 @@ -35,7 +35,6 @@ #include "awt_Font.h" #include "java_awt_Dimension.h" -#include "multi_font.h" #include "Disposer.h" #endif /* !HEADLESS */ #include <jni.h> @@ -436,269 +435,6 @@ return 1; } -struct FontData * -awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) -{ - /* We are going to create at most 4 outstanding local refs in this - * function. */ - if ((*env)->EnsureLocalCapacity(env, 4) < 0) { - return NULL; - } - - if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) { - JNU_CHECK_EXCEPTION_RETURN(env, NULL); - - struct FontData *fdata = NULL; - int32_t i, size; - char *fontsetname = NULL; - char *nativename = NULL; - Boolean doFree = FALSE; - jobjectArray componentFonts = NULL; - jobject peer = NULL; - jobject fontDescriptor = NULL; - jstring fontDescriptorName = NULL; - jstring charsetName = NULL; - - fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font, - fontIDs.pData); - - if (fdata != NULL && fdata->flist != NULL) { - return fdata; - } - size = (*env)->GetIntField(env, font, fontIDs.size); - fdata = (struct FontData *) malloc(sizeof(struct FontData)); - - peer = (*env)->CallObjectMethod(env, font, fontIDs.getPeer); - - componentFonts = - (*env)->GetObjectField(env, peer, platformFontIDs.componentFonts); - /* We no longer need peer */ - (*env)->DeleteLocalRef(env, peer); - - fdata->charset_num = (*env)->GetArrayLength(env, componentFonts); - - fdata->flist = (awtFontList *) malloc(sizeof(awtFontList) - * fdata->charset_num); - fdata->xfont = NULL; - for (i = 0; i < fdata->charset_num; i++) { - /* - * set xlfd name - */ - - fontDescriptor = (*env)->GetObjectArrayElement(env, componentFonts, i); - fontDescriptorName = - (*env)->GetObjectField(env, fontDescriptor, - fontDescriptorIDs.nativeName); - - if (!JNU_IsNull(env, fontDescriptorName)) { - nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL); - if (nativename == NULL) { - nativename = ""; - doFree = FALSE; - } else { - doFree = TRUE; - } - } else { - nativename = ""; - doFree = FALSE; - } - - fdata->flist[i].xlfd = malloc(strlen(nativename) - + strlen(defaultXLFD)); - jio_snprintf(fdata->flist[i].xlfd, strlen(nativename) + 10, - nativename, size * 10); - - if (nativename != NULL && doFree) - JNU_ReleaseStringPlatformChars(env, fontDescriptorName, (const char *) nativename); - - /* - * set charset_name - */ - - charsetName = - (*env)->GetObjectField(env, fontDescriptor, - fontDescriptorIDs.charsetName); - - fdata->flist[i].charset_name = (char *) - JNU_GetStringPlatformChars(env, charsetName, NULL); - if (fdata->flist[i].charset_name == NULL) { - (*env)->ExceptionClear(env); - JNU_ThrowOutOfMemoryError(env, "Could not create charset name"); - return NULL; - } - - /* We are done with the objects. */ - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, fontDescriptorName); - (*env)->DeleteLocalRef(env, charsetName); - - /* - * set load & XFontStruct - */ - fdata->flist[i].load = 0; - - /* - * This appears to be a bogus check. The actual intent appears - * to be to find out whether this is the "base" font in a set, - * rather than iso8859_1 explicitly. Note that iso8859_15 will - * and must also pass this test. - */ - - if (fdata->xfont == NULL && - strstr(fdata->flist[i].charset_name, "8859_1")) { - fdata->flist[i].xfont = - loadFont(awt_display, fdata->flist[i].xlfd, size * 10); - if (fdata->flist[i].xfont != NULL) { - fdata->flist[i].load = 1; - fdata->xfont = fdata->flist[i].xfont; - fdata->flist[i].index_length = 1; - } else { - /* Free any already allocated storage and fonts */ - int j = i; - for (j = 0; j <= i; j++) { - free((void *)fdata->flist[j].xlfd); - JNU_ReleaseStringPlatformChars(env, NULL, - fdata->flist[j].charset_name); - if (fdata->flist[j].load) { - XFreeFont(awt_display, fdata->flist[j].xfont); - } - } - free((void *)fdata->flist); - free((void *)fdata); - - if (errmsg != NULL) { - *errmsg = "java/lang" "NullPointerException"; - } - (*env)->DeleteLocalRef(env, componentFonts); - return NULL; - } - } - } - (*env)->DeleteLocalRef(env, componentFonts); - /* - * XFontSet will create if the peer of TextField/TextArea - * are used. - */ - fdata->xfs = NULL; - - JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata); - Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata)); - return fdata; - } else { - JNU_CHECK_EXCEPTION_RETURN(env, NULL); - Display *display = NULL; - struct FontData *fdata = NULL; - char fontSpec[1024]; - int32_t height; - int32_t oheight; - int32_t above = 0; /* tries above height */ - int32_t below = 0; /* tries below height */ - char *foundry = NULL; - char *name = NULL; - char *encoding = NULL; - char *style = NULL; - XFontStruct *xfont = NULL; - jstring family = NULL; - - if (JNU_IsNull(env, font)) { - if (errmsg != NULL) { - *errmsg = "java/lang" "NullPointerException"; - } - return (struct FontData *) NULL; - } - display = XDISPLAY; - - fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,fontIDs.pData); - if (fdata != NULL && fdata->xfont != NULL) { - return fdata; - } - - family = (*env)->CallObjectMethod(env, font, fontIDs.getFamily); - - if (!awtJNI_FontName(env, family, &foundry, &name, &encoding)) { - if (errmsg != NULL) { - *errmsg = "java/lang" "NullPointerException"; - } - (*env)->DeleteLocalRef(env, family); - return (struct FontData *) NULL; - } - style = Style((*env)->GetIntField(env, font, fontIDs.style)); - oheight = height = (*env)->GetIntField(env, font, fontIDs.size); - - while (1) { - jio_snprintf(fontSpec, sizeof(fontSpec), "-%s-%s-%s-*-*-%d-*-*-*-*-*-%s", - foundry, - name, - style, - height, - encoding); - - /*fprintf(stderr,"LoadFont: %s\n", fontSpec); */ - xfont = XLoadQueryFont(display, fontSpec); - - /* XXX: sometimes XLoadQueryFont returns a bogus font structure */ - /* with negative ascent. */ - if (xfont == NULL || xfont->ascent < 0) { - if (xfont != NULL) { - XFreeFont(display, xfont); - } - if (foundry != anyfoundry) { /* Use ptr comparison here, not strcmp */ - /* Try any other foundry before messing with the sizes */ - foundry = anyfoundry; - continue; - } - /* We couldn't find the font. We'll try to find an */ - /* alternate by searching for heights above and below our */ - /* preferred height. We try for 4 heights above and below. */ - /* If we still can't find a font we repeat the algorithm */ - /* using misc-fixed as the font. If we then fail, then we */ - /* give up and signal an error. */ - if (above == below) { - above++; - height = oheight + above; - } else { - below++; - if (below > 4) { - if (name != defaultfontname || style != anystyle) { - name = defaultfontname; - foundry = defaultfoundry; - height = oheight; - style = anystyle; - encoding = isolatin1; - above = below = 0; - continue; - } else { - if (errmsg != NULL) { - *errmsg = "java/io/" "FileNotFoundException"; - } - (*env)->DeleteLocalRef(env, family); - return (struct FontData *) NULL; - } - } - height = oheight - below; - } - continue; - } else { - fdata = ZALLOC(FontData); - - if (fdata == NULL) { - if (errmsg != NULL) { - *errmsg = "java/lang" "OutOfMemoryError"; - } - } else { - fdata->xfont = xfont; - JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata); - Disposer_AddRecord(env, font, pDataDisposeMethod, - ptr_to_jlong(fdata)); - } - (*env)->DeleteLocalRef(env, family); - return fdata; - } - } - /* not reached */ - } -} - /* * Registered with the 2D disposer to be called after the Font is GC'd. */
--- a/src/java.desktop/unix/native/common/awt/awt_Font.h Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.desktop/unix/native/common/awt/awt_Font.h Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. 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 @@ -34,11 +34,6 @@ jmethodID getFamily; }; -/* fieldIDs for XFontPeer fields that may be accessed from C */ -struct XFontPeerIDs { - jfieldID xfsname; -}; - /* fieldIDs for PlatformFont fields that may be accessed from C */ struct PlatformFontIDs { jfieldID componentFonts;
--- a/src/java.desktop/unix/native/common/awt/awt_p.h Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.desktop/unix/native/common/awt/awt_p.h Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2019, Oracle and/or its affiliates. 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 @@ -119,8 +119,6 @@ XFontStruct *xfont; /* Latin1 font */ }; -extern struct FontData *awtJNI_GetFontData(JNIEnv *env,jobject font, char **errmsg); - extern AwtGraphicsConfigDataPtr getDefaultConfig(int screen); extern AwtScreenDataPtr getScreenData(int screen); #endif /* !HEADLESS */
--- a/src/java.desktop/unix/native/libawt_xawt/awt/multi_font.c Thu Jul 25 02:16:49 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,393 +0,0 @@ -/* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -/* - * These routines are used for display string with multi font. - */ - -#ifdef HEADLESS - #error This file should not be included in headless library -#endif - -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <ctype.h> -#include <jni.h> -#include <jni_util.h> -#include <jvm.h> -#include "awt_Font.h" -#include "awt_p.h" -#include "multi_font.h" - -extern XFontStruct *loadFont(Display *, char *, int32_t); - -extern struct FontIDs fontIDs; -extern struct PlatformFontIDs platformFontIDs; -extern struct XFontPeerIDs xFontPeerIDs; - -/* - * make string with str + string representation of num - * This string is used as tag string of Motif Compound String and FontList. - */ -static void -makeTag(char *str, int32_t num, char *buf) -{ - int32_t len = strlen(str); - - strcpy(buf, str); - buf[len] = '0' + num % 100; - buf[len + 1] = '\0'; -} - -static int32_t -awtJNI_GetFontDescriptorNumber(JNIEnv * env - ,jobject font - ,jobject fd) -{ - int32_t i = 0, num; - /* initialize to NULL so that DeleteLocalRef will work. */ - jobjectArray componentFonts = NULL; - jobject peer = NULL; - jobject temp = NULL; - jboolean validRet = JNI_FALSE; - - if ((*env)->EnsureLocalCapacity(env, 2) < 0 || (*env)->ExceptionCheck(env)) - goto done; - - peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer); - if (peer == NULL) - goto done; - - componentFonts = (jobjectArray) - (*env)->GetObjectField(env,peer,platformFontIDs.componentFonts); - - if (componentFonts == NULL) - goto done; - - num = (*env)->GetArrayLength(env, componentFonts); - - for (i = 0; i < num; i++) { - temp = (*env)->GetObjectArrayElement(env, componentFonts, i); - - if ((*env)->IsSameObject(env, fd, temp)) { - validRet = JNI_TRUE; - break; - } - (*env)->DeleteLocalRef(env, temp); - } - - done: - (*env)->DeleteLocalRef(env, peer); - (*env)->DeleteLocalRef(env, componentFonts); - - if (validRet) - return i; - - return 0; -} - -jobject -awtJNI_GetFMFont(JNIEnv * env, jobject this) -{ - return JNU_CallMethodByName(env, NULL, this, "getFont_NoClientCode", - "()Ljava/awt/Font;").l; -} - -jboolean -awtJNI_IsMultiFont(JNIEnv * env, jobject this) -{ - jobject peer = NULL; - jobject fontConfig = NULL; - - if (this == NULL) { - return JNI_FALSE; - } - - if ((*env)->EnsureLocalCapacity(env, 2) < 0) { - return JNI_FALSE; - } - - peer = (*env)->CallObjectMethod(env,this,fontIDs.getPeer); - if (peer == NULL) { - return JNI_FALSE; - } - - fontConfig = (*env)->GetObjectField(env,peer,platformFontIDs.fontConfig); - (*env)->DeleteLocalRef(env, peer); - - if (fontConfig == NULL) { - return JNI_FALSE; - } - (*env)->DeleteLocalRef(env, fontConfig); - - return JNI_TRUE; -} - -jboolean -awtJNI_IsMultiFontMetrics(JNIEnv * env, jobject this) -{ - jobject peer = NULL; - jobject fontConfig = NULL; - jobject font = NULL; - - if (JNU_IsNull(env, this)) { - return JNI_FALSE; - } - if ((*env)->EnsureLocalCapacity(env, 3) < 0) { - return JNI_FALSE; - } - - font = JNU_CallMethodByName(env, NULL, this, "getFont_NoClientCode", - "()Ljava/awt/Font;").l; - if (JNU_IsNull(env, font) || (*env)->ExceptionCheck(env)) { - return JNI_FALSE; - } - - peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer); - (*env)->DeleteLocalRef(env, font); - - if (peer == NULL) { - return JNI_FALSE; - } - - fontConfig = (*env)->GetObjectField(env,peer,platformFontIDs.fontConfig); - (*env)->DeleteLocalRef(env, peer); - if (fontConfig == NULL) { - return JNI_FALSE; - } - (*env)->DeleteLocalRef(env, fontConfig); - - return JNI_TRUE; -} - -/* #define FONT_DEBUG 2 */ - -XFontSet -awtJNI_MakeFontSet(JNIEnv * env, jobject font) -{ - jstring xlfd = NULL; - char *xfontset = NULL; - int32_t size; - int32_t length = 0; - char *realxlfd = NULL, *ptr = NULL, *prev = NULL; - char **missing_list = NULL; - int32_t missing_count; - char *def_string = NULL; - XFontSet xfs; - jobject peer = NULL; - jstring xfsname = NULL; -#ifdef FONT_DEBUG - char xx[1024]; -#endif - - if ((*env)->EnsureLocalCapacity(env, 2) < 0) - return 0; - - size = (*env)->GetIntField(env, font, fontIDs.size) * 10; - - peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer); - xfsname = (*env)->GetObjectField(env, peer, xFontPeerIDs.xfsname); - - if (JNU_IsNull(env, xfsname)) - xfontset = ""; - else - xfontset = (char *)JNU_GetStringPlatformChars(env, xfsname, NULL); - - realxlfd = malloc(strlen(xfontset) + 50); - - prev = ptr = xfontset; - while ((ptr = strstr(ptr, "%d"))) { - char save = *(ptr + 2); - - *(ptr + 2) = '\0'; - jio_snprintf(realxlfd + length, strlen(xfontset) + 50 - length, - prev, size); - length = strlen(realxlfd); - *(ptr + 2) = save; - - prev = ptr + 2; - ptr += 2; - } - strcpy(realxlfd + length, prev); - -#ifdef FONT_DEBUG - strcpy(xx, realxlfd); -#endif - xfs = XCreateFontSet(awt_display, realxlfd, &missing_list, - &missing_count, &def_string); -#if FONT_DEBUG >= 2 - fprintf(stderr, "XCreateFontSet(%s)->0x%x\n", xx, xfs); -#endif - -#if FONT_DEBUG - if (missing_count != 0) { - int32_t i; - fprintf(stderr, "XCreateFontSet missing %d fonts:\n", missing_count); - for (i = 0; i < missing_count; ++i) { - fprintf(stderr, "\t\"%s\"\n", missing_list[i]); - } - fprintf(stderr, " requested \"%s\"\n", xx); -#if FONT_DEBUG >= 3 - exit(-1); -#endif - } -#endif - - free((void *)realxlfd); - - if (xfontset && !JNU_IsNull(env, xfsname)) - JNU_ReleaseStringPlatformChars(env, xfsname, (const char *) xfontset); - - (*env)->DeleteLocalRef(env, peer); - (*env)->DeleteLocalRef(env, xfsname); - return xfs; -} - -/* - * get multi font string width with multiple X11 font - * - * ASSUMES: We are not running on a privileged thread - */ -int32_t -awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int offset, int sLength, jobject font) -{ - char *err = NULL; - unsigned char *stringData = NULL; - char *offsetStringData = NULL; - int32_t stringCount, i; - int32_t size; - struct FontData *fdata = NULL; - jobject fontDescriptor = NULL; - jbyteArray data = NULL; - int32_t j; - int32_t width = 0; - int32_t length; - XFontStruct *xf = NULL; - jobjectArray dataArray = NULL; - if ((*env)->EnsureLocalCapacity(env, 3) < 0) - return 0; - - if (!JNU_IsNull(env, s) && !JNU_IsNull(env, font)) - { - jobject peer; - peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer); - - dataArray = (*env)->CallObjectMethod( - env, - peer, - platformFontIDs.makeConvertedMultiFontChars, - s, offset, sLength); - - if ((*env)->ExceptionOccurred(env)) - { - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - } - - (*env)->DeleteLocalRef(env, peer); - - if(dataArray == NULL) - { - return 0; - } - } else { - return 0; - } - - fdata = awtJNI_GetFontData(env, font, &err); - if ((*env)->ExceptionCheck(env)) { - (*env)->DeleteLocalRef(env, dataArray); - return 0; - } - - stringCount = (*env)->GetArrayLength(env, dataArray); - - size = (*env)->GetIntField(env, font, fontIDs.size); - - for (i = 0; i < stringCount; i+=2) - { - fontDescriptor = (*env)->GetObjectArrayElement(env, dataArray, i); - data = (*env)->GetObjectArrayElement(env, dataArray, i + 1); - - /* Bail if we've finished */ - if (fontDescriptor == NULL || data == NULL) { - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, data); - break; - } - - j = awtJNI_GetFontDescriptorNumber(env, font, fontDescriptor); - if ((*env)->ExceptionCheck(env)) { - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, data); - break; - } - - if (fdata->flist[j].load == 0) { - xf = loadFont(awt_display, - fdata->flist[j].xlfd, size * 10); - if (xf == NULL) { - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, data); - continue; - } - fdata->flist[j].load = 1; - fdata->flist[j].xfont = xf; - if (xf->min_byte1 == 0 && xf->max_byte1 == 0) - fdata->flist[j].index_length = 1; - else - fdata->flist[j].index_length = 2; - } - xf = fdata->flist[j].xfont; - - stringData = - (unsigned char *)(*env)->GetPrimitiveArrayCritical(env, data,NULL); - if (stringData == NULL) { - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, data); - (*env)->ExceptionClear(env); - JNU_ThrowOutOfMemoryError(env, "Could not get string data"); - break; - } - - length = (stringData[0] << 24) | (stringData[1] << 16) | - (stringData[2] << 8) | stringData[3]; - offsetStringData = (char *)(stringData + (4 * sizeof(char))); - - if (fdata->flist[j].index_length == 2) { - width += XTextWidth16(xf, (XChar2b *)offsetStringData, length/2); - } else { - width += XTextWidth(xf, offsetStringData, length); - } - - (*env)->ReleasePrimitiveArrayCritical(env, data, stringData, JNI_ABORT); - (*env)->DeleteLocalRef(env, fontDescriptor); - (*env)->DeleteLocalRef(env, data); - } - (*env)->DeleteLocalRef(env, dataArray); - - return width; -}
--- a/src/java.desktop/unix/native/libawt_xawt/awt/multi_font.h Thu Jul 25 02:16:49 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ -/* - * header for Multi Font String - */ -#ifndef _MULTI_FONT_H_ -#define _MULTI_FONT_H_ - -#ifndef HEADLESS -jboolean awtJNI_IsMultiFont(JNIEnv *env,jobject this); -jboolean awtJNI_IsMultiFontMetrics(JNIEnv *env,jobject this); -XFontSet awtJNI_MakeFontSet(JNIEnv *env,jobject font); -struct FontData *awtJNI_GetFontData(JNIEnv *env,jobject font, char **errmsg); -int32_t awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int32_t offset, - int32_t length, jobject font); -#endif /* !HEADLESS */ - -#endif /* _MULTI_FONT_H_ */
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Thu Jul 25 02:16:49 2019 +0000 +++ b/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Thu Jul 25 21:51:13 2019 +0000 @@ -79,16 +79,6 @@ extern Display* awt_init_Display(JNIEnv *env, jobject this); extern void freeNativeStringArray(char **array, jsize length); extern char** stringArrayToNative(JNIEnv *env, jobjectArray array, jsize * ret_length); - -struct XFontPeerIDs xFontPeerIDs; - -JNIEXPORT void JNICALL -Java_sun_awt_X11_XFontPeer_initIDs - (JNIEnv *env, jclass cls) -{ - xFontPeerIDs.xfsname = - (*env)->GetFieldID(env, cls, "xfsname", "Ljava/lang/String;"); -} #endif /* !HEADLESS */ /* This function gets called from the static initializer for FileDialog.java
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Thu Jul 25 21:51:13 2019 +0000 @@ -156,9 +156,10 @@ platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); process(); } - } catch (SecurityException e) { + } catch (SecurityException | UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) { // Without permission to find or create the MBeanServer, // we cannot process any Graal mbeans. + // Various other errors can occur in the ManagementFactory (JDK-8076557) deferred = null; } } else {
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java Thu Jul 25 21:51:13 2019 +0000 @@ -171,4 +171,3 @@ return res; } } -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ConstantProbablityBranchFoldingTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.api.directives.test; + +import org.graalvm.compiler.api.directives.GraalDirectives; +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.graalvm.compiler.graph.iterators.NodeIterable; +import org.graalvm.compiler.nodes.IfNode; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.junit.Assert; +import org.junit.Test; + +public class ConstantProbablityBranchFoldingTest extends GraalCompilerTest { + + public static int branchFoldingSnippet1() { + if (GraalDirectives.injectBranchProbability(0.5, true)) { + return 1; + } else { + return 2; + } + } + + public static int branchFoldingSnippet2() { + if (GraalDirectives.injectBranchProbability(0.5, false)) { + return 1; + } else { + return 2; + } + } + + @Test + public void testEarlyFolding1() { + test("branchFoldingSnippet1"); + } + + @Test + public void testEarlyFolding2() { + test("branchFoldingSnippet2"); + } + + @Override + protected void checkLowTierGraph(StructuredGraph graph) { + NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE); + Assert.assertEquals("IfNode count", 0, ifNodes.count()); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/AArch64BitCountAssemblerTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/AArch64BitCountAssemblerTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -75,6 +75,9 @@ AArch64MacroAssembler masm = new AArch64MacroAssembler(target); Register dst = registerConfig.getReturnRegister(JavaKind.Int); Register src = asRegister(cc.getArgument(0)); + // Generate a nop first as AArch64 Hotspot requires instruction at nmethod verified + // entry to be a jump or nop. (See https://github.com/oracle/graal/issues/1439) + masm.nop(); RegisterArray registers = registerConfig.filterAllocatableRegisters(AArch64Kind.V64_BYTE, registerConfig.getAllocatableRegisters()); masm.popcnt(size, dst, src, registers.get(registers.size() - 1)); masm.ret(AArch64.lr);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LoweringProviderMixin.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.core.aarch64; + +import org.graalvm.compiler.nodes.spi.LoweringProvider; + +public interface AArch64LoweringProviderMixin extends LoweringProvider { + + @Override + default Integer smallestCompareWidth() { + return 32; + } + + @Override + default boolean supportBulkZeroing() { + return false; + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -80,9 +80,9 @@ */ public static void replace(ReadNode readNode) { assert readNode.getUsageCount() == 1; - assert readNode.getUsageAt(0) instanceof ZeroExtendNode || readNode.getUsageAt(0) instanceof SignExtendNode; + assert readNode.usages().first() instanceof ZeroExtendNode || readNode.usages().first() instanceof SignExtendNode; - ValueNode usage = (ValueNode) readNode.getUsageAt(0); + ValueNode usage = (ValueNode) readNode.usages().first(); boolean isSigned = usage instanceof SignExtendNode; IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java Thu Jul 25 21:51:13 2019 +0000 @@ -49,7 +49,7 @@ if (node instanceof ReadNode) { ReadNode readNode = (ReadNode) node; if (readNode.hasExactlyOneUsage()) { - Node usage = readNode.getUsageAt(0); + Node usage = readNode.usages().first(); if (usage instanceof ZeroExtendNode || usage instanceof SignExtendNode) { AArch64ReadNode.replace(readNode); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java Thu Jul 25 21:51:13 2019 +0000 @@ -24,8 +24,10 @@ package org.graalvm.compiler.core.aarch64; +import java.util.List; import java.util.ListIterator; +import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.java.DefaultSuitesCreator; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.options.OptionValues; @@ -37,24 +39,33 @@ import org.graalvm.compiler.phases.tiers.Suites; public class AArch64SuitesCreator extends DefaultSuitesCreator { - private final Class<? extends Phase> insertReadReplacementBefore; + private final List<Class<? extends Phase>> insertReadReplacementBeforePositions; - public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, Class<? extends Phase> insertReadReplacementBefore) { + public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, List<Class<? extends Phase>> insertReadReplacementBeforePositions) { super(compilerConfiguration, plugins); - this.insertReadReplacementBefore = insertReadReplacementBefore; + this.insertReadReplacementBeforePositions = insertReadReplacementBeforePositions; } @Override public Suites createSuites(OptionValues options) { Suites suites = super.createSuites(options); - - ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(insertReadReplacementBefore); - // Put AArch64ReadReplacementPhase right before the SchedulePhase - while (PhaseSuite.findNextPhase(findPhase, insertReadReplacementBefore)) { - // Search for last occurrence of SchedulePhase + ListIterator<BasePhase<? super LowTierContext>> findPhase = null; + for (Class<? extends Phase> phase : insertReadReplacementBeforePositions) { + findPhase = suites.getLowTier().findPhase(phase); + if (findPhase != null) { + // Put AArch64ReadReplacementPhase right before the requested phase + while (PhaseSuite.findNextPhase(findPhase, phase)) { + // Search for last occurrence of SchedulePhase + } + findPhase.previous(); + break; + } } - findPhase.previous(); - findPhase.add(new AArch64ReadReplacementPhase()); + if (findPhase != null) { + findPhase.add(new AArch64ReadReplacementPhase()); + } else { + throw GraalError.shouldNotReachHere("Cannot find phase to insert AArch64ReadReplacementPhase"); + } return suites; } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/ConstantStackMoveTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/ConstantStackMoveTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -143,7 +143,7 @@ } @Test - public void runByte() throws Throwable { + public void runByte() { runTest("testByte"); } @@ -157,7 +157,7 @@ } @Test - public void runShort() throws Throwable { + public void runShort() { runTest("testShort"); } @@ -171,7 +171,7 @@ } @Test - public void runInt() throws Throwable { + public void runInt() { runTest("testInt"); } @@ -185,7 +185,7 @@ } @Test - public void runLong() throws Throwable { + public void runLong() { runTest("testLong"); } @@ -199,7 +199,7 @@ } @Test - public void runFloat() throws Throwable { + public void runFloat() { runTest("testFloat"); } @@ -213,7 +213,7 @@ } @Test - public void runDouble() throws Throwable { + public void runDouble() { runTest("testDouble"); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/StackStoreTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/StackStoreTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -113,7 +113,7 @@ } @Test - public void run0() throws Throwable { + public void run0() { runTest("test0", 0xDEADDEAD); } @@ -122,7 +122,7 @@ } @Test - public void run1() throws Throwable { + public void run1() { runTest("test1", 0xDEADDEAD); } @@ -131,7 +131,7 @@ } @Test - public void run2() throws Throwable { + public void run2() { runTest("test2", 0xDEADDEAD); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Jul 25 21:51:13 2019 +0000 @@ -126,6 +126,7 @@ import org.graalvm.compiler.lir.amd64.AMD64Unary; import org.graalvm.compiler.lir.amd64.AMD64ZeroMemoryOp; import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary; +import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryConstFloatOp; import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryOp; import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary; import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator; @@ -1360,9 +1361,13 @@ } } - private Variable emitBinary(LIRKind resultKind, VexRVMOp op, Value a, Value b) { + protected Variable emitBinary(LIRKind resultKind, VexRVMOp op, Value a, Value b) { Variable result = getLIRGen().newVariable(resultKind); - getLIRGen().append(new AVXBinaryOp(op, getRegisterSize(result), result, asAllocatable(a), asAllocatable(b))); + if (b instanceof ConstantValue && (b.getPlatformKind() == AMD64Kind.SINGLE || b.getPlatformKind() == AMD64Kind.DOUBLE)) { + getLIRGen().append(new AVXBinaryConstFloatOp(op, getRegisterSize(result), result, asAllocatable(a), (ConstantValue) b)); + } else { + getLIRGen().append(new AVXBinaryOp(op, getRegisterSize(result), result, asAllocatable(a), asAllocatable(b))); + } return result; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Thu Jul 25 21:51:13 2019 +0000 @@ -47,8 +47,8 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.Condition; @@ -80,10 +80,10 @@ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp; import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp; import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp; +import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.HashTableSwitchOp; import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp; import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp; import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp; -import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.HashTableSwitchOp; import org.graalvm.compiler.lir.amd64.AMD64LFenceOp; import org.graalvm.compiler.lir.amd64.AMD64Move; import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LoweringProviderMixin.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.core.amd64; + +import org.graalvm.compiler.nodes.spi.LoweringProvider; + +public interface AMD64LoweringProviderMixin extends LoweringProvider { + + @Override + default Integer smallestCompareWidth() { + return 8; + } + + @Override + default boolean supportBulkZeroing() { + return true; + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -50,6 +50,7 @@ import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.PrimitiveConstant; import jdk.vm.ci.meta.Value; public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase { @@ -65,6 +66,9 @@ switch (c.getJavaKind()) { case Long: return NumUtil.isInt(c.asLong()); + case Float: + case Double: + return false; case Object: return c.isNull(); default: @@ -75,6 +79,12 @@ } @Override + public boolean mayEmbedConstantLoad(Constant constant) { + // Only consider not inlineable constants here. + return constant instanceof PrimitiveConstant && ((PrimitiveConstant) constant).getJavaKind().isNumericFloat(); + } + + @Override public boolean allowConstantToStackMove(Constant constant) { if (constant instanceof DataPointerConstant) { return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Jul 25 21:51:13 2019 +0000 @@ -289,4 +289,6 @@ @Option(help = "If applicable, use bulk zeroing instructions when the zeroing size in bytes exceeds this threshold.", type = OptionType.Expert) public static final OptionKey<Integer> MinimalBulkZeroingSize = new OptionKey<>(2048); + @Option(help = "Alignment in bytes for loop header blocks.", type = OptionType.Expert) + public static final OptionKey<Integer> LoopHeaderAlignment = new OptionKey<>(16); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeWriter.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeWriter.java Thu Jul 25 21:51:13 2019 +0000 @@ -32,6 +32,8 @@ import static org.graalvm.compiler.core.common.util.TypeConversion.asU4; import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe; +import java.nio.ByteBuffer; + import org.graalvm.compiler.core.common.calc.UnsignedMath; import sun.misc.Unsafe; @@ -103,6 +105,17 @@ return result; } + /** Copies the buffer into the provided ByteBuffer at its current position. */ + public final ByteBuffer toByteBuffer(ByteBuffer buffer) { + assert buffer.remaining() <= totalSize; + int initialPos = buffer.position(); + for (Chunk cur = firstChunk; cur != null; cur = cur.next) { + buffer.put(cur.data, 0, cur.size); + } + assert buffer.position() - initialPos == totalSize; + return buffer; + } + @Override public final void putS1(long value) { long offset = writeOffset(Byte.BYTES);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCArithmeticLIRGenerator.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCArithmeticLIRGenerator.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SparcLoweringProviderMixin.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.core.sparc; + +import org.graalvm.compiler.nodes.spi.LoweringProvider; + +public interface SparcLoweringProviderMixin extends LoweringProvider { + + @Override + default Integer smallestCompareWidth() { + return 32; + } + + @Override + default boolean supportBulkZeroing() { + return false; + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationPiTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationPiTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -63,4 +63,3 @@ test("testSnippet1", 1); } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -24,6 +24,7 @@ package org.graalvm.compiler.core.test; +import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; import org.junit.Test; public class ConditionalNodeTest extends GraalCompilerTest { @@ -106,4 +107,23 @@ sink0 = 1; return Math.min(-1, value); } + + @Test + public void test4() { + test("conditionalTest4", this, 0); + test("conditionalTest4", this, 1); + } + + int a; + InvokeKind b; + + public static int conditionalTest4(ConditionalNodeTest node, int a) { + if (a == 1) { + node.b = InvokeKind.Virtual; + } else { + node.b = InvokeKind.Special; + } + node.a = a; + return a; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -53,17 +53,18 @@ String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"}; EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap(); overrides.put(DebugOptions.DumpPath, dumpDirectoryPath.toString()); + overrides.put(DebugOptions.PrintCFG, true); overrides.put(DebugOptions.PrintGraph, PrintGraphTarget.File); overrides.put(DebugOptions.PrintCanonicalGraphStrings, true); overrides.put(DebugOptions.Dump, "*"); // Generate dump files. test(new OptionValues(getInitialOptions(), overrides), "snippet"); - // Check that Ideal files got created, in the right place. + // Check that IGV files got created, in the right place. checkForFiles(dumpDirectoryPath, extensions); // Clean up the generated files. - scrubDirectory(dumpDirectoryPath); + removeDirectory(dumpDirectoryPath); } /** @@ -92,24 +93,4 @@ assertTrue(paths[0].equals(paths[i]), paths[0] + " != " + paths[i]); } } - - /** - * Remove the temporary directory. - */ - private static void scrubDirectory(Path directoryPath) { - try { - try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) { - for (Path filePath : stream) { - if (Files.isRegularFile(filePath)) { - Files.delete(filePath); - } else if (Files.isDirectory(filePath)) { - scrubDirectory(filePath); - } - } - } - Files.delete(directoryPath); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FindUniqueConcreteMethodBugTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FindUniqueConcreteMethodBugTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -29,7 +29,6 @@ import jdk.vm.ci.meta.ResolvedJavaType; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; public class FindUniqueConcreteMethodBugTest extends GraalCompilerTest { @@ -44,7 +43,6 @@ * {@link PersonImpl#getName()} and {@link Tenant#getName()}). */ @Test - @Ignore("fix HotSpotResolvedObjectTypeImpl.findUniqueConcreteMethod") public void test() throws NoSuchMethodException { ResolvedJavaMethod ifaceMethod = getMetaAccess().lookupJavaMethod(Person.class.getDeclaredMethod("getName")); @@ -64,9 +62,8 @@ // this causes a VM crash as getLabelLength() directly invokes PersonImpl.getName(). test("getLabelLength", tenant); - ResolvedJavaMethod expected = null; AssumptionResult<ResolvedJavaMethod> actual = getMetaAccess().lookupJavaType(AbstractPerson.class).findUniqueConcreteMethod(ifaceMethod); - Assert.assertEquals(expected, actual.getResult()); + Assert.assertNull(String.valueOf(actual), actual); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1116,8 +1116,14 @@ return graph; } + @SuppressWarnings("try") protected void applyFrontEnd(StructuredGraph graph) { - GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), getOptimisticOptimizations(), graph.getProfilingInfo(), createSuites(graph.getOptions())); + DebugContext debug = graph.getDebug(); + try (DebugContext.Scope s = debug.scope("FrontEnd", graph)) { + GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), getOptimisticOptimizations(), graph.getProfilingInfo(), createSuites(graph.getOptions())); + } catch (Throwable e) { + throw debug.handle(e); + } } protected StructuredGraph lastCompiledGraph;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchFoldingTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.core.test; + +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.phases.common.CanonicalizerPhase; +import org.junit.Test; + +public class SwitchFoldingTest extends GraalCompilerTest { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + private static final String REFERENCE_SNIPPET_2 = "reference2Snippet"; + private static final String REFERENCE_SNIPPET_3 = "reference3Snippet"; + private static final String REFERENCE_SNIPPET_4 = "reference4Snippet"; + private static final String REFERENCE_SNIPPET_5 = "reference5Snippet"; + + public static int referenceSnippet(int a) { + switch (a) { + case 0: + return 10; + case 1: + return 5; + case 2: + return 3; + case 3: + return 11; + case 4: + return 14; + case 5: + return 2; + case 6: + return 1; + case 7: + return 0; + case 8: + return 7; + default: + return 6; + } + } + + public static int reference2Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + case 2: + return 1; + case 3: + return 6; + default: + return 7; + } + } + + public static int reference3Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + case 2: + case 4: + return 6; + case 6: + case 7: + default: + return 7; + } + } + + public static int test1Snippet(int a) { + if (a == 0) { + return 10; + } else if (a == 1) { + return 5; + } else if (a == 2) { + return 3; + } else if (a == 3) { + return 11; + } else if (a == 4) { + return 14; + } else if (a == 5) { + return 2; + } else if (a == 6) { + return 1; + } else if (a == 7) { + return 0; + } else if (a == 8) { + return 7; + } else { + return 6; + } + } + + @Test + public void test1() { + test1("test1Snippet"); + } + + public static int test2Snippet(int a) { + switch (a) { + case 0: + return 10; + case 1: + return 5; + case 2: + return 3; + case 3: + return 11; + case 4: + return 14; + default: + switch (a) { + case 5: + return 2; + case 6: + return 1; + case 7: + return 0; + case 8: + return 7; + default: + return 6; + } + } + } + + @Test + public void test2() { + test1("test2Snippet"); + } + + public static int test3Snippet(int a) { + switch (a) { + case 0: + return 10; + default: + switch (a) { + case 1: + return 5; + default: + switch (a) { + case 2: + return 3; + default: + switch (a) { + case 3: + return 11; + default: + switch (a) { + case 4: + return 14; + default: + switch (a) { + case 5: + return 2; + default: + switch (a) { + case 6: + return 1; + default: + switch (a) { + case 7: + return 0; + default: + switch (a) { + case 8: + return 7; + default: + return 6; + } + } + } + } + } + } + } + } + } + } + + @Test + public void test3() { + test1("test3Snippet"); + } + + public static int test4Snippet(int a) { + switch (a) { + case 0: + return 10; + case 1: + return 5; + case 2: + return 3; + case 3: + return 11; + case 4: + return 14; + case 5: + return 2; + case 6: + return 1; + default: + if (a == 7) { + return 0; + } else if (a == 8) { + return 7; + } else { + return 6; + } + } + } + + @Test + public void test4() { + test1("test4Snippet"); + } + + public static int test5Snippet(int a) { + switch (a) { + case 0: + return 10; + default: + switch (a) { + case 1: + return 5; + default: + switch (a) { + case 2: + return 3; + default: + switch (a) { + case 3: + return 11; + default: + switch (a) { + case 4: + return 14; + default: + switch (a) { + case 5: + return 2; + default: + switch (a) { + case 6: + return 1; + default: + if (a == 7) { + return 0; + } else if (a == 8) { + return 7; + } else { + return 6; + } + } + } + } + } + } + } + } + } + + @Test + public void test5() { + test1("test5Snippet"); + } + + public static int test6Snippet(int a) { + if (a == 0) { + return 10; + } else { + switch (a) { + case 1: + return 5; + default: + if (a == 2) { + return 3; + } else if (a == 3) { + return 11; + } else { + switch (a) { + case 4: + return 14; + case 5: + return 2; + case 6: + return 1; + default: + if (a == 7) { + return 0; + } else if (a == 8) { + return 7; + } else { + return 6; + } + } + } + + } + } + } + + @Test + public void test6() { + test1("test6Snippet"); + } + + public static int test7Snippet(int a) { + if (a == 0) { + return 4; + } else { + switch (a) { + case 1: + case 2: + return 1; + case 3: + return 6; + default: + return 7; + } + } + } + + @Test + public void test7() { + test2("test7Snippet"); + } + + public static int test8Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + case 2: + case 7: + default: + switch (a) { + case 2: + case 6: + default: + switch (a) { + case 1: + case 2: + case 4: + return 6; + default: + return 7; + } + } + } + } + + @Test + public void test8() { + test3("test8Snippet"); + } + + public static int reference4Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + case 2: + case 4: + return 6; + case 6: + return 7; + case 7: + return 7; + default: + return 7; + } + } + + public static int test9Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + case 2: + case 4: + return 6; + case 6: + case 7: + default: + if (a == 6) { + return 7; + } else if (a == 7) { + return 7; + } else { + return 7; + } + } + } + + @Test + public void test9() { + test4("test9Snippet"); + } + + public static int reference5Snippet(int a) { + switch (a) { + case 0: + return 4; + case 1: + return 1; + case 2: + return 1; + case 3: + return 6; + default: + return 7; + } + } + + public static int test10Snippet(int a) { + if (a == 0) { + return 4; + } else { + if (a == 1 || a == 2) { + return 1; + } else { + switch (a) { + case 3: + return 6; + default: + return 7; + } + } + } + } + + @Test + public void test10() { + test5("test10Snippet"); + } + + private void test1(String snippet) { + test(snippet, REFERENCE_SNIPPET); + } + + private void test2(String snippet) { + test(snippet, REFERENCE_SNIPPET_2); + } + + private void test3(String snippet) { + test(snippet, REFERENCE_SNIPPET_3); + } + + private void test4(String snippet) { + test(snippet, REFERENCE_SNIPPET_4); + } + + private void test5(String snippet) { + test(snippet, REFERENCE_SNIPPET_5); + } + + private void test(String snippet, String ref) { + StructuredGraph graph = parseEager(snippet, StructuredGraph.AllowAssumptions.YES); + DebugContext debug = graph.getDebug(); + debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph"); + new CanonicalizerPhase().apply(graph, getProviders()); + StructuredGraph referenceGraph = parseEager(ref, StructuredGraph.AllowAssumptions.YES); + assertEquals(referenceGraph, graph); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/backend/BackendTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/backend/BackendTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -45,10 +45,10 @@ } @SuppressWarnings("try") - protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) { + protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph, OptimisticOptimizations optimizations) { DebugContext debug = graph.getDebug(); try (DebugContext.Scope s = debug.scope("FrontEnd")) { - GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, graph.getProfilingInfo(), createSuites(graph.getOptions())); + GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), optimizations, graph.getProfilingInfo(), createSuites(graph.getOptions())); } catch (Throwable e) { throw debug.handle(e); } @@ -57,4 +57,7 @@ return lirGen; } + protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) { + return getLIRGenerationResult(graph, OptimisticOptimizations.NONE); + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Thu Jul 25 21:51:13 2019 +0000 @@ -302,10 +302,16 @@ } } + /** + * Calls {@link System#exit(int)} in the runtime embedding the Graal compiler. This will be a + * different runtime than Graal's runtime in the case of libgraal. + */ + protected abstract void exitHostVM(int status); + private void maybeExitVM(ExceptionAction action) { if (action == ExitVM) { TTY.println("Exiting VM after retry compilation of " + this); - System.exit(-1); + exitHostVM(-1); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java Thu Jul 25 21:51:13 2019 +0000 @@ -156,10 +156,6 @@ } assert checkValues(vobjValue.getType(), values, slotKinds); vobjValue.setValues(values, slotKinds); - - if (vobjNode instanceof VirtualBoxingNode) { - GraalServices.markVirtualObjectAsAutoBox(vobjValue); - } } virtualObjectsArray = new VirtualObject[virtualObjects.size()]; @@ -323,7 +319,8 @@ assert obj.entryCount() == 0 || state instanceof VirtualObjectState; VirtualObject vobject = virtualObjects.get(obj); if (vobject == null) { - vobject = VirtualObject.get(obj.type(), virtualObjects.size()); + boolean isAutoBox = obj instanceof VirtualBoxingNode; + vobject = GraalServices.createVirtualObject(obj.type(), virtualObjects.size(), isAutoBox); virtualObjects.put(obj, vobject); pendingVirtualObjects.add(obj); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. 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
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Thu Jul 25 21:51:13 2019 +0000 @@ -257,7 +257,6 @@ * @throws BailoutException if the code installation failed */ public InstalledCode createDefaultInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationResult compilationResult) { - System.out.println(compilationResult.getSpeculationLog()); return createInstalledCode(debug, method, compilationResult, null, true); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Thu Jul 25 21:51:13 2019 +0000 @@ -818,22 +818,24 @@ private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) { if (filter == null) { - fail("filter cannot be null"); + throw fail("filter cannot be null"); } checkReplaceWith(other); int i = 0; - while (i < this.getUsageCount()) { + int usageCount = this.getUsageCount(); + while (i < usageCount) { Node usage = this.getUsageAt(i); if (filter.test(usage)) { replaceAtUsage(other, toBeDeleted, usage); this.movUsageFromEndTo(i); + usageCount--; } else { ++i; } } } - public Node getUsageAt(int index) { + private Node getUsageAt(int index) { if (index == 0) { return this.usage0; } else if (index == 1) { @@ -848,14 +850,35 @@ replaceAtMatchingUsages(other, usagePredicate, null); } + private void replaceAtUsagePos(Node other, Node usage, Position pos) { + pos.initialize(usage, other); + maybeNotifyInputChanged(usage); + if (other != null) { + other.addUsage(usage); + } + } + public void replaceAtUsages(InputType type, Node other) { checkReplaceWith(other); - for (Node usage : usages().snapshot()) { + int i = 0; + int usageCount = this.getUsageCount(); + if (usageCount == 0) { + return; + } + usages: while (i < usageCount) { + Node usage = this.getUsageAt(i); for (Position pos : usage.inputPositions()) { if (pos.getInputType() == type && pos.get(usage) == this) { - pos.set(usage, other); + replaceAtUsagePos(other, usage, pos); + this.movUsageFromEndTo(i); + usageCount--; + continue usages; } } + i++; + } + if (hasNoUsages()) { + maybeNotifyZeroUsages(this); } } @@ -913,6 +936,14 @@ } } + public void replaceFirstInput(Node oldInput, Node newInput, InputType type) { + for (Position pos : inputPositions()) { + if (pos.getInputType() == type && pos.get(this) == oldInput) { + pos.set(this, newInput); + } + } + } + public void clearInputs() { assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); getNodeClass().unregisterAtInputsAsUsage(this); @@ -1059,6 +1090,8 @@ assertFalse(input.isDeleted(), "input was deleted %s", input); assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); + Class<?> expectedType = pos.getType(); + assertTrue(expectedType.isAssignableFrom(input.getClass()), "Invalid input type for %s: expected a %s but was a %s", pos, expectedType, input.getClass()); } } return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Thu Jul 25 21:51:13 2019 +0000 @@ -126,7 +126,7 @@ field.setAccessible(true); return (NodeClass<T>) field.get(null); } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { - throw new RuntimeException(e); + throw new RuntimeException("Could not load Graal NodeClass TYPE field for " + clazz, e); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java Thu Jul 25 21:51:13 2019 +0000 @@ -127,6 +127,7 @@ private boolean check(Node node) { assert node.graph() == graph : String.format("%s is not part of the graph", node); assert !isNew(node) : "this node was added to the graph after creating the node map : " + node; + assert node.isAlive() : "this node is not alive: " + node; return true; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Position.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Position.java Thu Jul 25 21:51:13 2019 +0000 @@ -146,4 +146,12 @@ public int getIndex() { return index; } + + public Class<?> getType() { + if (index < edges.getDirectCount()) { + return edges.getType(index); + } else { + return Node.class; + } + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java Thu Jul 25 21:51:13 2019 +0000 @@ -49,6 +49,7 @@ import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; import org.graalvm.compiler.core.gen.LIRGenerationProvider; +import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotDataBuilder; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; @@ -72,12 +73,16 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import jdk.vm.ci.aarch64.AArch64Kind; import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.CompilationRequest; +import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.RegisterConfig; import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.site.Mark; import jdk.vm.ci.hotspot.HotSpotCallingConventionType; import jdk.vm.ci.hotspot.HotSpotSentinelConstant; import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig; @@ -85,6 +90,8 @@ import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; +import sun.misc.Unsafe; + /** * HotSpot AArch64 specific backend. */ @@ -126,6 +133,46 @@ } } + @Override + public InstalledCode createInstalledCode(DebugContext debug, + ResolvedJavaMethod method, + CompilationRequest compilationRequest, + CompilationResult compilationResult, + InstalledCode predefinedInstalledCode, + boolean isDefault, + Object[] context) { + boolean isStub = (method == null); + boolean isAOT = compilationResult.isImmutablePIC(); + if (!isStub && !isAOT) { + // Non-stub compilation results are installed into HotSpot as nmethods. As AArch64 has + // a constraint that the instruction at nmethod verified entry point should be a nop or + // jump, AArch64HotSpotBackend always generate a nop placeholder before the code body + // for non-AOT compilations. See AArch64HotSpotBackend.emitInvalidatePlaceholder(). This + // assert checks if the nop placeholder is generated at all required places, including + // in manually assembled code in CodeGenTest cases. + assert hasInvalidatePlaceholder(compilationResult); + } + return super.createInstalledCode(debug, method, compilationRequest, compilationResult, predefinedInstalledCode, isDefault, context); + } + + private boolean hasInvalidatePlaceholder(CompilationResult compilationResult) { + byte[] targetCode = compilationResult.getTargetCode(); + int verifiedEntryOffset = 0; + for (Mark mark : compilationResult.getMarks()) { + Object markId = mark.id; + if (markId instanceof Integer && (int) markId == config.MARKID_VERIFIED_ENTRY) { + // The nmethod verified entry is located at some pc offset. + verifiedEntryOffset = mark.pcOffset; + break; + } + } + Unsafe unsafe = GraalUnsafeAccess.getUnsafe(); + int instruction = unsafe.getIntVolatile(targetCode, unsafe.arrayBaseOffset(byte[].class) + verifiedEntryOffset); + AArch64MacroAssembler masm = new AArch64MacroAssembler(getTarget()); + masm.nop(); + return instruction == masm.getInt(0); + } + private class HotSpotFrameContext implements FrameContext { final boolean isStub;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Jul 25 21:51:13 2019 +0000 @@ -29,6 +29,7 @@ import static jdk.vm.ci.common.InitTimer.timer; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.graalvm.compiler.bytecode.BytecodeProvider; @@ -193,7 +194,7 @@ protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, @SuppressWarnings("unused") Replacements replacements) { - AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, SchedulePhase.class); + AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, Arrays.asList(SchedulePhase.class)); Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool())); return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -25,6 +25,7 @@ package org.graalvm.compiler.hotspot.aarch64; +import org.graalvm.compiler.core.aarch64.AArch64LoweringProviderMixin; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.graph.Node; @@ -45,7 +46,7 @@ import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; import jdk.vm.ci.meta.MetaAccessProvider; -public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider { +public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements AArch64LoweringProviderMixin { private AArch64IntegerArithmeticSnippets integerArithmeticSnippets; private AArch64FloatArithmeticSnippets floatArithmeticSnippets;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -27,6 +27,7 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs; import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.core.amd64.AMD64LoweringProviderMixin; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.graph.Node; @@ -53,7 +54,7 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; -public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider { +public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements AMD64LoweringProviderMixin { private AMD64ConvertSnippets.Templates convertSnippets; private ProbabilisticProfileSnippets.Templates profileSnippets; @@ -135,14 +136,4 @@ ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, dispatchNode.getStubCallDescriptor(), dispatchNode.getStubCallArgs())); graph.replaceFixed(dispatchNode, call); } - - @Override - public Integer smallestCompareWidth() { - return 8; - } - - @Override - public boolean supportBulkZeroing() { - return true; - } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotStrategySwitchOp.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotStrategySwitchOp.java Thu Jul 25 21:51:13 2019 +0000 @@ -34,7 +34,7 @@ import jdk.vm.ci.code.Register; import jdk.vm.ci.code.ValueUtil; -import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; +import jdk.vm.ci.hotspot.HotSpotConstant; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.Value; @@ -58,8 +58,8 @@ @Override protected void emitComparison(Constant c) { - if (c instanceof HotSpotMetaspaceConstant) { - HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) c; + if (c instanceof HotSpotConstant) { + HotSpotConstant meta = (HotSpotConstant) c; if (meta.isCompressed()) { crb.recordInlineDataInCode(meta); masm.cmpl(keyRegister, 0xDEADDEAD);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/BenchmarkCounterOverflowTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/BenchmarkCounterOverflowTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -28,6 +28,7 @@ import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -100,7 +101,7 @@ } @Test - public void spawnSubprocess() throws Throwable { + public void spawnSubprocess() throws IOException, InterruptedException { Assume.assumeFalse("subprocess already spawned -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY)); List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine()); vmArgs.add("-XX:JVMCICounterSize=1");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/ExceedMaxOopMapStackOffset.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/ExceedMaxOopMapStackOffset.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. 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 @@ -120,7 +120,7 @@ } @Test - public void runStackObjects() throws Throwable { + public void runStackObjects() { int max = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig().maxOopMapStackOffset; if (max == Integer.MAX_VALUE) { max = 16 * 1024 - 64;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -153,7 +153,7 @@ } @Test - public void runStackObjects() throws Throwable { + public void runStackObjects() { int max = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig().maxOopMapStackOffset; Assume.assumeFalse("no limit on oop map size", max == Integer.MAX_VALUE); numPrimitiveSlots = (max / 8) * 2;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -25,6 +25,7 @@ package org.graalvm.compiler.hotspot.sparc; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; +import org.graalvm.compiler.core.sparc.SparcLoweringProviderMixin; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.meta.DefaultHotSpotLoweringProvider; @@ -36,7 +37,7 @@ import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; import jdk.vm.ci.meta.MetaAccessProvider; -public class SPARCHotSpotLoweringProvider extends DefaultHotSpotLoweringProvider { +public class SPARCHotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements SparcLoweringProviderMixin { public SPARCHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BoxDeoptimizationTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BoxDeoptimizationTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -24,85 +24,97 @@ package org.graalvm.compiler.hotspot.test; +import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPEC; + import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.core.test.GraalCompilerTest; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; public class BoxDeoptimizationTest extends GraalCompilerTest { - private static boolean isJDK13OrLater = JavaVersionUtil.JAVA_SPEC >= 13; - public static void testInteger() { - Object[] values = {42, new Exception()}; + private static void checkJDK() { + Assume.assumeTrue(JAVA_SPEC == 8 || JAVA_SPEC >= 13); + } + + public static void testIntegerSnippet() { + Object[] values = {42, -42, new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Integer.valueOf(42)); + Assert.assertSame(values[1], Integer.valueOf(-42)); } @Test - public void test1() { - Assume.assumeTrue(isJDK13OrLater); - test("testInteger"); + public void testInteger() { + checkJDK(); + test("testIntegerSnippet"); } - public static void testLong() { - Object[] values = {42L, new Exception()}; + public static void testLongSnippet() { + long highBitsOnly = 2L << 40; + Object[] values = {42L, -42L, highBitsOnly, new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Long.valueOf(42)); + Assert.assertSame(values[1], Long.valueOf(-42)); + Assert.assertNotSame(values[2], highBitsOnly); } @Test - public void test2() { - Assume.assumeTrue(isJDK13OrLater); - test("testLong"); + public void testLong() { + checkJDK(); + test("testLongSnippet"); } - public static void testChar() { - Object[] values = {'a', new Exception()}; + public static void testCharSnippet() { + Object[] values = {'a', 'Z', new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Character.valueOf('a')); + Assert.assertSame(values[1], Character.valueOf('Z')); } @Test - public void test3() { - Assume.assumeTrue(isJDK13OrLater); - test("testChar"); + public void testChar() { + checkJDK(); + test("testCharSnippet"); } - public static void testShort() { - Object[] values = {(short) 42, new Exception()}; + public static void testShortSnippet() { + Object[] values = {(short) 42, (short) -42, new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Short.valueOf((short) 42)); + Assert.assertSame(values[1], Short.valueOf((short) -42)); } @Test - public void test4() { - Assume.assumeTrue(isJDK13OrLater); - test("testShort"); + public void testShort() { + checkJDK(); + test("testShortSnippet"); } - public static void testByte() { - Object[] values = {(byte) 42, new Exception()}; + public static void testByteSnippet() { + Object[] values = {(byte) 42, (byte) -42, new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Byte.valueOf((byte) 42)); + Assert.assertSame(values[1], Byte.valueOf((byte) -42)); } @Test - public void test5() { - Assume.assumeTrue(isJDK13OrLater); - test("testByte"); + public void testByte() { + checkJDK(); + test("testByteSnippet"); } - public static void testBoolean() { - Object[] values = {true, new Exception()}; + public static void testBooleanSnippet() { + Object[] values = {true, false, new Exception()}; GraalDirectives.deoptimize(); Assert.assertSame(values[0], Boolean.valueOf(true)); + Assert.assertSame(values[1], Boolean.valueOf(false)); } @Test - public void test6() { - Assume.assumeTrue(isJDK13OrLater); - test("testBoolean"); + public void testBoolean() { + checkJDK(); + test("testBooleanSnippet"); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Jul 25 21:51:13 2019 +0000 @@ -24,6 +24,9 @@ package org.graalvm.compiler.hotspot.test; +import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesDecryptName; +import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesEncryptName; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -41,6 +44,7 @@ import org.graalvm.compiler.api.test.Graal; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; +import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; @@ -501,21 +505,17 @@ "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I"); } + boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(config); + String cbcEncryptName = implNames ? "implEncrypt" : "encrypt"; + String cbcDecryptName = implNames ? "implDecrypt" : "decrypt"; + // AES intrinsics if (!config.useAESIntrinsics) { - if (isJDK9OrHigher()) { - add(ignore, - "com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V", - "com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V", - "com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I", - "com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I"); - } else { - add(ignore, - "com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V", - "com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V", - "com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I", - "com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I"); - } + add(ignore, + "com/sun/crypto/provider/AESCrypt." + aesDecryptName + "([BI[BI)V", + "com/sun/crypto/provider/AESCrypt." + aesEncryptName + "([BI[BI)V", + "com/sun/crypto/provider/CipherBlockChaining." + cbcDecryptName + "([BII[BI)I", + "com/sun/crypto/provider/CipherBlockChaining." + cbcEncryptName + "([BII[BI)I"); } // BigInteger intrinsics
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -209,10 +210,9 @@ System.out.println(proc); } - List<Probe> probes = new ArrayList<>(initialProbes); - Probe diagnosticProbe = null; - if (!extraVmArgs.contains("-Dgraal.TruffleCompilationExceptionsAreFatal=true")) { - diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1); + try { + List<Probe> probes = new ArrayList<>(initialProbes); + Probe diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1); probes.add(diagnosticProbe); probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) { @Override @@ -220,22 +220,20 @@ return actualOccurrences > 0 ? null : "expected at least 1 occurrence"; } }); - } - for (String line : proc.output) { - for (Probe probe : probes) { - if (probe.matches(line)) { - break; + for (String line : proc.output) { + for (Probe probe : probes) { + if (probe.matches(line)) { + break; + } } } - } - for (Probe probe : probes) { - String error = probe.test(); - if (error != null) { - Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc)); + for (Probe probe : probes) { + String error = probe.test(); + if (error != null) { + Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc)); + } } - } - if (diagnosticProbe != null) { String line = diagnosticProbe.lastMatchingLine; int substringStart = line.indexOf(diagnosticProbe.substring); int substringLength = diagnosticProbe.substring.length(); @@ -263,8 +261,10 @@ } } finally { zip.delete(); - dumpPath.delete(); } + } finally { + Path directory = dumpPath.toPath(); + removeDirectory(directory); } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompressedOopTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompressedOopTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -313,8 +313,8 @@ Assert.assertTrue(buffer.length() == 28); String a = new String("TestTestTestTestTestTestTest"); installedBenchmarkCode.executeVarargs(buffer, a.toCharArray()); - Assert.assertTrue(buffer.length() == 56); - Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest")); + Assert.assertEquals(56, buffer.length()); + Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", buffer.toString()); } public static void stringBuilderTest(Object c1, Object c2) { @@ -339,8 +339,8 @@ for (int i = 0; i < add.length; i++) { buffer.append(add[i]); } - Assert.assertTrue(buffer.length() == 56); - Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest")); + Assert.assertEquals(56, buffer.length()); + Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", buffer.toString()); } @Test @@ -356,8 +356,8 @@ char[] dst = new char[buffer.length() * 2]; System.arraycopy(buffer.toString().toCharArray(), 0, dst, 0, buffer.length()); System.arraycopy(a.toCharArray(), 0, dst, buffer.length(), buffer.length()); - Assert.assertTrue(dst.length == 56); - Assert.assertTrue(new String(dst).equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest")); + Assert.assertEquals(56, dst.length); + Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", new String(dst)); } @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -35,12 +35,11 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; -import org.junit.Assert; -import org.junit.Test; - import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; +import org.junit.Assert; +import org.junit.Test; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -91,7 +90,10 @@ @Test public void testCipherBlockChainingIntrinsics() throws Exception { - if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", HotSpotGraphBuilderPlugins.cbcEncryptName, HotSpotGraphBuilderPlugins.cbcDecryptName)) { + boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(runtime().getVMConfig()); + String cbcEncryptName = implNames ? "implEncrypt" : "encrypt"; + String cbcDecryptName = implNames ? "implDecrypt" : "decrypt"; + if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, cbcDecryptName)) { ByteArrayOutputStream actual = new ByteArrayOutputStream(); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding")); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -378,12 +378,15 @@ MBeanAttributeInfo dumpPath = findAttributeInfo("DumpPath", info); MBeanAttributeInfo printGraphFile = findAttributeInfo("PrintGraphFile", info); MBeanAttributeInfo showDumpFiles = findAttributeInfo("ShowDumpFiles", info); + MBeanAttributeInfo methodFilter = findAttributeInfo("MethodFilter", info); Object originalDumpPath = server.getAttribute(mbeanName, dumpPath.getName()); Object originalPrintGraphFile = server.getAttribute(mbeanName, printGraphFile.getName()); Object originalShowDumpFiles = server.getAttribute(mbeanName, showDumpFiles.getName()); + Object originalMethodFilter = server.getAttribute(mbeanName, methodFilter.getName()); final File tmpDir = new File(HotSpotGraalManagementTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile(); server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), quoted(tmpDir))); + server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), "")); // Force output to a file even if there's a running IGV instance available. server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), true)); server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), false)); @@ -392,6 +395,7 @@ server.invoke(mbeanName, "dumpMethod", params, null); boolean found = false; String expectedIgvDumpSuffix = "[Arrays.asList(Object[])List].bgv"; + Assert.assertTrue(tmpDir.toString() + " was not created or is not a directory", tmpDir.isDirectory()); List<String> dumpPathEntries = Arrays.asList(tmpDir.list()); for (String entry : dumpPathEntries) { if (entry.endsWith(expectedIgvDumpSuffix)) { @@ -403,8 +407,11 @@ dumpPathEntries.stream().collect(Collectors.joining(System.lineSeparator())))); } } finally { - deleteDirectory(tmpDir.toPath()); + if (tmpDir.isDirectory()) { + deleteDirectory(tmpDir.toPath()); + } server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), originalDumpPath)); + server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), originalMethodFilter)); server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), originalPrintGraphFile)); server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), originalShowDumpFiles)); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -27,9 +27,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; +import java.util.Random; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.hotspot.JVMCIVersionCheck; +import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version; +import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version2; +import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version3; import org.junit.Assert; import org.junit.Test; @@ -43,24 +47,37 @@ props.put(name, sprops.getProperty(name)); } - for (int i = 0; i < 100; i++) { + long seed = Long.getLong("test.seed", System.nanoTime()); + Random random = new Random(seed); + + for (int i = 0; i < 50; i++) { int minMajor = i; - int minMinor = 100 - i; - for (int j = 0; j < 100; j++) { + int minMinor = 50 - i; + for (int j = 0; j < 50; j++) { int major = j; - int minor = 100 - j; + int minor = 50 - j; - boolean ok = (major > minMajor) || (major == minMajor && minor >= minMinor); - for (String sep : new String[]{".", "-b"}) { - String javaVmVersion = String.format("prefix-jvmci-%03d%s%03d-suffix", major, sep, minor); - if (ok) { - JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false); - } else { - try { - JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false); - Assert.fail("expected to fail checking " + javaVmVersion + " against " + minMajor + "." + minMinor); - } catch (InternalError e) { - // pass + for (int k = 0; k < 30; k++) { + int minBuild = random.nextInt(100); + int build = random.nextInt(100); + + for (Version version : new Version[]{new Version2(major, minor), new Version3(major, minor, build)}) { + for (Version minVersion : new Version[]{new Version2(minMajor, minMinor), new Version3(minMajor, minMinor, minBuild)}) { + String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version); + if (!version.isLessThan(minVersion)) { + try { + JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false); + } catch (InternalError e) { + throw new AssertionError("Failed " + JVMCIVersionCheckTest.class.getSimpleName() + " with -Dtest.seed=" + seed, e); + } + } else { + try { + JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false); + Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion + " (-Dtest.seed=" + seed + ")"); + } catch (InternalError e) { + // pass + } + } } } } @@ -72,8 +89,9 @@ for (String version : new String[]{"0" + sep + Long.MAX_VALUE, Long.MAX_VALUE + sep + 0}) { String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version); try { - JVMCIVersionCheck.check(props, 0, 59, "1.8", javaVmVersion, false); - Assert.fail("expected to fail checking " + javaVmVersion + " against 0.59"); + Version2 minVersion = new Version2(0, 59); + JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false); + Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion); } catch (InternalError e) { // pass }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/NodeCostDumpUtil.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/NodeCostDumpUtil.java Thu Jul 25 21:51:13 2019 +0000 @@ -234,4 +234,3 @@ } } -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationContext.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + +package org.graalvm.compiler.hotspot; + +import org.graalvm.compiler.debug.GraalError; + +import jdk.vm.ci.meta.JavaConstant; + +/** + * A context for scoping the lifetime of foreign objects. + * + * The need for this mechanism is best explained with an example. When folding a GETFIELD bytecode + * denoting a {@code final static} non-primitive field, libgraal can create a {@link JavaConstant} + * wrapping a handle to the field's value in the HotSpot heap. This handle must be released before + * HotSpot can reclaim the object it references. Performing a compilation in the scope of a + * {@linkplain HotSpotGraalServices#openLocalCompilationContext local} context ensures the handle is + * released once the compilation completes, allowing the HotSpot GC to subsequently reclaim the + * HotSpot object. When libgraal creates data structures that outlive a single compilation and may + * contain foreign object references (e.g. snippet graphs), it must enter the + * {@linkplain HotSpotGraalServices#enterGlobalCompilationContext global} context. Foreign object + * handles created in the global context are only released once their {@link JavaConstant} wrappers + * are reclaimed by the libgraal GC. + * + * {@link CompilationContext}s have no impact on {@link JavaConstant}s that do not encapsulate a + * foreign object reference. + * + * The object returned by {@link HotSpotGraalServices#enterGlobalCompilationContext} or + * {@link HotSpotGraalServices#openLocalCompilationContext} should be used in a try-with-resources + * statement. Failure to close a context will almost certainly result in foreign objects being + * leaked. + */ +public class CompilationContext implements AutoCloseable { + private final AutoCloseable impl; + + CompilationContext(AutoCloseable impl) { + this.impl = impl; + } + + @Override + public void close() { + try { + impl.close(); + } catch (Exception e) { + GraalError.shouldNotReachHere(e); + } + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationCounters.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationCounters.java Thu Jul 25 21:51:13 2019 +0000 @@ -26,6 +26,7 @@ import static org.graalvm.compiler.hotspot.HotSpotGraalCompiler.fmt; import static org.graalvm.compiler.hotspot.HotSpotGraalCompiler.str; + import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -35,9 +36,10 @@ import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.options.Option; +import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.options.OptionKey; + import jdk.vm.ci.code.CompilationRequest; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -85,7 +87,7 @@ } } TTY.flush(); - System.exit(-1); + HotSpotGraalServices.exit(-1); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Jul 25 21:51:13 2019 +0000 @@ -97,8 +97,13 @@ } @Override + protected void exitHostVM(int status) { + HotSpotGraalServices.exit(status); + } + + @Override public String toString() { - return getMethod().format("%H.%n(%p)"); + return getMethod().format("%H.%n(%p) @ " + getEntryBCI()); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java Thu Jul 25 21:51:13 2019 +0000 @@ -238,7 +238,7 @@ TTY.printf("======================= WATCH DOG THREAD =======================%n" + "%s took %d identical stack traces, which indicates a stuck compilation (id=%d) of %s%n%sExiting VM%n", this, numberOfIdenticalStackTraces, currentId, fmt(currentMethod), fmt(lastStackTrace)); - System.exit(-1); + HotSpotGraalServices.exit(-1); } } else if (newStackTrace) { synchronized (CompilationWatchDog.class) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java Thu Jul 25 21:51:13 2019 +0000 @@ -200,7 +200,7 @@ for (CompilerConfigurationFactory candidate : getAllCandidates()) { System.out.println(" " + candidate.name); } - System.exit(0); + HotSpotGraalServices.exit(0); } else if (value != null) { for (CompilerConfigurationFactory candidate : GraalServices.load(CompilerConfigurationFactory.class)) { if (candidate.name.equals(value)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Jul 25 21:51:13 2019 +0000 @@ -111,39 +111,41 @@ @SuppressWarnings("try") CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault, OptionValues initialOptions) { - if (graalRuntime.isShutdown()) { - return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true); - } + try (CompilationContext scope = HotSpotGraalServices.openLocalCompilationContext(request)) { + if (graalRuntime.isShutdown()) { + return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true); + } - ResolvedJavaMethod method = request.getMethod(); + ResolvedJavaMethod method = request.getMethod(); - if (graalRuntime.isBootstrapping()) { - if (DebugOptions.BootstrapInitializeOnly.getValue(initialOptions)) { - return HotSpotCompilationRequestResult.failure(String.format("Skip compilation because %s is enabled", DebugOptions.BootstrapInitializeOnly.getName()), true); - } - if (bootstrapWatchDog != null) { - if (bootstrapWatchDog.hitCriticalCompilationRateOrTimeout()) { - // Drain the compilation queue to expedite completion of the bootstrap - return HotSpotCompilationRequestResult.failure("hit critical bootstrap compilation rate or timeout", true); + if (graalRuntime.isBootstrapping()) { + if (DebugOptions.BootstrapInitializeOnly.getValue(initialOptions)) { + return HotSpotCompilationRequestResult.failure(String.format("Skip compilation because %s is enabled", DebugOptions.BootstrapInitializeOnly.getName()), true); + } + if (bootstrapWatchDog != null) { + if (bootstrapWatchDog.hitCriticalCompilationRateOrTimeout()) { + // Drain the compilation queue to expedite completion of the bootstrap + return HotSpotCompilationRequestResult.failure("hit critical bootstrap compilation rate or timeout", true); + } } } - } - HotSpotCompilationRequest hsRequest = (HotSpotCompilationRequest) request; - CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, shouldRetainLocalVariables(hsRequest.getJvmciEnv()), installAsDefault); - OptionValues options = task.filterOptions(initialOptions); - try (CompilationWatchDog w1 = CompilationWatchDog.watch(method, hsRequest.getId(), options); - BootstrapWatchDog.Watch w2 = bootstrapWatchDog == null ? null : bootstrapWatchDog.watch(request); - CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(options);) { - if (compilationCounters != null) { - compilationCounters.countCompilation(method); + HotSpotCompilationRequest hsRequest = (HotSpotCompilationRequest) request; + CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, shouldRetainLocalVariables(hsRequest.getJvmciEnv()), installAsDefault); + OptionValues options = task.filterOptions(initialOptions); + try (CompilationWatchDog w1 = CompilationWatchDog.watch(method, hsRequest.getId(), options); + BootstrapWatchDog.Watch w2 = bootstrapWatchDog == null ? null : bootstrapWatchDog.watch(request); + CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(options);) { + if (compilationCounters != null) { + compilationCounters.countCompilation(method); + } + CompilationRequestResult r = null; + try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM); + Activation a = debug.activate()) { + r = task.runCompilation(debug); + } + assert r != null; + return r; } - CompilationRequestResult r = null; - try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM); - Activation a = debug.activate()) { - r = task.runCompilation(debug); - } - assert r != null; - return r; } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalServices.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalServices.java Thu Jul 25 21:51:13 2019 +0000 @@ -26,6 +26,9 @@ import jdk.vm.ci.hotspot.HotSpotMetaData; +/** + * JDK 13 version of {@code HotSpotGraalServices}. + */ public class HotSpotGraalServices { /** @@ -35,4 +38,17 @@ public static byte[] getImplicitExceptionBytes(HotSpotMetaData metaData) { return metaData.implicitExceptionBytes(); } + + public static CompilationContext enterGlobalCompilationContext() { + return null; + } + + @SuppressWarnings("unused") + public static CompilationContext openLocalCompilationContext(Object description) { + return null; + } + + public static void exit(int status) { + System.exit(status); + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java Thu Jul 25 21:51:13 2019 +0000 @@ -208,6 +208,7 @@ return super.getSnippet(method, recursiveEntry, args, trackNodeSourcePosition, replaceePosition, options); } + @SuppressWarnings("try") private StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, Object[] args, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { boolean useEncodedGraphs = UseEncodedGraphs.getValue(options); if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) { @@ -219,11 +220,15 @@ if (getEncodedSnippets() == null) { throw GraalError.shouldNotReachHere("encoded snippets not found"); } - StructuredGraph graph = getEncodedSnippets().getEncodedSnippet(method, this, args, allowAssumptions, options); - if (graph == null) { - throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)")); + // Snippets graphs can contain foreign object reference and + // outlive a single compilation. + try (CompilationContext scope = HotSpotGraalServices.enterGlobalCompilationContext()) { + StructuredGraph graph = getEncodedSnippets().getEncodedSnippet(method, this, args, allowAssumptions, options); + if (graph == null) { + throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)")); + } + return graph; } - return graph; } } else { assert registeredSnippets == null || registeredSnippets.contains(method) : "Asking for snippet method that was never registered: " + method.format("%H.%n(%p)");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -42,6 +42,7 @@ import org.graalvm.compiler.serviceprovider.GraalServices; import org.graalvm.compiler.serviceprovider.ServiceProvider; +import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.services.Services; @@ -96,7 +97,7 @@ * initialization. */ class DelayedOutputStream extends OutputStream { - private volatile OutputStream lazy; + @NativeImageReinitialize private volatile OutputStream lazy; private OutputStream lazy() { if (lazy == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicateBase.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicateBase.java Thu Jul 25 21:51:13 2019 +0000 @@ -43,4 +43,3 @@ return HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.ByHolder; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Thu Jul 25 21:51:13 2019 +0000 @@ -28,6 +28,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API @@ -41,8 +43,107 @@ */ public final class JVMCIVersionCheck { - private static final int JVMCI8_MIN_MAJOR_VERSION = 19; - private static final int JVMCI8_MIN_MINOR_VERSION = 1; + private static final Version JVMCI8_MIN_VERSION = new Version3(19, 2, 1); + + public interface Version { + boolean isLessThan(Version other); + + static Version parse(String vmVersion) { + Matcher m = Pattern.compile(".*-jvmci-(\\d+)\\.(\\d+)-b(\\d+).*").matcher(vmVersion); + if (m.matches()) { + try { + int major = Integer.parseInt(m.group(1)); + int minor = Integer.parseInt(m.group(2)); + int build = Integer.parseInt(m.group(3)); + return new Version3(major, minor, build); + } catch (NumberFormatException e) { + // ignore + } + } + m = Pattern.compile(".*-jvmci-(\\d+)(?:\\.|-b)(\\d+).*").matcher(vmVersion); + if (m.matches()) { + try { + int major = Integer.parseInt(m.group(1)); + int minor = Integer.parseInt(m.group(2)); + return new Version2(major, minor); + } catch (NumberFormatException e) { + // ignore + } + } + return null; + } + } + + public static class Version2 implements Version { + private final int major; + private final int minor; + + public Version2(int major, int minor) { + this.major = major; + this.minor = minor; + } + + @Override + public boolean isLessThan(Version other) { + if (other.getClass() == Version3.class) { + return true; + } + Version2 o = (Version2) other; + if (this.major < o.major) { + return true; + } + if (this.major == o.major && this.minor < o.minor) { + return true; + } + return false; + } + + @Override + public String toString() { + if (major >= 19) { + return String.format("%d-b%02d", major, minor); + } else { + return String.format("%d.%d", major, minor); + } + } + } + + public static class Version3 implements Version { + private final int major; + private final int minor; + private final int build; + + public Version3(int major, int minor, int build) { + this.major = major; + this.minor = minor; + this.build = build; + } + + @Override + public boolean isLessThan(Version other) { + if (other.getClass() == Version2.class) { + return false; + } + Version3 o = (Version3) other; + if (this.major < o.major) { + return true; + } + if (this.major == o.major) { + if (this.minor < o.minor) { + return true; + } + if (this.minor == o.minor && this.build < o.build) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return String.format("%d.%d-b%02d", major, minor, build); + } + } private static void failVersionCheck(Map<String, String> props, boolean exit, String reason, Object... args) { Formatter errorMessage = new Formatter().format(reason, args); @@ -53,9 +154,7 @@ errorMessage.format("Currently used Java home directory is %s.%n", javaHome); errorMessage.format("Currently used VM configuration is: %s%n", vmName); if (props.get("java.specification.version").compareTo("1.9") < 0) { - errorMessage.format("Download the latest JVMCI JDK 8 from " + - "https://www.oracle.com/technetwork/graalvm/downloads/index.html or " + - "https://github.com/graalvm/openjdk8-jvmci-builder/releases"); + errorMessage.format("Download the latest JVMCI JDK 8 from https://github.com/graalvm/openjdk8-jvmci-builder/releases"); } else { errorMessage.format("Download JDK 11 or later."); } @@ -74,7 +173,6 @@ private final String javaSpecVersion; private final String vmVersion; - private int cursor; private final Map<String, String> props; private JVMCIVersionCheck(Map<String, String> props, String javaSpecVersion, String vmVersion) { @@ -85,112 +183,28 @@ static void check(Map<String, String> props, boolean exitOnFailure) { JVMCIVersionCheck checker = new JVMCIVersionCheck(props, props.get("java.specification.version"), props.get("java.vm.version")); - checker.run(exitOnFailure, JVMCI8_MIN_MAJOR_VERSION, JVMCI8_MIN_MINOR_VERSION); + checker.run(exitOnFailure, JVMCI8_MIN_VERSION); } /** * Entry point for testing. */ public static void check(Map<String, String> props, - int jvmci8MinMajorVersion, - int jvmci8MinMinorVersion, + Version minVersion, String javaSpecVersion, - String javaVmVersion, - boolean exitOnFailure) { + String javaVmVersion, boolean exitOnFailure) { JVMCIVersionCheck checker = new JVMCIVersionCheck(props, javaSpecVersion, javaVmVersion); - checker.run(exitOnFailure, jvmci8MinMajorVersion, jvmci8MinMinorVersion); + checker.run(exitOnFailure, minVersion); } - /** - * Parses a positive decimal number at {@link #cursor}. - * - * @return -1 if there is no positive decimal number at {@link #cursor} - */ - private int parseNumber() { - int result = -1; - while (cursor < vmVersion.length()) { - int digit = vmVersion.charAt(cursor) - '0'; - if (digit >= 0 && digit <= 9) { - if (result == -1) { - result = digit; - } else { - long r = (long) result * (long) 10; - if ((int) r != r) { - // Overflow - return -1; - } - result = (int) r + digit; + private void run(boolean exitOnFailure, Version minVersion) { + if (javaSpecVersion.compareTo("1.9") < 0) { + Version v = Version.parse(vmVersion); + if (v != null) { + if (v.isLessThan(minVersion)) { + failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion); } - cursor++; - } else { - break; - } - } - return result; - } - - /** - * Parse {@code "."} or {@code "-b"} at {@link #cursor}. - * - * @return {@code true} iff there was an expected separator at {@link #cursor} - */ - private boolean parseSeparator() { - if (cursor < vmVersion.length()) { - char ch = vmVersion.charAt(cursor); - if (ch == '.') { - cursor++; - return true; - } - if (ch == '-') { - cursor++; - if (cursor < vmVersion.length()) { - if (vmVersion.charAt(cursor) == 'b') { - cursor++; - return true; - } - } - return false; - } - } - return false; - } - - private static String getJVMCIVersionString(int major, int minor) { - if (major >= 19) { - return String.format("%d-b%02d", major, minor); - } else { - return String.format("%d.%d", major, minor); - } - } - - private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8MinMinorVersion) { - // Don't use regular expressions to minimize Graal startup time - if (javaSpecVersion.compareTo("1.9") < 0) { - cursor = vmVersion.indexOf("-jvmci-"); - if (cursor >= 0) { - cursor += "-jvmci-".length(); - int major = parseNumber(); - if (major == -1) { - failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" + - "Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion); - return; - } - - if (parseSeparator()) { - int minor = parseNumber(); - if (minor == -1) { - failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" + - "Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion); - return; - } - - if (major > jvmci8MinMajorVersion || (major >= jvmci8MinMajorVersion && minor >= jvmci8MinMinorVersion)) { - return; - } - failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", - getJVMCIVersionString(major, minor), getJVMCIVersionString(jvmci8MinMajorVersion, jvmci8MinMinorVersion)); - return; - } + return; } failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" + "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -182,7 +182,7 @@ /** * HotSpot implementation of {@link LoweringProvider}. */ -public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider { +public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider { protected final HotSpotGraalRuntimeProvider runtime; protected final HotSpotRegistersProvider registers;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Jul 25 21:51:13 2019 +0000 @@ -44,6 +44,7 @@ import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; +import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode; import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions; @@ -106,6 +107,7 @@ import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.vm.ci.code.CodeUtil; +import jdk.vm.ci.hotspot.VMIntrinsicMethod; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.JavaKind; @@ -429,8 +431,6 @@ r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class); } - public static final String cbcEncryptName; - public static final String cbcDecryptName; public static final String aesEncryptName; public static final String aesDecryptName; @@ -439,15 +439,11 @@ static { if (JavaVersionUtil.JAVA_SPEC <= 8) { - cbcEncryptName = "encrypt"; - cbcDecryptName = "decrypt"; aesEncryptName = "encryptBlock"; aesDecryptName = "decryptBlock"; reflectionClass = "sun.reflect.Reflection"; constantPoolClass = "sun.reflect.ConstantPool"; } else { - cbcEncryptName = "implEncrypt"; - cbcDecryptName = "implDecrypt"; aesEncryptName = "implEncryptBlock"; aesDecryptName = "implDecryptBlock"; reflectionClass = "jdk.internal.reflect.Reflection"; @@ -455,6 +451,19 @@ } } + public static boolean cbcUsesImplNames(GraalHotSpotVMConfig config) { + for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) { + if ("com/sun/crypto/provider/CipherBlockChaining".equals(intrinsic.declaringClass)) { + if ("encrypt".equals(intrinsic.name)) { + return false; + } else if ("implEncrypt".equals(intrinsic.name)) { + return true; + } + } + } + throw GraalError.shouldNotReachHere(); + } + private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) { if (config.useAESIntrinsics) { assert config.aescryptEncryptBlockStub != 0L; @@ -464,9 +473,15 @@ String arch = config.osArch; String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : ""; Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", bytecodeProvider); + + boolean implNames = cbcUsesImplNames(config); + String cbcEncryptName = implNames ? "implEncrypt" : "encrypt"; + String cbcDecryptName = implNames ? "implDecrypt" : "decrypt"; + r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class); r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class); + r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", bytecodeProvider); r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class); r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Thu Jul 25 21:51:13 2019 +0000 @@ -244,4 +244,3 @@ private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag"); } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. 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
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java Thu Jul 25 21:51:13 2019 +0000 @@ -41,7 +41,6 @@ import org.graalvm.compiler.loop.phases.LoopTransformations; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.Verbosity; -import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.EntryMarkerNode; import org.graalvm.compiler.nodes.EntryProxyNode; import org.graalvm.compiler.nodes.FixedGuardNode; @@ -159,11 +158,8 @@ LoopEx loop = loops.loop(l); loop.loopBegin().markOsrLoop(); LoopTransformations.peel(loop); - osr.replaceAtUsages(InputType.Guard, AbstractBeginNode.prevBegin((FixedNode) osr.predecessor())); - for (Node usage : osr.usages().snapshot()) { - EntryProxyNode proxy = (EntryProxyNode) usage; - proxy.replaceAndDelete(proxy.value()); - } + + osr.prepareDelete(); GraphUtil.removeFixedWithUnusedInputs(osr); debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement loop peeling result"); } while (true); @@ -228,6 +224,7 @@ } osr.replaceAtUsages(InputType.Guard, osrStart); + osr.replaceAtUsages(InputType.Anchor, osrStart); } debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement after replacing entry proxies"); GraphUtil.killCFG(start);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java Thu Jul 25 21:51:13 2019 +0000 @@ -191,4 +191,3 @@ println(""); } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Thu Jul 25 21:51:13 2019 +0000 @@ -212,14 +212,27 @@ } @Snippet - public static Object allocateInstance(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, - @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, + public static Object allocateInstance(@ConstantParameter long size, + KlassPointer hub, + Word prototypeMarkWord, + @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, + @ConstantParameter Register threadRegister, + @ConstantParameter boolean constantSize, + @ConstantParameter String typeContext, @ConstantParameter Counters counters) { - return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); + return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters)); } - public static Object allocateInstanceHelper(long size, KlassPointer hub, Word prototypeMarkWord, boolean fillContents, - Register threadRegister, boolean constantSize, String typeContext, Counters counters) { + public static Object allocateInstanceHelper(long size, + KlassPointer hub, + Word prototypeMarkWord, + boolean fillContents, + boolean emitMemoryBarrier, + Register threadRegister, + boolean constantSize, + String typeContext, + Counters counters) { Object result; Word thread = registerAsWord(threadRegister); Word top = readTlabTop(thread); @@ -228,7 +241,7 @@ if (useTLAB(INJECTED_VMCONFIG) && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { writeTlabTop(thread, newTop); emitPrefetchAllocate(newTop, false); - result = formatObject(hub, size, top, prototypeMarkWord, fillContents, constantSize, counters); + result = formatObject(hub, size, top, prototypeMarkWord, fillContents, emitMemoryBarrier, constantSize, counters); } else { Counters theCounters = counters; if (theCounters != null && theCounters.stub != null) { @@ -255,18 +268,27 @@ private static native Object newInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); @Snippet - public static Object allocateInstancePIC(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, - @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, + public static Object allocateInstancePIC(@ConstantParameter long size, + KlassPointer hub, + Word prototypeMarkWord, + @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, + @ConstantParameter Register threadRegister, + @ConstantParameter boolean constantSize, + @ConstantParameter String typeContext, @ConstantParameter Counters counters) { // Klass must be initialized by the time the first instance is allocated, therefore we can // just load it from the corresponding cell and avoid the resolution check. We have to use a // fixed load though, to prevent it from floating above the initialization. KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); - return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); + return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters)); } @Snippet - public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, + public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, + @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, + @ConstantParameter Register threadRegister, @ConstantParameter Counters counters) { if (probability(SLOW_PATH_PROBABILITY, type == null)) { DeoptimizeNode.deopt(None, RuntimeConstraint); @@ -277,10 +299,15 @@ DeoptimizeNode.deopt(None, RuntimeConstraint); } - return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, counters, nonNullType)); + return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, emitMemoryBarrier, threadRegister, counters, nonNullType)); } - private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, Counters counters, Class<?> nonNullType) { + private static Object allocateInstanceDynamicHelper(Class<?> type, + boolean fillContents, + boolean emitMemoryBarrier, + Register threadRegister, + Counters counters, + Class<?> nonNullType) { KlassPointer hub = ClassGetHubNode.readClass(nonNullType); if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor()); @@ -299,7 +326,7 @@ * FIXME(je,ds): we should actually pass typeContext instead of "" but late * binding of parameters is not yet supported by the GraphBuilderPlugin system. */ - return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", counters); + return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, false, "", counters); } } else { DeoptimizeNode.deopt(None, RuntimeConstraint); @@ -320,6 +347,7 @@ @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, @@ -328,7 +356,7 @@ // Primitive array types are eagerly pre-resolved. We can use a floating load. KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub); return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, - threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); + emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); } @Snippet @@ -338,6 +366,7 @@ @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, @@ -346,7 +375,7 @@ // Array type would be resolved by dominating resolution. KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, - threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); + emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); } @Snippet @@ -356,6 +385,7 @@ @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, @@ -367,7 +397,7 @@ headerSize, log2ElementSize, fillContents, - threadRegister, + emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, useBulkZeroing, @@ -384,8 +414,18 @@ return config.areNullAllocationStubsAvailable(); } - private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister, - boolean maybeUnroll, String typeContext, boolean useBulkZeroing, Counters counters) { + private static Object allocateArrayImpl(KlassPointer hub, + int length, + Word prototypeMarkWord, + int headerSize, + int log2ElementSize, + boolean fillContents, + boolean emitMemoryBarrier, + Register threadRegister, + boolean maybeUnroll, + String typeContext, + boolean useBulkZeroing, + Counters counters) { Object result; long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize); Word thread = registerAsWord(threadRegister); @@ -400,7 +440,7 @@ if (theCounters != null && theCounters.arrayLoopInit != null) { theCounters.arrayLoopInit.inc(); } - result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, useBulkZeroing, counters); + result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, useBulkZeroing, counters); } else { result = newArrayStub(hub, length); } @@ -461,19 +501,29 @@ Class<?> voidClass, int length, @ConstantParameter boolean fillContents, + @ConstantParameter boolean emitMemoryBarrier, @ConstantParameter Register threadRegister, @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, @ConstantParameter boolean useBulkZeroing, Word prototypeMarkWord, @ConstantParameter Counters counters) { - Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, + Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, emitMemoryBarrier, threadRegister, knownElementKind, knownLayoutHelper, useBulkZeroing, prototypeMarkWord, counters); return result; } - private static Object allocateArrayDynamicImpl(Class<?> elementType, Class<?> voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind, - int knownLayoutHelper, boolean useBulkZeroing, Word prototypeMarkWord, Counters counters) { + private static Object allocateArrayDynamicImpl(Class<?> elementType, + Class<?> voidClass, + int length, + boolean fillContents, + boolean emitMemoryBarrier, + Register threadRegister, + JavaKind knownElementKind, + int knownLayoutHelper, + boolean useBulkZeroing, + Word prototypeMarkWord, + Counters counters) { /* * We only need the dynamic check for void when we have no static information from * knownElementKind. @@ -516,7 +566,7 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG); Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, - threadRegister, false, "dynamic type", useBulkZeroing, counters); + emitMemoryBarrier, threadRegister, false, "dynamic type", useBulkZeroing, counters); return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length); } @@ -650,7 +700,14 @@ /** * Formats some allocated memory with an object header and zeroes out the rest. */ - private static Object formatObject(KlassPointer hub, long size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, Counters counters) { + private static Object formatObject(KlassPointer hub, + long size, + Word memory, + Word compileTimePrototypeMarkWord, + boolean fillContents, + boolean emitMemoryBarrier, + boolean constantSize, + Counters counters) { Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord; initializeObjectHeader(memory, prototypeMarkWord, hub); if (fillContents) { @@ -658,7 +715,9 @@ } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { fillWithGarbage(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, counters); } - MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); + if (emitMemoryBarrier) { + MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); + } return memory.toObjectNonNull(); } @@ -677,8 +736,17 @@ /** * Formats some allocated memory with an object header and zeroes out the rest. */ - private static Object formatArray(KlassPointer hub, long allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll, - boolean useBulkZeroing, Counters counters) { + private static Object formatArray(KlassPointer hub, + long allocationSize, + int length, + int headerSize, + Word memory, + Word prototypeMarkWord, + boolean fillContents, + boolean emitMemoryBarrier, + boolean maybeUnroll, + boolean useBulkZeroing, + Counters counters) { memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init()); /* * store hub last as the concurrent garbage collectors assume length is valid if hub field @@ -690,7 +758,9 @@ } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { fillWithGarbage(allocationSize, memory, false, headerSize, maybeUnroll, counters); } - MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); + if (emitMemoryBarrier) { + MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); + } return memory.toObjectNonNull(); } @@ -756,6 +826,7 @@ args.add("hub", hub); args.add("prototypeMarkWord", type.prototypeMarkWord()); args.addConst("fillContents", newInstanceNode.fillContents()); + args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("constantSize", true); args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : ""); @@ -799,6 +870,7 @@ args.addConst("headerSize", headerSize); args.addConst("log2ElementSize", log2ElementSize); args.addConst("fillContents", newArrayNode.fillContents()); + args.addConst("emitMemoryBarrier", newArrayNode.emitMemoryBarrier()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("maybeUnroll", length.isConstant()); args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : ""); @@ -816,6 +888,7 @@ assert classClass != null; args.add("classClass", classClass); args.addConst("fillContents", newInstanceNode.fillContents()); + args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("counters", counters); @@ -833,6 +906,7 @@ ValueNode length = newArrayNode.length(); args.add("length", length.isAlive() ? length : graph.addOrUniqueWithInputs(length)); args.addConst("fillContents", newArrayNode.fillContents()); + args.addConst("emitMemoryBarrier", newArrayNode.emitMemoryBarrier()); args.addConst("threadRegister", registers.getThreadRegister()); /* * We use Kind.Illegal as a marker value instead of null because constant snippet
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Jul 25 21:51:13 2019 +0000 @@ -391,7 +391,6 @@ import org.graalvm.compiler.nodes.extended.LoadHubNode; import org.graalvm.compiler.nodes.extended.MembarNode; import org.graalvm.compiler.nodes.extended.StateSplitProxyNode; -import org.graalvm.compiler.nodes.extended.ValueAnchorNode; import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode; @@ -624,7 +623,6 @@ } static class IntrinsicScope extends InliningScope { - StateSplit returnStateSplit; ArrayList<StateSplit> invalidStateUsers; IntrinsicScope(BytecodeParser parser) { @@ -635,6 +633,7 @@ super(parser, callee, args); } + @SuppressWarnings("unlikely-arg-type") @Override public void close() { IntrinsicContext intrinsic = parser.intrinsicContext; @@ -1405,7 +1404,7 @@ if (profile == null || profile.getNotRecordedProbability() > 0.0) { return null; } else { - return append(new ValueAnchorNode(null)); + return BeginNode.prevBegin(lastInstr); } } @@ -4794,6 +4793,9 @@ } } + private static final int SWITCH_DEOPT_UNSEEN = -2; + private static final int SWITCH_DEOPT_SEEN = -1; + private void genSwitch(BytecodeSwitch bs) { int bci = bci(); ValueNode value = frameState.pop(JavaKind.Int); @@ -4811,20 +4813,16 @@ ArrayList<BciBlock> actualSuccessors = new ArrayList<>(); int[] keys = new int[nofCases]; int[] keySuccessors = new int[nofCasesPlusDefault]; - int deoptSuccessorIndex = -1; + int deoptSuccessorIndex = SWITCH_DEOPT_UNSEEN; int nextSuccessorIndex = 0; boolean constantValue = value.isConstant(); for (int i = 0; i < nofCasesPlusDefault; i++) { if (i < nofCases) { keys[i] = bs.keyAt(i); } - if (!constantValue && isNeverExecutedCode(keyProbabilities[i])) { - if (deoptSuccessorIndex < 0) { - deoptSuccessorIndex = nextSuccessorIndex++; - actualSuccessors.add(null); - } - keySuccessors[i] = deoptSuccessorIndex; + deoptSuccessorIndex = SWITCH_DEOPT_SEEN; + keySuccessors[i] = SWITCH_DEOPT_SEEN; } else { int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget(); SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci); @@ -4859,20 +4857,31 @@ * * The following code rewires deoptimization stub to existing resolved branch target if * the target is connected by more than 1 cases. + * + * If this operation rewires every deoptimization seen to an existing branch, care is + * taken that we do not spawn a branch that will never be taken. */ - if (deoptSuccessorIndex >= 0) { - int[] connectedCases = new int[nextSuccessorIndex]; + if (deoptSuccessorIndex == SWITCH_DEOPT_SEEN) { + int[] connectedCases = new int[nextSuccessorIndex + 1]; for (int i = 0; i < nofCasesPlusDefault; i++) { - connectedCases[keySuccessors[i]]++; + connectedCases[keySuccessors[i] + 1]++; } for (int i = 0; i < nofCasesPlusDefault; i++) { - if (keySuccessors[i] == deoptSuccessorIndex) { + if (keySuccessors[i] == SWITCH_DEOPT_SEEN) { int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget(); SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci); int rewiredIndex = info.actualIndex; - if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) { + if (rewiredIndex >= 0 && connectedCases[rewiredIndex + 1] > 1) { + // Rewire keySuccessors[i] = info.actualIndex; + } else { + if (deoptSuccessorIndex == SWITCH_DEOPT_SEEN) { + // Spawn deopt successor if needed. + deoptSuccessorIndex = nextSuccessorIndex++; + actualSuccessors.add(null); + } + keySuccessors[i] = deoptSuccessorIndex; } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Thu Jul 25 21:51:13 2019 +0000 @@ -528,8 +528,8 @@ break; case Object: if (input.isNull()) { - if (crb.mustReplaceWithNullRegister(input)) { - masm.mov(64, dst, crb.nullRegister); + if (crb.mustReplaceWithUncompressedNullRegister(input)) { + masm.mov(64, dst, crb.uncompressedNullRegister); } else { masm.mov(dst, 0); } @@ -725,7 +725,7 @@ @Override public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { - Register nullRegister = crb.nullRegister; + Register nullRegister = crb.uncompressedNullRegister; if (!nullRegister.equals(Register.None)) { emitConversion(asRegister(result), asRegister(input), nullRegister, masm); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java Thu Jul 25 21:51:13 2019 +0000 @@ -645,4 +645,3 @@ return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature); } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java Thu Jul 25 21:51:13 2019 +0000 @@ -213,7 +213,7 @@ masm.cmpq(keyRegister, (AMD64Address) crb.asLongConstRef(jc)); break; case Object: - AMD64Move.const2reg(crb, masm, asRegister(scratch), jc); + AMD64Move.const2reg(crb, masm, asRegister(scratch), jc, AMD64Kind.QWORD); masm.cmpptr(keyRegister, asRegister(scratch)); break; default:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Thu Jul 25 21:51:13 2019 +0000 @@ -156,7 +156,7 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(result)) { - const2reg(crb, masm, asRegister(result), input); + const2reg(crb, masm, asRegister(result), input, (AMD64Kind) result.getPlatformKind()); } else { assert isStackSlot(result); const2stack(crb, masm, result, input); @@ -557,7 +557,7 @@ } } else if (isJavaConstant(input)) { if (isRegister(result)) { - const2reg(crb, masm, asRegister(result), asJavaConstant(input)); + const2reg(crb, masm, asRegister(result), asJavaConstant(input), moveKind); } else if (isStackSlot(result)) { const2stack(crb, masm, result, asJavaConstant(input)); } else { @@ -645,7 +645,7 @@ } } - public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input) { + public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input, AMD64Kind moveKind) { /* * Note: we use the kind of the input operand (and not the kind of the result operand) * because they don't match in all cases. For example, an object constant can be loaded to a @@ -691,20 +691,34 @@ } break; case Object: + assert moveKind != null : "a nun-null moveKind is required for loading an object constant"; // Do not optimize with an XOR as this instruction may be between // a CMP and a Jcc in which case the XOR will modify the condition // flags and interfere with the Jcc. if (input.isNull()) { - if (crb.mustReplaceWithNullRegister(input)) { - masm.movq(result, crb.nullRegister); + if (moveKind == AMD64Kind.QWORD && crb.mustReplaceWithUncompressedNullRegister(input)) { + masm.movq(result, crb.uncompressedNullRegister); } else { + // Upper bits will be zeroed so this also works for narrow oops masm.movslq(result, 0); } - } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(input); - masm.movq(result, 0xDEADDEADDEADDEADL, true); } else { - masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); + if (crb.target.inlineObjects) { + crb.recordInlineDataInCode(input); + if (moveKind == AMD64Kind.DWORD) { + // Support for narrow oops + masm.movl(result, 0xDEADDEAD, true); + } else { + masm.movq(result, 0xDEADDEADDEADDEADL, true); + } + } else { + if (moveKind == AMD64Kind.DWORD) { + // Support for narrow oops + masm.movl(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); + } else { + masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); + } + } } break; default: @@ -752,13 +766,13 @@ break; case Object: if (input.isNull()) { - if (crb.mustReplaceWithNullRegister(input)) { - masm.movq(dest, crb.nullRegister); + if (crb.mustReplaceWithUncompressedNullRegister(input)) { + masm.movq(dest, crb.uncompressedNullRegister); return; } imm = 0; } else { - throw GraalError.shouldNotReachHere("Non-null object constants must be in register"); + throw GraalError.shouldNotReachHere("Non-null object constants must be in a register"); } break; default: @@ -941,7 +955,7 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - Register nullRegister = crb.nullRegister; + Register nullRegister = crb.uncompressedNullRegister; if (!nullRegister.equals(Register.None)) { emitConversion(asRegister(result), asRegister(input), nullRegister, masm); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZapRegistersOp.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZapRegistersOp.java Thu Jul 25 21:51:13 2019 +0000 @@ -34,6 +34,7 @@ import org.graalvm.compiler.lir.asm.CompilationResultBuilder; import org.graalvm.compiler.lir.framemap.FrameMap; +import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.RegisterSaveLayout; import jdk.vm.ci.meta.JavaConstant; @@ -66,7 +67,7 @@ for (int i = 0; i < zappedRegisters.length; i++) { Register reg = zappedRegisters[i]; if (reg != null) { - AMD64Move.const2reg(crb, masm, reg, zapValues[i]); + AMD64Move.const2reg(crb, masm, reg, zapValues[i], AMD64Kind.QWORD); } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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 @@ -35,6 +35,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.asm.amd64.AVXKind; +import org.graalvm.compiler.lir.ConstantValue; import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; @@ -42,6 +43,7 @@ import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; +import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.meta.AllocatableValue; public class AMD64VectorBinary { @@ -102,6 +104,38 @@ } } + public static final class AVXBinaryConstFloatOp extends AMD64LIRInstruction { + + public static final LIRInstructionClass<AVXBinaryConstFloatOp> TYPE = LIRInstructionClass.create(AVXBinaryConstFloatOp.class); + + @Opcode private final VexRVMOp opcode; + private final AVXKind.AVXSize size; + + @Def({REG}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue x; + protected ConstantValue y; + + public AVXBinaryConstFloatOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, ConstantValue y) { + super(TYPE); + assert y.getPlatformKind() == AMD64Kind.SINGLE || y.getPlatformKind() == AMD64Kind.DOUBLE; + this.opcode = opcode; + this.size = size; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (y.getPlatformKind() == AMD64Kind.SINGLE) { + opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asFloatConstRef(y.getJavaConstant())); + } else { + assert y.getPlatformKind() == AMD64Kind.DOUBLE; + opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asDoubleConstRef(y.getJavaConstant())); + } + } + } + public static final class AVXBinaryMemoryOp extends AMD64LIRInstruction { public static final LIRInstructionClass<AVXBinaryMemoryOp> TYPE = LIRInstructionClass.create(AVXBinaryMemoryOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/ConstantStackCastTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/ConstantStackCastTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -99,7 +99,7 @@ } @Test - public void runByte() throws Throwable { + public void runByte() { runTest("testByte", (byte) 0); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/LIRTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/LIRTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -254,7 +254,7 @@ @java.lang.annotation.Retention(RetentionPolicy.RUNTIME) @java.lang.annotation.Target(ElementType.METHOD) - public static @interface LIRIntrinsic { + public @interface LIRIntrinsic { } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/LIRTestTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/LIRTestTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -54,7 +54,7 @@ } @Test - public void runInt() throws Throwable { + public void runInt() { runTest("testGetOutput", Integer.MIN_VALUE, 0, supply(() -> new int[3])); runTest("testGetOutput", -1, Integer.MAX_VALUE, supply(() -> new int[3])); runTest("testGetOutput", 0, 42, supply(() -> new int[3]));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/StackMoveTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/StackMoveTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 @@ -98,7 +98,7 @@ } @Test - public void runInt() throws Throwable { + public void runInt() { runTest("testInt", Integer.MIN_VALUE, supply(() -> new int[4])); runTest("testInt", -1, supply(() -> new int[4])); runTest("testInt", 0, supply(() -> new int[4])); @@ -125,7 +125,7 @@ } @Test - public void runLong() throws Throwable { + public void runLong() { runTest("testLong", Long.MIN_VALUE, supply(() -> new long[3])); runTest("testLong", -1L, supply(() -> new long[3])); runTest("testLong", 0L, supply(() -> new long[3])); @@ -152,7 +152,7 @@ } @Test - public void runFloat() throws Throwable { + public void runFloat() { runTest("testFloat", Float.MIN_VALUE, supply(() -> new float[3])); runTest("testFloat", -1f, supply(() -> new float[3])); runTest("testFloat", -0.1f, supply(() -> new float[3])); @@ -217,7 +217,7 @@ } @Test - public void runShort() throws Throwable { + public void runShort() { runTest("testShort", Short.MIN_VALUE, supply(() -> new short[3])); runTest("testShort", (short) -1, supply(() -> new short[3])); runTest("testShort", (short) 0, supply(() -> new short[3])); @@ -251,7 +251,7 @@ } @Test - public void runByte() throws Throwable { + public void runByte() { runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3])); runTest("testByte", (byte) -1, supply(() -> new byte[3])); runTest("testByte", (byte) 0, supply(() -> new byte[3]));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/StackStoreLoadTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.jtt/src/org/graalvm/compiler/lir/jtt/StackStoreLoadTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -139,7 +139,7 @@ } @Test - public void runByte() throws Throwable { + public void runByte() { runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3])); runTest("testByte", (byte) -1, supply(() -> new byte[3])); runTest("testByte", (byte) 0, supply(() -> new byte[3]));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRVerifier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRVerifier.java Thu Jul 25 21:51:13 2019 +0000 @@ -25,7 +25,7 @@ package org.graalvm.compiler.lir; import static org.graalvm.compiler.lir.LIRValueUtil.asVariable; -import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; +import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue; import static org.graalvm.compiler.lir.LIRValueUtil.isVariable; import static jdk.vm.ci.code.ValueUtil.asRegister; @@ -242,7 +242,7 @@ if ((isVariable(value) && flags.contains(OperandFlag.REG)) || (isRegister(value) && flags.contains(OperandFlag.REG)) || (isStackSlotValue(value) && flags.contains(OperandFlag.STACK)) || - (isJavaConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || + (isConstantValue(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) { return; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/StandardOp.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/StandardOp.java Thu Jul 25 21:51:13 2019 +0000 @@ -35,6 +35,7 @@ import jdk.internal.vm.compiler.collections.EconomicSet; import org.graalvm.compiler.asm.Label; +import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; @@ -154,7 +155,7 @@ @Override public void emitCode(CompilationResultBuilder crb) { if (align) { - crb.asm.align(crb.target.wordSize * 2); + crb.asm.align(GraalOptions.LoopHeaderAlignment.getValue(crb.getOptions())); } crb.asm.bind(label); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java Thu Jul 25 21:51:13 2019 +0000 @@ -127,7 +127,7 @@ public final Assembler asm; public final DataBuilder dataBuilder; public final CompilationResult compilationResult; - public final Register nullRegister; + public final Register uncompressedNullRegister; public final TargetDescription target; public final CodeCacheProvider codeCache; public final ForeignCallsProvider foreignCalls; @@ -171,17 +171,44 @@ */ private boolean conservativeLabelOffsets = false; - public final boolean mustReplaceWithNullRegister(JavaConstant nullConstant) { - return !nullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant); + public final boolean mustReplaceWithUncompressedNullRegister(JavaConstant nullConstant) { + return !uncompressedNullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant); } - public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext, - OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister) { - this(codeCache, foreignCalls, frameMap, asm, dataBuilder, frameContext, options, debug, compilationResult, nullRegister, EconomicMap.create(Equivalence.DEFAULT)); + public CompilationResultBuilder(CodeCacheProvider codeCache, + ForeignCallsProvider foreignCalls, + FrameMap frameMap, + Assembler asm, + DataBuilder dataBuilder, + FrameContext frameContext, + OptionValues options, + DebugContext debug, + CompilationResult compilationResult, + Register uncompressedNullRegister) { + this(codeCache, + foreignCalls, + frameMap, + asm, + dataBuilder, + frameContext, + options, + debug, + compilationResult, + uncompressedNullRegister, + EconomicMap.create(Equivalence.DEFAULT)); } - public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext, - OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister, EconomicMap<Constant, Data> dataCache) { + public CompilationResultBuilder(CodeCacheProvider codeCache, + ForeignCallsProvider foreignCalls, + FrameMap frameMap, + Assembler asm, + DataBuilder dataBuilder, + FrameContext frameContext, + OptionValues options, + DebugContext debug, + CompilationResult compilationResult, + Register uncompressedNullRegister, + EconomicMap<Constant, Data> dataCache) { this.target = codeCache.getTarget(); this.codeCache = codeCache; this.foreignCalls = foreignCalls; @@ -189,7 +216,7 @@ this.asm = asm; this.dataBuilder = dataBuilder; this.compilationResult = compilationResult; - this.nullRegister = nullRegister; + this.uncompressedNullRegister = uncompressedNullRegister; this.frameContext = frameContext; this.options = options; this.debug = debug;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilderFactory.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilderFactory.java Thu Jul 25 21:51:13 2019 +0000 @@ -52,8 +52,8 @@ @Override public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, - FrameContext frameContext, OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister) { - return new CompilationResultBuilder(codeCache, foreignCalls, frameMap, asm, dataBuilder, frameContext, options, debug, compilationResult, nullRegister); + FrameContext frameContext, OptionValues options, DebugContext debug, CompilationResult compilationResult, Register uncompressedNullRegister) { + return new CompilationResultBuilder(codeCache, foreignCalls, frameMap, asm, dataBuilder, frameContext, options, debug, compilationResult, uncompressedNullRegister); } }; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Thu Jul 25 21:51:13 2019 +0000 @@ -60,9 +60,9 @@ import org.graalvm.compiler.lir.StandardOp.BlockEndOp; import org.graalvm.compiler.lir.StandardOp.LabelOp; import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp; -import org.graalvm.compiler.lir.hashing.Hasher; import org.graalvm.compiler.lir.SwitchStrategy; import org.graalvm.compiler.lir.Variable; +import org.graalvm.compiler.lir.hashing.Hasher; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; @@ -230,11 +230,31 @@ } @Override + public Variable emitReadRegister(Register register, ValueKind<?> kind) { + return emitMove(register.asValue(kind)); + } + + @Override + public void emitWriteRegister(Register dst, Value src, ValueKind<?> kind) { + emitMove(dst.asValue(kind), src); + } + + @Override public void emitMoveConstant(AllocatableValue dst, Constant src) { append(moveFactory.createLoad(dst, src)); } @Override + public boolean canInlineConstant(Constant constant) { + return moveFactory.canInlineConstant(constant); + } + + @Override + public boolean mayEmbedConstantLoad(Constant constant) { + return moveFactory.mayEmbedConstantLoad(constant); + } + + @Override public Value emitConstant(LIRKind kind, Constant constant) { if (moveFactory.canInlineConstant(constant)) { return new ConstantValue(toRegisterKind(kind), constant);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Thu Jul 25 21:51:13 2019 +0000 @@ -65,14 +65,22 @@ interface MoveFactory { /** + * Checks whether the loading of the supplied constant can be deferred until usage. + */ + @SuppressWarnings("unused") + default boolean mayEmbedConstantLoad(Constant constant) { + return false; + } + + /** * Checks whether the supplied constant can be used without loading it into a register for * most operations, i.e., for commonly used arithmetic, logical, and comparison operations. * - * @param c The constant to check. + * @param constant The constant to check. * @return True if the constant can be used directly, false if the constant needs to be in a * register. */ - boolean canInlineConstant(Constant c); + boolean canInlineConstant(Constant constant); /** * @param constant The constant that might be moved to a stack slot. @@ -130,6 +138,10 @@ BlockScope getBlockScope(AbstractBlockBase<?> block); + boolean canInlineConstant(Constant constant); + + boolean mayEmbedConstantLoad(Constant constant); + Value emitConstant(LIRKind kind, Constant constant); Value emitJavaConstant(JavaConstant constant); @@ -192,6 +204,10 @@ void emitMove(AllocatableValue dst, Value src); + Variable emitReadRegister(Register register, ValueKind<?> kind); + + void emitWriteRegister(Register dst, Value src, ValueKind<?> wordStamp); + void emitMoveConstant(AllocatableValue dst, Constant src); Variable emitAddress(AllocatableValue stackslot);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/ssa/SSAVerifier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/ssa/SSAVerifier.java Thu Jul 25 21:51:13 2019 +0000 @@ -26,7 +26,7 @@ package org.graalvm.compiler.lir.ssa; import static jdk.vm.ci.code.ValueUtil.isRegister; -import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; +import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue; import java.util.BitSet; @@ -137,7 +137,7 @@ } private static boolean shouldProcess(Value value) { - return !value.equals(Value.ILLEGAL) && !isJavaConstant(value) && !isRegister(value) && !isStackSlotValue(value); + return !value.equals(Value.ILLEGAL) && !isConstantValue(value) && !isRegister(value) && !isStackSlotValue(value); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -26,7 +26,9 @@ import java.util.ListIterator; +import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.core.common.CompilationIdentifier; +import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.iterators.NodeIterable; @@ -216,6 +218,25 @@ test("testSignExtensionSnippet", 9L); } + public static Object objectPhi(int n) { + Integer v = Integer.valueOf(200); + GraalDirectives.blackhole(v); // Prevents PEA + Integer r = 1; + + for (int i = 0; iterationCount(100, i < n); i++) { + GraalDirectives.blackhole(r); // Create a phi of two loop invariants + r = v; + } + + return r; + } + + @Test + public void testObjectPhi() { + OptionValues options = new OptionValues(getInitialOptions(), GraalOptions.LoopPeeling, false); + test(options, "objectPhi", 1); + } + @Override protected Suites createSuites(OptionValues opts) { Suites suites = super.createSuites(opts).copy();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. 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 @@ -344,7 +344,7 @@ } } } - LoopFragment.computeNodes(branchNodes, branch.graph(), blocks, exits); + LoopFragment.computeNodes(branchNodes, branch.graph(), this, blocks, exits); } public EconomicMap<Node, InductionVariable> getInductionVariables() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. 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 @@ -25,12 +25,11 @@ package org.graalvm.compiler.loop; import java.util.ArrayDeque; -import java.util.Collections; import java.util.Deque; import java.util.Iterator; import jdk.internal.vm.compiler.collections.EconomicMap; -import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph; import org.graalvm.compiler.graph.Graph; import org.graalvm.compiler.graph.Graph.DuplicationReplacement; import org.graalvm.compiler.graph.Node; @@ -42,18 +41,15 @@ import org.graalvm.compiler.nodes.FixedNode; import org.graalvm.compiler.nodes.FrameState; import org.graalvm.compiler.nodes.GuardNode; -import org.graalvm.compiler.nodes.GuardPhiNode; import org.graalvm.compiler.nodes.GuardProxyNode; import org.graalvm.compiler.nodes.Invoke; +import org.graalvm.compiler.nodes.LoopBeginNode; import org.graalvm.compiler.nodes.LoopExitNode; import org.graalvm.compiler.nodes.MergeNode; -import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.PhiNode; import org.graalvm.compiler.nodes.ProxyNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.ValuePhiNode; -import org.graalvm.compiler.nodes.ValueProxyNode; import org.graalvm.compiler.nodes.VirtualState; import org.graalvm.compiler.nodes.cfg.Block; import org.graalvm.compiler.nodes.cfg.ControlFlowGraph; @@ -199,17 +195,7 @@ } } - protected static NodeBitMap computeNodes(Graph graph, Iterable<AbstractBeginNode> blocks) { - return computeNodes(graph, blocks, Collections.emptyList()); - } - - protected static NodeBitMap computeNodes(Graph graph, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) { - final NodeBitMap nodes = graph.createNodeBitMap(); - computeNodes(nodes, graph, blocks, earlyExits); - return nodes; - } - - protected static void computeNodes(NodeBitMap nodes, Graph graph, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) { + protected static void computeNodes(NodeBitMap nodes, Graph graph, LoopEx loop, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) { for (AbstractBeginNode b : blocks) { if (b.isDeleted()) { continue; @@ -261,11 +247,11 @@ for (Node n : b.getBlockNodes()) { if (n instanceof CommitAllocationNode) { for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) { - markFloating(worklist, obj, nodes, nonLoopNodes); + markFloating(worklist, loop, obj, nodes, nonLoopNodes); } } if (n instanceof MonitorEnterNode) { - markFloating(worklist, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes); + markFloating(worklist, loop, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes); } if (n instanceof AbstractMergeNode) { /* @@ -274,12 +260,12 @@ */ for (PhiNode phi : ((AbstractMergeNode) n).phis()) { for (Node usage : phi.usages()) { - markFloating(worklist, usage, nodes, nonLoopNodes); + markFloating(worklist, loop, usage, nodes, nonLoopNodes); } } } for (Node usage : n.usages()) { - markFloating(worklist, usage, nodes, nonLoopNodes); + markFloating(worklist, loop, usage, nodes, nonLoopNodes); } } } @@ -331,10 +317,14 @@ workList.push(entry); } - private static void markFloating(Deque<WorkListEntry> workList, Node start, NodeBitMap loopNodes, NodeBitMap nonLoopNodes) { + private static void markFloating(Deque<WorkListEntry> workList, LoopEx loop, Node start, NodeBitMap loopNodes, NodeBitMap nonLoopNodes) { if (isLoopNode(start, loopNodes, nonLoopNodes).isKnown()) { return; } + + LoopBeginNode loopBeginNode = loop.loopBegin(); + ControlFlowGraph cfg = loop.loopsData().getCFG(); + pushWorkList(workList, start, loopNodes); while (!workList.isEmpty()) { WorkListEntry currentEntry = workList.peek(); @@ -352,13 +342,27 @@ workList.pop(); boolean isLoopNode = currentEntry.isLoopNode; Node current = currentEntry.n; - if (!isLoopNode && current instanceof GuardNode) { - /* - * (gd) this is only OK if we are not going to make loop transforms based on - * this - */ - assert !((GuardNode) current).graph().hasValueProxies(); - isLoopNode = true; + if (!isLoopNode && current instanceof GuardNode && !current.hasUsages()) { + GuardNode guard = (GuardNode) current; + if (isLoopNode(guard.getCondition(), loopNodes, nonLoopNodes) != TriState.FALSE) { + ValueNode anchor = guard.getAnchor().asNode(); + TriState isAnchorInLoop = isLoopNode(anchor, loopNodes, nonLoopNodes); + if (isAnchorInLoop != TriState.FALSE) { + if (!(anchor instanceof LoopExitNode && ((LoopExitNode) anchor).loopBegin() == loopBeginNode)) { + /* + * (gd) this is wrong in general, it's completely avoidable while we + * are doing loop transforms using ValueProxies. If it happens after + * it could still cause problem. + */ + assert !((GuardNode) current).graph().hasValueProxies(); + isLoopNode = true; + } + } else if (AbstractControlFlowGraph.strictlyDominates(cfg.blockFor(anchor), cfg.blockFor(loopBeginNode))) { + // The anchor is above the loop. The no-usage guard can potentially be + // scheduled inside the loop. + isLoopNode = true; + } + } } if (isLoopNode) { loopNodes.mark(current); @@ -467,14 +471,7 @@ final ValueNode replaceWith; ValueNode newVpn = prim(newEarlyExitIsLoopExit ? vpn : vpn.value()); if (newVpn != null) { - PhiNode phi; - if (vpn instanceof ValueProxyNode) { - phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(NodeView.DEFAULT), merge)); - } else if (vpn instanceof GuardProxyNode) { - phi = graph.addWithoutUnique(new GuardPhiNode(merge)); - } else { - throw GraalError.shouldNotReachHere(); - } + PhiNode phi = vpn.createPhi(merge); phi.addInput(vpn); phi.addInput(newVpn); replaceWith = phi;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Thu Jul 25 21:51:13 2019 +0000 @@ -169,12 +169,13 @@ LoopBeginNode mainLoopBegin = loop.loopBegin(); ArrayList<ValueNode> backedgeValues = new ArrayList<>(); for (PhiNode mainPhiNode : mainLoopBegin.phis()) { - ValueNode duplicatedNode = getDuplicatedNode(mainPhiNode.valueAt(1)); + ValueNode originalNode = mainPhiNode.valueAt(1); + ValueNode duplicatedNode = getDuplicatedNode(originalNode); if (duplicatedNode == null) { - if (mainLoopBegin.isPhiAtMerge(mainPhiNode.valueAt(1))) { - duplicatedNode = ((PhiNode) (mainPhiNode.valueAt(1))).valueAt(1); + if (mainLoopBegin.isPhiAtMerge(originalNode)) { + duplicatedNode = ((PhiNode) (originalNode)).valueAt(1); } else { - assert mainPhiNode.valueAt(1).isConstant() : mainPhiNode.valueAt(1); + assert originalNode.isConstant() || loop.isOutsideLoop(originalNode) : "Not duplicated node " + originalNode; } } backedgeValues.add(duplicatedNode);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentWhole.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentWhole.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. 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 @@ -64,7 +64,9 @@ public NodeBitMap nodes() { if (nodes == null) { Loop<Block> loop = loop().loop(); - nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(loop.getBlocks()), LoopFragment.toHirBlocks(loop.getLoopExits())); + NodeBitMap loopNodes = graph().createNodeBitMap(); + LoopFragment.computeNodes(loopNodes, graph(), loop(), LoopFragment.toHirBlocks(loop.getBlocks()), LoopFragment.toHirBlocks(loop.getLoopExits())); + nodes = loopNodes; } return nodes; } @@ -110,7 +112,6 @@ @Override public void insertBefore(LoopEx loop) { - // TODO Auto-generated method stub - + // nothing to do } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -59,21 +59,20 @@ Node next = from; while (next != null) { if (next instanceof AbstractBeginNode) { - AbstractBeginNode begin = (AbstractBeginNode) next; - return begin; + return (AbstractBeginNode) next; } next = next.predecessor(); } return null; } - private void evacuateGuards(FixedNode evacuateFrom) { + private void evacuateAnchored(FixedNode evacuateFrom) { if (!hasNoUsages()) { AbstractBeginNode prevBegin = prevBegin(evacuateFrom); assert prevBegin != null; - for (Node anchored : anchored().snapshot()) { - anchored.replaceFirstInput(this, prevBegin); - } + replaceAtUsages(InputType.Anchor, prevBegin); + replaceAtUsages(InputType.Guard, prevBegin); + assert anchored().isEmpty() : anchored().snapshot(); } } @@ -82,7 +81,7 @@ } public void prepareDelete(FixedNode evacuateFrom) { - evacuateGuards(evacuateFrom); + evacuateAnchored(evacuateFrom); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. 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 @@ -38,11 +38,14 @@ import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.NodeMap; import org.graalvm.compiler.graph.iterators.NodeIterable; import org.graalvm.compiler.lir.ConstantValue; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.calc.FloatingNode; +import org.graalvm.compiler.nodes.cfg.Block; import org.graalvm.compiler.nodes.spi.ArrayLengthProvider; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; @@ -143,14 +146,32 @@ @Override public void generate(NodeLIRBuilderTool gen) { - LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT)); + LIRGeneratorTool lirTool = gen.getLIRGeneratorTool(); + LIRKind kind = lirTool.getLIRKind(stamp(NodeView.DEFAULT)); if (onlyUsedInVirtualState()) { gen.setResult(this, new ConstantValue(kind, value)); + } else if (lirTool.canInlineConstant(value) || (lirTool.mayEmbedConstantLoad(value) && hasExactlyOneUsage() && onlyUsedInCurrentBlock())) { + gen.setResult(this, new ConstantValue(lirTool.toRegisterKind(kind), value)); } else { gen.setResult(this, gen.getLIRGeneratorTool().emitConstant(kind, value)); } } + /** + * Expecting false for loop invariant. + */ + private boolean onlyUsedInCurrentBlock() { + assert graph().getLastSchedule() != null; + NodeMap<Block> nodeBlockMap = graph().getLastSchedule().getNodeToBlockMap(); + Block currentBlock = nodeBlockMap.get(this); + for (Node usage : usages()) { + if (currentBlock != nodeBlockMap.get(usage)) { + return false; + } + } + return true; + } + private boolean onlyUsedInVirtualState() { for (Node n : this.usages()) { if (n instanceof VirtualState) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryMarkerNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryMarkerNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -30,7 +30,9 @@ import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.IterableNodeType; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.iterators.NodeIterable; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; @@ -51,4 +53,24 @@ public void generate(NodeLIRBuilderTool gen) { throw new GraalError("OnStackReplacementNode should not survive"); } + + @Override + public NodeIterable<Node> anchored() { + return super.anchored().filter(n -> { + if (n instanceof EntryProxyNode) { + EntryProxyNode proxyNode = (EntryProxyNode) n; + return proxyNode.proxyPoint != this; + } + return true; + }); + } + + @Override + public void prepareDelete(FixedNode evacuateFrom) { + for (Node usage : usages().filter(EntryProxyNode.class).snapshot()) { + EntryProxyNode proxy = (EntryProxyNode) usage; + proxy.replaceAndDelete(proxy.value()); + } + super.prepareDelete(evacuateFrom); + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedGuardNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedGuardNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -30,19 +30,22 @@ import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.graph.IterableNodeType; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.nodes.spi.SwitchFoldable; import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.DeoptimizationReason; import jdk.vm.ci.meta.SpeculationLog; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}", allowedUsageTypes = Guard, size = SIZE_2, cycles = CYCLES_2) -public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType { +public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType, SwitchFoldable { public static final NodeClass<FixedGuardNode> TYPE = NodeClass.create(FixedGuardNode.class); public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { @@ -115,4 +118,92 @@ public boolean canDeoptimize() { return true; } + + @Override + public Node getNextSwitchFoldableBranch() { + return next(); + } + + @Override + public boolean isInSwitch(ValueNode switchValue) { + return hasNoUsages() && isNegated() && SwitchFoldable.maybeIsInSwitch(condition()) && SwitchFoldable.sameSwitchValue(condition(), switchValue); + } + + @Override + public void cutOffCascadeNode() { + /* nop */ + } + + @Override + public void cutOffLowestCascadeNode() { + setNext(null); + } + + @Override + public boolean isDefaultSuccessor(AbstractBeginNode beginNode) { + return beginNode.next() == next(); + } + + @Override + public AbstractBeginNode getDefault() { + FixedNode defaultNode = next(); + setNext(null); + return BeginNode.begin(defaultNode); + } + + @Override + public ValueNode switchValue() { + if (SwitchFoldable.maybeIsInSwitch(condition())) { + return ((IntegerEqualsNode) condition()).getX(); + } + return null; + } + + @Override + public boolean isNonInitializedProfile() { + // @formatter:off + // Checkstyle: stop + /* + * These nodes can appear in non initialized cascades. Though they are technically profiled + * nodes, their presence does not really prevent us from constructing a uniform distribution + * for the new switch, while keeping these to probability 0. Furthermore, these can be the + * result of the pattern: + * if (c) { + * CompilerDirectives.transferToInterpreter(); + * } + * Since we cannot differentiate this case from, say, a guard created because profiling + * determined that the branch was never taken, and given what we saw before, we will + * consider all fixedGuards as nodes with no profiles for switch folding purposes. + */ + // Checkstyle: resume + // @formatter:on + return true; + } + + @Override + public int intKeyAt(int i) { + assert i == 0; + return ((IntegerEqualsNode) condition()).getY().asJavaConstant().asInt(); + } + + @Override + public double keyProbability(int i) { + return 0; + } + + @Override + public AbstractBeginNode keySuccessor(int i) { + DeoptimizeNode deopt = new DeoptimizeNode(getAction(), getReason(), getSpeculation()); + deopt.setNodeSourcePosition(getNodeSourcePosition()); + AbstractBeginNode begin = new BeginNode(); + // Link the two nodes, but do not add them to the graph yet, so we do not need to remove + // them on an abort. + begin.next = deopt; + return begin; + } + + @Override + public double defaultProbability() { + return 1.0d; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Thu Jul 25 21:51:13 2019 +0000 @@ -319,7 +319,7 @@ public static final NodeClass<ProxyPlaceholder> TYPE = NodeClass.create(ProxyPlaceholder.class); @Input ValueNode value; - @Input(InputType.Unchecked) Node proxyPoint; + @Input(InputType.Association) Node proxyPoint; public ProxyPlaceholder(ValueNode value, MergeNode proxyPoint) { super(TYPE, value.stamp(NodeView.DEFAULT)); @@ -884,14 +884,7 @@ if (!merge.isPhiAtMerge(existing)) { /* Now we have two different values, so we need to create a phi node. */ - PhiNode phi; - if (proxy instanceof ValueProxyNode) { - phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(NodeView.DEFAULT), merge)); - } else if (proxy instanceof GuardProxyNode) { - phi = graph.addWithoutUnique(new GuardPhiNode(merge)); - } else { - throw GraalError.shouldNotReachHere(); - } + PhiNode phi = proxy.createPhi(merge); /* Add the inputs from all previous exits. */ for (int j = 0; j < merge.phiPredecessorCount() - 1; j++) { phi.addInput(existing); @@ -1336,6 +1329,11 @@ * @param methodScope The current method. */ protected void cleanupGraph(MethodScope methodScope) { + for (MergeNode merge : graph.getNodes(MergeNode.TYPE)) { + for (ProxyPlaceholder placeholder : merge.usages().filter(ProxyPlaceholder.class).snapshot()) { + placeholder.replaceAndDelete(placeholder.value); + } + } assert verifyEdges(); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardProxyNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardProxyNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -62,6 +62,11 @@ } @Override + public PhiNode createPhi(AbstractMergeNode merge) { + return graph().addWithoutUnique(new GuardPhiNode(merge)); + } + + @Override public Node getOriginalNode() { return (value == null ? null : value.asNode()); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -42,6 +42,7 @@ import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.core.common.type.PrimitiveStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.debug.CounterKey; @@ -71,8 +72,10 @@ import org.graalvm.compiler.nodes.java.LoadFieldNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.nodes.spi.SwitchFoldable; import org.graalvm.compiler.nodes.util.GraphUtil; +import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; @@ -87,7 +90,7 @@ * of a comparison. */ @NodeInfo(cycles = CYCLES_1, size = SIZE_2, sizeRationale = "2 jmps") -public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable { +public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, SwitchFoldable { public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class); private static final CounterKey CORRECTED_PROBABILITIES = DebugContext.counter("CorrectedProbabilities"); @@ -297,6 +300,10 @@ return; } + if (switchTransformationOptimization(tool)) { + return; + } + if (falseSuccessor().hasNoUsages() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode && !(((IfNode) falseSuccessor().next()).falseSuccessor() instanceof LoopExitNode)) { AbstractBeginNode intermediateBegin = falseSuccessor(); @@ -454,6 +461,70 @@ return true; } + // SwitchFoldable implementation. + + @Override + public Node getNextSwitchFoldableBranch() { + return falseSuccessor(); + } + + @Override + public boolean isInSwitch(ValueNode switchValue) { + return SwitchFoldable.maybeIsInSwitch(condition()) && SwitchFoldable.sameSwitchValue(condition(), switchValue); + } + + @Override + public void cutOffCascadeNode() { + setTrueSuccessor(null); + } + + @Override + public void cutOffLowestCascadeNode() { + setFalseSuccessor(null); + setTrueSuccessor(null); + } + + @Override + public AbstractBeginNode getDefault() { + return falseSuccessor(); + } + + @Override + public ValueNode switchValue() { + if (SwitchFoldable.maybeIsInSwitch(condition())) { + return ((IntegerEqualsNode) condition()).getX(); + } + return null; + } + + @Override + public boolean isNonInitializedProfile() { + return getTrueSuccessorProbability() == 0.5d; + } + + @Override + public int intKeyAt(int i) { + assert i == 0; + return ((IntegerEqualsNode) condition()).getY().asJavaConstant().asInt(); + } + + @Override + public double keyProbability(int i) { + assert i == 0; + return getTrueSuccessorProbability(); + } + + @Override + public AbstractBeginNode keySuccessor(int i) { + assert i == 0; + return trueSuccessor(); + } + + @Override + public double defaultProbability() { + return 1.0d - getTrueSuccessorProbability(); + } + /** * Try to optimize this as if it were a {@link ConditionalNode}. */ @@ -606,6 +677,50 @@ } } } + } else if (y instanceof PrimitiveConstant && ((PrimitiveConstant) y).asLong() < 0 && falseSuccessor().next() instanceof IfNode) { + IfNode ifNode2 = (IfNode) falseSuccessor().next(); + AbstractBeginNode falseSucc = ifNode2.falseSuccessor(); + AbstractBeginNode trueSucc = ifNode2.trueSuccessor(); + IntegerBelowNode below = null; + if (ifNode2.condition() instanceof IntegerLessThanNode) { + ValueNode x = lessThan.getX(); + IntegerLessThanNode lessThan2 = (IntegerLessThanNode) ifNode2.condition(); + /* + * Convert x >= -C1 && x < C2, represented as !(x < -C1) && x < C2, into an + * unsigned compare. This condition is equivalent to x + C1 |<| C1 + C2 if C1 + + * C2 does not overflow. + */ + Constant c2 = lessThan2.getY().stamp(view).asConstant(); + if (lessThan2.getX() == x && c2 instanceof PrimitiveConstant && ((PrimitiveConstant) c2).asLong() > 0 && + x.stamp(view).isCompatible(lessThan.getY().stamp(view)) && + x.stamp(view).isCompatible(lessThan2.getY().stamp(view)) && + sameDestination(trueSuccessor(), ifNode2.falseSuccessor)) { + long newLimitValue = -((PrimitiveConstant) y).asLong() + ((PrimitiveConstant) c2).asLong(); + // Make sure the limit fits into the target type without overflow. + if (newLimitValue > 0 && newLimitValue <= CodeUtil.maxValue(PrimitiveStamp.getBits(x.stamp(view)))) { + ConstantNode newLimit = ConstantNode.forIntegerStamp(x.stamp(view), newLimitValue, graph()); + ConstantNode c1 = ConstantNode.forIntegerStamp(x.stamp(view), -((PrimitiveConstant) y).asLong(), graph()); + ValueNode addNode = graph().addOrUniqueWithInputs(AddNode.create(x, c1, view)); + below = graph().unique(new IntegerBelowNode(addNode, newLimit)); + } + } + } + if (below != null) { + try (DebugCloseable position = ifNode2.withNodeSourcePosition()) { + ifNode2.setTrueSuccessor(null); + ifNode2.setFalseSuccessor(null); + + IfNode newIfNode = graph().add(new IfNode(below, trueSucc, falseSucc, trueSuccessorProbability)); + // Remove the < -C1 test. + tool.deleteBranch(trueSuccessor); + graph().removeSplit(this, falseSuccessor); + + // Replace the second test with the new one. + ifNode2.predecessor().replaceFirstSuccessor(ifNode2, newIfNode); + ifNode2.safeDelete(); + return true; + } + } } } return false; @@ -1268,8 +1383,7 @@ private MergeNode insertMerge(AbstractBeginNode begin, FrameState stateAfter) { MergeNode merge = graph().add(new MergeNode()); if (!begin.anchored().isEmpty()) { - Object before = null; - before = begin.anchored().snapshot(); + Object before = begin.anchored().snapshot(); begin.replaceAtUsages(InputType.Guard, merge); begin.replaceAtUsages(InputType.Anchor, merge); assert begin.anchored().isEmpty() : before + " " + begin.anchored().snapshot();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -75,4 +75,6 @@ public static GuardProxyNode forGuard(GuardingNode value, LoopExitNode exit, StructuredGraph graph) { return graph.unique(new GuardProxyNode(value, exit)); } + + public abstract PhiNode createPhi(AbstractMergeNode merge); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -54,6 +54,11 @@ } @Override + public PhiNode createPhi(AbstractMergeNode merge) { + return graph().addWithoutUnique(new ValuePhiNode(stamp(NodeView.DEFAULT), merge)); + } + + @Override public boolean inferStamp() { return updateStamp(value.stamp(NodeView.DEFAULT)); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -117,10 +117,7 @@ return false; } - int compareAgainstZero = 0; - int usageCount = self.getUsageCount(); - for (int i = 0; i < usageCount; i++) { - Node usage = self.getUsageAt(i); + for (Node usage : self.usages()) { if (usage instanceof IntegerEqualsNode) { IntegerEqualsNode equalsNode = (IntegerEqualsNode) usage; ValueNode node = equalsNode.getY(); @@ -131,12 +128,13 @@ ConstantNode constantNode = (ConstantNode) node; Constant constant = constantNode.asConstant(); if (constant instanceof PrimitiveConstant && ((PrimitiveConstant) constant).asLong() == 0) { - compareAgainstZero++; + continue; } } } + return false; } - return compareAgainstZero == usageCount; + return true; } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -32,8 +32,11 @@ import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.iterators.NodePredicates; +import org.graalvm.compiler.graph.spi.Canonicalizable; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -56,7 +59,7 @@ * intended primarily for snippets, so that they can define their fast and slow paths. */ @NodeInfo(cycles = CYCLES_0, cyclesRationale = "Artificial Node", size = SIZE_0) -public final class BranchProbabilityNode extends FloatingNode implements Simplifiable, Lowerable { +public final class BranchProbabilityNode extends FloatingNode implements Simplifiable, Lowerable, Canonicalizable { public static final NodeClass<BranchProbabilityNode> TYPE = NodeClass.create(BranchProbabilityNode.class); public static final double LIKELY_PROBABILITY = 0.6; @@ -98,6 +101,15 @@ } @Override + public Node canonical(CanonicalizerTool tool) { + if (condition.isConstant()) { + // fold constant conditions early during PE + return condition; + } + return this; + } + + @Override public void simplify(SimplifierTool tool) { if (!hasUsages()) { return;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -36,6 +36,7 @@ import org.graalvm.compiler.core.common.type.PrimitiveStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; @@ -51,6 +52,7 @@ import org.graalvm.compiler.nodes.java.LoadIndexedNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.nodes.spi.SwitchFoldable; import org.graalvm.compiler.nodes.util.GraphUtil; import jdk.vm.ci.meta.DeoptimizationAction; @@ -63,7 +65,7 @@ * values. The actual implementation of the switch will be decided by the backend. */ @NodeInfo -public final class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { +public final class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable, SwitchFoldable { public static final NodeClass<IntegerSwitchNode> TYPE = NodeClass.create(IntegerSwitchNode.class); protected final int[] keys; @@ -75,6 +77,7 @@ this.keys = keys; assert value.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger(); assert assertSorted(); + assert assertNoUntargettedSuccessor(); } private boolean assertSorted() { @@ -84,6 +87,18 @@ return true; } + private boolean assertNoUntargettedSuccessor() { + boolean[] checker = new boolean[successors.size()]; + for (int successorIndex : keySuccessors) { + checker[successorIndex] = true; + } + checker[defaultSuccessorIndex()] = true; + for (boolean b : checker) { + assert b; + } + return true; + } + public IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) { this(value, new AbstractBeginNode[successorCount], keys, keyProbabilities, keySuccessors); } @@ -104,6 +119,14 @@ return JavaConstant.forInt(keys[i]); } + /** + * Gets the key at the specified index, as a java int. + */ + @Override + public int intKeyAt(int i) { + return keys[i]; + } + @Override public int keyCount() { return keys.length; @@ -148,9 +171,63 @@ return; } else if (tryRemoveUnreachableKeys(tool, value().stamp(view))) { return; + } else if (switchTransformationOptimization(tool)) { + return; } } + private void addSuccessorForDeletion(AbstractBeginNode defaultNode) { + successors.add(defaultNode); + } + + @Override + public Node getNextSwitchFoldableBranch() { + return defaultSuccessor(); + } + + @Override + public boolean isInSwitch(ValueNode switchValue) { + return value == switchValue; + } + + @Override + public void cutOffCascadeNode() { + AbstractBeginNode toKill = defaultSuccessor(); + clearSuccessors(); + addSuccessorForDeletion(toKill); + } + + @Override + public void cutOffLowestCascadeNode() { + clearSuccessors(); + } + + @Override + public AbstractBeginNode getDefault() { + return defaultSuccessor(); + } + + @Override + public ValueNode switchValue() { + return value(); + } + + @Override + public boolean isNonInitializedProfile() { + int nbSuccessors = getSuccessorCount(); + double prob = 0.0d; + for (int i = 0; i < nbSuccessors; i++) { + if (keyProbabilities[i] > 0.0d) { + if (prob == 0.0d) { + prob = keyProbabilities[i]; + } else if (keyProbabilities[i] != prob) { + return false; + } + } + } + return true; + } + static final class KeyData { final int key; final double keyProbability; @@ -208,7 +285,7 @@ * because {@link Enum#ordinal()} can change when recompiling an enum, it cannot be used * directly as the value that is switched on. An intermediate int[] array, which is initialized * once at run time based on the actual {@link Enum#ordinal()} values, is used. - * + * <p> * The {@link ConstantFieldProvider} of Graal already detects the int[] arrays and marks them as * {@link ConstantNode#isDefaultStable() stable}, i.e., the array elements are constant. The * code in this method detects array loads from such a stable array and re-wires the switch to
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -198,6 +198,13 @@ } /** + * Returns the probability of taking the default branch. + */ + public double defaultProbability() { + return keyProbabilities[keyProbabilities.length - 1]; + } + + /** * Returns the index of the default (fall through) successor of this switch. */ public int defaultSuccessorIndex() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java Thu Jul 25 21:51:13 2019 +0000 @@ -50,4 +50,3 @@ return precise; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java Thu Jul 25 21:51:13 2019 +0000 @@ -41,4 +41,3 @@ } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java Thu Jul 25 21:51:13 2019 +0000 @@ -53,4 +53,3 @@ return verifyOnly; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java Thu Jul 25 21:51:13 2019 +0000 @@ -54,4 +54,3 @@ return address; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Thu Jul 25 21:51:13 2019 +0000 @@ -243,4 +243,3 @@ return false; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -32,9 +32,12 @@ import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode; import org.graalvm.compiler.nodes.FrameState; +import org.graalvm.compiler.nodes.extended.MembarNode; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; +import jdk.vm.ci.code.MemoryBarriers; + /** * The {@code AbstractNewObjectNode} is the base class for the new instance and new array nodes. */ @@ -44,6 +47,12 @@ public static final NodeClass<AbstractNewObjectNode> TYPE = NodeClass.create(AbstractNewObjectNode.class); protected final boolean fillContents; + /** + * Controls whether this allocation emits a {@link MembarNode} with + * {@link MemoryBarriers#STORE_STORE} as part of the object initialization. + */ + protected boolean emitMemoryBarrier = true; + protected AbstractNewObjectNode(NodeClass<? extends AbstractNewObjectNode> c, Stamp stamp, boolean fillContents, FrameState stateBefore) { super(c, stamp, stateBefore); this.fillContents = fillContents; @@ -65,4 +74,12 @@ public boolean canDeoptimize() { return true; } + + public boolean emitMemoryBarrier() { + return emitMemoryBarrier; + } + + public void clearEmitMemoryBarrier() { + this.emitMemoryBarrier = false; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -35,6 +35,7 @@ import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.Verbosity; +import org.graalvm.compiler.nodes.BeginNode; import org.graalvm.compiler.nodes.CallTargetNode; import org.graalvm.compiler.nodes.FixedGuardNode; import org.graalvm.compiler.nodes.Invoke; @@ -43,7 +44,7 @@ import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.extended.ValueAnchorNode; +import org.graalvm.compiler.nodes.extended.AnchoringNode; import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider; import org.graalvm.compiler.nodes.type.StampTool; @@ -232,11 +233,7 @@ * an assumption but as we need an instanceof check anyway we can verify both * properties by checking of the receiver is an instance of the single implementor. */ - ValueAnchorNode anchor = new ValueAnchorNode(null); - if (anchor != null) { - graph().add(anchor); - graph().addBeforeFixed(invoke().asNode(), anchor); - } + AnchoringNode anchor = BeginNode.prevBegin(invoke().asNode()); LogicNode condition = graph().addOrUniqueWithInputs(InstanceOfNode.create(speculatedType, receiver, getProfile(), anchor)); FixedGuardNode guard = graph().add(new FixedGuardNode(condition, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, false)); graph().addBeforeFixed(invoke().asNode(), guard);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -50,15 +50,10 @@ /** * Indicates the smallest width for comparing an integer value on the target platform. */ - default Integer smallestCompareWidth() { - // most platforms only support 32 and 64 bit compares - return 32; - } + Integer smallestCompareWidth(); /** * Indicates whether the target platform supports bulk zeroing instruction. */ - default boolean supportBulkZeroing() { - return false; - } + boolean supportBulkZeroing(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/SwitchFoldable.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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. + */ + + + +package org.graalvm.compiler.nodes.spi; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import jdk.internal.vm.compiler.collections.EconomicMap; +import jdk.internal.vm.compiler.collections.Equivalence; +import org.graalvm.compiler.core.common.SuppressFBWarnings; +import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.core.common.type.PrimitiveStamp; +import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.graph.spi.SimplifierTool; +import org.graalvm.compiler.nodes.AbstractBeginNode; +import org.graalvm.compiler.nodes.BeginNode; +import org.graalvm.compiler.nodes.FixedNode; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.ValueNodeInterface; +import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; +import org.graalvm.compiler.nodes.calc.SignExtendNode; +import org.graalvm.compiler.nodes.extended.IntegerSwitchNode; +import org.graalvm.compiler.nodes.util.GraphUtil; + +/** + * Nodes that implement this interface can be collapsed to a single IntegerSwitch when they are seen + * in a cascade. + */ +@SuppressFBWarnings(value = {"UCF"}, justification = "javac spawns useless control flow in static initializer when using assert(asNode().isAlive())") +public interface SwitchFoldable extends ValueNodeInterface { + Comparator<KeyData> SORTER = Comparator.comparingInt((KeyData k) -> k.key); + + /** + * Returns the direct successor in the branch to check for SwitchFoldability. + */ + Node getNextSwitchFoldableBranch(); + + /** + * Returns the value that will be used as the switch input. This value should be an int. + */ + ValueNode switchValue(); + + /** + * Returns the branch that will close this switch folding, assuming this is called on the lowest + * node of the cascade. + */ + AbstractBeginNode getDefault(); + + /** + * Determines whether the node should be folded in the current folding attempt. + * + * @param switchValue the value of the switch that will spawn through this folding attempt. + * @return true if this node should be folded in the current folding attempt, false otherwise. + * @see SwitchFoldable#maybeIsInSwitch(LogicNode) + * @see SwitchFoldable#sameSwitchValue(LogicNode, ValueNode) + */ + boolean isInSwitch(ValueNode switchValue); + + /** + * Removes the successors of this node, while keeping it linked to the rest of the cascade. + */ + void cutOffCascadeNode(); + + /** + * Completely removes all successors from this node. + */ + void cutOffLowestCascadeNode(); + + /** + * Returns the value of the i-th key of this node. + */ + int intKeyAt(int i); + + /** + * Returns the probability of seeing the i-th key of this node. + */ + double keyProbability(int i); + + /** + * Returns the branch to follow when seeing the i-th key of this node. + */ + AbstractBeginNode keySuccessor(int i); + + /** + * Returns the probability of going to the default branch. + */ + double defaultProbability(); + + /** + * @return The number of keys the SwitchFoldable node will try to add. + */ + default int keyCount() { + return 1; + } + + /** + * Should be overridden if getDefault() has side effects. + */ + default boolean isDefaultSuccessor(AbstractBeginNode successor) { + return successor == getDefault(); + } + + /** + * Heuristics that tries to determine whether or not a foldable node was profiled. + */ + default boolean isNonInitializedProfile() { + return false; + } + + static boolean maybeIsInSwitch(LogicNode condition) { + return condition instanceof IntegerEqualsNode && ((IntegerEqualsNode) condition).getY().isJavaConstant(); + } + + static boolean sameSwitchValue(LogicNode condition, ValueNode switchValue) { + return ((IntegerEqualsNode) condition).getX() == switchValue; + } + + // Helper data structures + + class Helper { + private Helper() { + } + + private static boolean isDuplicateKey(int key, QuickQueryKeyData keyData) { + return keyData.contains(key); + } + + private static int duplicateIndex(AbstractBeginNode begin, QuickQueryList<AbstractBeginNode> successors) { + return successors.indexOf(begin); + } + + private static Node skipUpBegins(Node node) { + Node result = node; + while (result instanceof BeginNode && result.hasNoUsages()) { + result = result.predecessor(); + } + return result; + } + + private static Node skipDownBegins(Node node) { + Node result = node; + while (result instanceof BeginNode && result.hasNoUsages()) { + result = ((BeginNode) result).next(); + } + return result; + } + + private static SwitchFoldable getParentSwitchNode(SwitchFoldable node, ValueNode switchValue) { + Node result = skipUpBegins(node.asNode().predecessor()); + if (result instanceof SwitchFoldable && ((SwitchFoldable) result).isInSwitch(switchValue)) { + return (SwitchFoldable) result; + } + return null; + } + + private static SwitchFoldable getChildSwitchNode(SwitchFoldable node, ValueNode switchValue) { + Node result = skipDownBegins(node.getNextSwitchFoldableBranch()); + if (result instanceof SwitchFoldable && ((SwitchFoldable) result).isInSwitch(switchValue)) { + return (SwitchFoldable) result; + } + return null; + } + + private static int addDefault(SwitchFoldable node, QuickQueryList<AbstractBeginNode> successors) { + AbstractBeginNode defaultBranch = node.getDefault(); + int index = successors.indexOf(defaultBranch); + if (index == -1) { + index = successors.size(); + successors.add(defaultBranch); + } + return index; + } + + private static int countNonDeoptSuccessors(QuickQueryKeyData keyData) { + int result = 0; + for (KeyData key : keyData.list) { + if (key.keyProbability > 0.0d) { + result++; + } + } + return result; + } + + /** + * Updates the current state of the IntegerSwitch that will be spawned. That means: + * <p> + * - Checking for duplicate keys: add the duplicate key's branch to duplicates + * <p> + * - For branches of non-duplicate keys: add them to successors and update the keyData + * accordingly + * <p> + * - Update the value of the cumulative probability, ie, multiply it by the probability of + * taking the next branch (according to {@link SwitchFoldable#getNextSwitchFoldableBranch}) + * <p> + * </p> + * + * @see QuickQueryList + * @see QuickQueryKeyData + */ + private static void updateSwitchData(SwitchFoldable node, QuickQueryKeyData keyData, QuickQueryList<AbstractBeginNode> newSuccessors, double[] cumulative, double[] totalProbabilities, + QuickQueryList<AbstractBeginNode> duplicates) { + for (int i = 0; i < node.keyCount(); i++) { + int key = node.intKeyAt(i); + double keyProbability = cumulative[0] * node.keyProbability(i); + KeyData data; + AbstractBeginNode keySuccessor = node.keySuccessor(i); + if (isDuplicateKey(key, keyData)) { + // Key was already seen + data = keyData.fromKey(key); + if (data.keySuccessor != KeyData.KEY_UNKNOWN) { + // Unreachable key: kill it manually at the end + if (!newSuccessors.contains(keySuccessor) && !duplicates.contains(keySuccessor) && keySuccessor.isAlive()) { + // This might be a false alert, if one of the next keys points to it. + duplicates.add(keySuccessor); + } + continue; + } + /* + * A key might not be able to immediately link to its target, if it is shared + * with the default target. In that case, we will need to resolve the target at + * a later time, either by seeing this key going to a known target in later + * cascade nodes, or by linking it to the overall default target at the very end + * of the folding. + */ + } else { + data = new KeyData(key, keyProbability, KeyData.KEY_UNKNOWN); + totalProbabilities[0] += keyProbability; + keyData.add(data); + } + if (keySuccessor.isUnregistered()) { + // Shortcut map check if uninitialized node. + data.keySuccessor = newSuccessors.size(); + newSuccessors.addUnique(keySuccessor); + } else { + int pos = duplicateIndex(keySuccessor, newSuccessors); + if (pos != -1) { + // Target is already known + data.keySuccessor = pos; + } else if (!node.isDefaultSuccessor(keySuccessor)) { + data.keySuccessor = newSuccessors.size(); + newSuccessors.add(keySuccessor); + } + } + } + cumulative[0] *= node.defaultProbability(); + } + } + + final class KeyData { + private static final int KEY_UNKNOWN = -2; + + private final int key; + private final double keyProbability; + private int keySuccessor; + + KeyData(int key, double keyProbability, int keySuccessor) { + this.key = key; + this.keyProbability = keyProbability; + this.keySuccessor = keySuccessor; + } + } + + /** + * Supports O(1) addition to the list, fast {@code contains} and {@code indexOf} queries + * (usually O(1), worst case O(n)), and O(1) random access. + */ + final class QuickQueryList<T> { + private final List<T> list = new ArrayList<>(); + private final EconomicMap<T, Integer> map = EconomicMap.create(Equivalence.IDENTITY); + + private int indexOf(T begin) { + return map.get(begin, -1); + } + + private boolean contains(T o) { + return map.containsKey(o); + } + + @SuppressWarnings("unused") + private T get(int index) { + return list.get(index); + } + + private boolean add(T item) { + map.put(item, list.size()); + return list.add(item); + } + + /** + * Adds an object, known to be unique beforehand. + */ + private void addUnique(T item) { + list.add(item); + } + + private int size() { + return list.size(); + } + } + + final class QuickQueryKeyData { + private final List<KeyData> list = new ArrayList<>(); + private final EconomicMap<Integer, KeyData> map = EconomicMap.create(); + + private void add(KeyData key) { + assert !map.containsKey(key.key); + list.add(key); + map.put(key.key, key); + } + + private boolean contains(int key) { + return map.containsKey(key); + } + + private KeyData get(int index) { + return list.get(index); + } + + private int size() { + return list.size(); + } + + private KeyData fromKey(int key) { + assert contains(key); + return map.get(key); + } + + private void sort() { + list.sort(SORTER); + } + + } + + /** + * Collapses a cascade of foldables (IfNode, FixedGuard and IntegerSwitch) into a single switch. + */ + default boolean switchTransformationOptimization(SimplifierTool tool) { + ValueNode switchValue = switchValue(); + assert asNode().isAlive(); + if (switchValue == null || !isInSwitch(switchValue) || (Helper.getParentSwitchNode(this, switchValue) == null && Helper.getChildSwitchNode(this, switchValue) == null)) { + // Don't bother trying if there is nothing to do. + return false; + } + Stamp switchStamp = switchValue.stamp(NodeView.DEFAULT); + + // Abort if we do not have an int + if (!(switchStamp instanceof IntegerStamp)) { + return false; + } + if (PrimitiveStamp.getBits(switchStamp) > 32) { + return false; + } + + // PlaceHolder for cascade traversal. + SwitchFoldable iteratingNode = this; + SwitchFoldable topMostSwitchNode = this; + + // Find top-most foldable. + while (iteratingNode != null) { + topMostSwitchNode = iteratingNode; + iteratingNode = Helper.getParentSwitchNode(iteratingNode, switchValue); + } + QuickQueryKeyData keyData = new QuickQueryKeyData(); + QuickQueryList<AbstractBeginNode> successors = new QuickQueryList<>(); + QuickQueryList<AbstractBeginNode> potentiallyUnreachable = new QuickQueryList<>(); + double[] cumulative = {1.0d}; + double[] totalProbability = {0.0d}; + + iteratingNode = topMostSwitchNode; + SwitchFoldable lowestSwitchNode = topMostSwitchNode; + + // If this stays true, we will need to spawn an uniform distribution. + boolean uninitializedProfiles = true; + + // Go down the if cascade, collecting necessary data + while (iteratingNode != null) { + lowestSwitchNode = iteratingNode; + Helper.updateSwitchData(iteratingNode, keyData, successors, cumulative, totalProbability, potentiallyUnreachable); + if (!iteratingNode.isNonInitializedProfile()) { + uninitializedProfiles = false; + } + iteratingNode = Helper.getChildSwitchNode(iteratingNode, switchValue); + } + + if (keyData.size() < 4 || lowestSwitchNode == topMostSwitchNode) { + // Abort if it's not worth the hassle + return false; + } + + // At that point, we will commit the optimization. + StructuredGraph graph = asNode().graph(); + + // Sort the keys + keyData.sort(); + + /* + * The total probability might be different than 1 if there was a duplicate key which was + * erased by another branch whose probability was different (/ex: in the case where a method + * constituted of only a switch is inlined after a guard for a particular value of that + * switch). In that case, we need to re-normalize the probabilities. A more "correct" way + * would be to only re-normalize the probabilities of the switch after the guard, but this + * cannot be done without an additional overhead. + */ + totalProbability[0] += cumulative[0]; + assert totalProbability[0] > 0.0d; + double normalizationFactor = 1 / totalProbability[0]; + + // Spawn the required data structures + int newKeyCount = keyData.list.size(); + int[] keys = new int[newKeyCount]; + double[] keyProbabilities = new double[newKeyCount + 1]; + int[] keySuccessors = new int[newKeyCount + 1]; + int nonDeoptSuccessorCount = Helper.countNonDeoptSuccessors(keyData) + (cumulative[0] > 0.0d ? 1 : 0); + double uniform = (uninitializedProfiles && nonDeoptSuccessorCount > 0 ? 1 / (double) nonDeoptSuccessorCount : 1.0d); + + // Add default + keyProbabilities[newKeyCount] = uninitializedProfiles && cumulative[0] > 0.0d ? uniform : normalizationFactor * cumulative[0]; + keySuccessors[newKeyCount] = Helper.addDefault(lowestSwitchNode, successors); + + // Add branches. + for (int i = 0; i < newKeyCount; i++) { + SwitchFoldable.KeyData data = keyData.get(i); + keys[i] = data.key; + keyProbabilities[i] = uninitializedProfiles && data.keyProbability > 0.0d ? uniform : normalizationFactor * data.keyProbability; + keySuccessors[i] = data.keySuccessor != KeyData.KEY_UNKNOWN ? data.keySuccessor : keySuccessors[newKeyCount]; + } + + // Spin an adapter if the value is narrower than an int + ValueNode adapter = null; + if (((IntegerStamp) switchStamp).getBits() < 32) { + adapter = graph.addOrUnique(new SignExtendNode(switchValue, 32)); + } else { + adapter = switchValue; + } + + // Spawn the switch node + IntegerSwitchNode toInsert = new IntegerSwitchNode(adapter, successors.size(), keys, keyProbabilities, keySuccessors); + graph.add(toInsert); + + // Detach the cascade from the graph + lowestSwitchNode.cutOffLowestCascadeNode(); + iteratingNode = lowestSwitchNode; + while (iteratingNode != null) { + if (iteratingNode != lowestSwitchNode) { + iteratingNode.cutOffCascadeNode(); + } + iteratingNode = Helper.getParentSwitchNode(iteratingNode, switchValue); + } + + // Place the new Switch node + topMostSwitchNode.asNode().replaceAtPredecessor(toInsert); + topMostSwitchNode.asNode().replaceAtUsages(toInsert); + + // Attach the branches to the switch. + int pos = 0; + for (AbstractBeginNode begin : successors.list) { + if (begin.isUnregistered()) { + graph.add(begin.next()); + graph.add(begin); + begin.setNext(begin.next()); + } + toInsert.setBlockSuccessor(pos++, begin); + } + + // Remove the cascade and unreachable code + GraphUtil.killCFG((FixedNode) topMostSwitchNode); + for (AbstractBeginNode duplicate : potentiallyUnreachable.list) { + if (duplicate.predecessor() == null) { + // Make sure the duplicate is not reachable. + assert duplicate.isAlive(); + GraphUtil.killCFG(duplicate); + } + } + + tool.addToWorkList(toInsert); + + return true; + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Thu Jul 25 21:51:13 2019 +0000 @@ -224,6 +224,14 @@ } } + String optionStabilityName = getAnnotationValue(annotation, "stability", VariableElement.class).getSimpleName().toString(); + if (optionStabilityName.equals("STABLE")) { + if (help.length() == 0) { + processingEnv.getMessager().printMessage(Kind.ERROR, "A stable option must have non-empty help text", element); + return; + } + } + String optionTypeName = getAnnotationValue(annotation, "type", VariableElement.class).getSimpleName().toString(); info.options.add(new OptionInfo(optionName, optionTypeName, help, extraHelp, optionType, declaringClass, field.getSimpleName().toString())); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Thu Jul 25 21:51:13 2019 +0000 @@ -175,14 +175,9 @@ AbstractBeginNode beginNode = b.getBeginNode(); if (beginNode instanceof AbstractMergeNode && anchorBlock != b) { AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode; - for (GuardNode guard : mergeNode.guards().snapshot()) { - try (DebugCloseable closeable = guard.withNodeSourcePosition()) { - GuardNode newlyCreatedGuard = new GuardNode(guard.getCondition(), anchorBlock.getBeginNode(), guard.getReason(), guard.getAction(), guard.isNegated(), guard.getSpeculation(), - guard.getNoDeoptSuccessorPosition()); - GuardNode newGuard = mergeNode.graph().unique(newlyCreatedGuard); - guard.replaceAndDelete(newGuard); - } - } + mergeNode.replaceAtUsages(InputType.Anchor, anchorBlock.getBeginNode()); + mergeNode.replaceAtUsages(InputType.Guard, anchorBlock.getBeginNode()); + assert mergeNode.anchored().isEmpty(); } FixedNode endNode = b.getEndNode();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java Thu Jul 25 21:51:13 2019 +0000 @@ -48,4 +48,3 @@ return false; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Thu Jul 25 21:51:13 2019 +0000 @@ -42,7 +42,6 @@ import org.graalvm.compiler.bytecode.Bytecode; import org.graalvm.compiler.core.common.cfg.BlockMap; import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.graph.CachedGraph; import org.graalvm.compiler.graph.Edges; import org.graalvm.compiler.graph.Graph; @@ -66,7 +65,6 @@ import org.graalvm.compiler.nodes.cfg.Block; import org.graalvm.compiler.nodes.cfg.ControlFlowGraph; import org.graalvm.compiler.nodes.util.JavaConstantFormattable; -import org.graalvm.compiler.phases.schedule.SchedulePhase; import org.graalvm.graphio.GraphBlocks; import org.graalvm.graphio.GraphElements; import org.graalvm.graphio.GraphLocations; @@ -591,22 +589,8 @@ this.graph = graph; StructuredGraph.ScheduleResult scheduleResult = null; if (graph instanceof StructuredGraph) { - StructuredGraph structuredGraph = (StructuredGraph) graph; - scheduleResult = structuredGraph.getLastSchedule(); - if (scheduleResult == null) { - - // Also provide a schedule when an error occurs - if (DebugOptions.PrintGraphWithSchedule.getValue(graph.getOptions()) || debug.contextLookup(Throwable.class) != null) { - try { - SchedulePhase schedule = new SchedulePhase(graph.getOptions()); - schedule.apply(structuredGraph); - scheduleResult = structuredGraph.getLastSchedule(); - } catch (Throwable t) { - } - } - - } + scheduleResult = GraalDebugHandlersFactory.tryGetSchedule(debug, structuredGraph); } cfg = scheduleResult == null ? debug.contextLookup(ControlFlowGraph.class) : scheduleResult.getCFG(); blockToNodes = scheduleResult == null ? null : scheduleResult.getBlockToNodesMap();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Thu Jul 25 21:51:13 2019 +0000 @@ -211,12 +211,14 @@ } else if (object instanceof StructuredGraph) { if (cfgPrinter.cfg == null) { StructuredGraph graph = (StructuredGraph) object; - cfgPrinter.cfg = ControlFlowGraph.compute(graph, true, true, true, false); - cfgPrinter.printCFG(message, cfgPrinter.cfg.getBlocks(), true); - } else { + ScheduleResult scheduleResult = GraalDebugHandlersFactory.tryGetSchedule(debug, graph); + if (scheduleResult != null) { + cfgPrinter.cfg = scheduleResult.getCFG(); + } + } + if (cfgPrinter.cfg != null) { cfgPrinter.printCFG(message, cfgPrinter.cfg.getBlocks(), true); } - } else if (object instanceof CompilationResult) { final CompilationResult compResult = (CompilationResult) object; cfgPrinter.printMachineCode(disassemble(codeCache, compResult, null), message);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Thu Jul 25 21:51:13 2019 +0000 @@ -28,16 +28,19 @@ import java.util.List; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugDumpHandler; import org.graalvm.compiler.debug.DebugHandler; import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.debug.DebugOptions; -import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.nodeinfo.Verbosity; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult; import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.phases.schedule.SchedulePhase; import org.graalvm.compiler.serviceprovider.ServiceProvider; @ServiceProvider(DebugHandlersFactory.class) @@ -62,9 +65,6 @@ } handlers.add(new NodeDumper()); if (DebugOptions.PrintCFG.getValue(options) || DebugOptions.PrintBackendCFG.getValue(options)) { - if (DebugOptions.PrintCFG.getValue(options)) { - TTY.out.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -Dgraal.PrintCFG=false to disable it"); - } handlers.add(new CFGPrinterObserver()); } handlers.add(new NoDeadCodeVerifyHandler()); @@ -91,4 +91,20 @@ return new CanonicalStringGraphPrinter(snippetReflection); } + @SuppressWarnings("try") + static ScheduleResult tryGetSchedule(DebugContext debug, StructuredGraph graph) { + ScheduleResult scheduleResult = graph.getLastSchedule(); + if (scheduleResult == null) { + // Also provide a schedule when an error occurs + if (DebugOptions.PrintGraphWithSchedule.getValue(graph.getOptions()) || debug.contextLookup(Throwable.class) != null) { + try (DebugCloseable noIntercept = debug.disableIntercept()) { + SchedulePhase schedule = new SchedulePhase(graph.getOptions()); + schedule.apply(graph); + scheduleResult = graph.getLastSchedule(); + } catch (Throwable t) { + } + } + } + return scheduleResult; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Thu Jul 25 21:51:13 2019 +0000 @@ -136,36 +136,26 @@ // Get all current JavaMethod instances in the context. List<String> inlineContext = getInlineContext(graph); - if (inlineContext != previousInlineContext) { + if (!inlineContext.equals(previousInlineContext)) { Map<Object, Object> properties = new HashMap<>(); properties.put("graph", graph.toString()); addCompilationId(properties, graph); - if (inlineContext.equals(previousInlineContext)) { - /* - * two different graphs have the same inline context, so make sure they appear - * in different folders by closing and reopening the top scope. - */ - int inlineDepth = previousInlineContext.size() - 1; - closeScope(debug, inlineDepth); - openScope(debug, inlineContext.get(inlineDepth), inlineDepth, properties); - } else { - // Check for method scopes that must be closed since the previous dump. - for (int i = 0; i < previousInlineContext.size(); ++i) { - if (i >= inlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) { - for (int inlineDepth = previousInlineContext.size() - 1; inlineDepth >= i; --inlineDepth) { - closeScope(debug, inlineDepth); - } - break; + // Check for method scopes that must be closed since the previous dump. + for (int i = 0; i < previousInlineContext.size(); ++i) { + if (i >= inlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) { + for (int inlineDepth = previousInlineContext.size() - 1; inlineDepth >= i; --inlineDepth) { + closeScope(debug, inlineDepth); } + break; } - // Check for method scopes that must be opened since the previous dump. - for (int i = 0; i < inlineContext.size(); ++i) { - if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) { - for (int inlineDepth = i; inlineDepth < inlineContext.size(); ++inlineDepth) { - openScope(debug, inlineContext.get(inlineDepth), inlineDepth, inlineDepth == inlineContext.size() - 1 ? properties : null); - } - break; + } + // Check for method scopes that must be opened since the previous dump. + for (int i = 0; i < inlineContext.size(); ++i) { + if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) { + for (int inlineDepth = i; inlineDepth < inlineContext.size(); ++inlineDepth) { + openScope(debug, inlineContext.get(inlineDepth), inlineDepth, inlineDepth == inlineContext.size() - 1 ? properties : null); } + break; } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfDispatchNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfDispatchNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -307,4 +307,3 @@ return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, true, array, arrayLength, fromIndex, values); } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Jul 25 21:51:13 2019 +0000 @@ -766,6 +766,8 @@ } else { newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph))); } + // The final STORE_STORE barrier will be emitted by finishAllocatedObjects + newObject.clearEmitMemoryBarrier(); recursiveLowerings.add(newObject); graph.addBeforeFixed(commit, newObject);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyWithDelayedLoweringNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyWithDelayedLoweringNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -60,4 +60,3 @@ this.bci = bci; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -91,7 +91,7 @@ generator.getLIRGeneratorTool().emitIncomingValues(new Value[]{result}); } if (!directUse) { - result = generator.getLIRGeneratorTool().emitMove(result); + result = generator.getLIRGeneratorTool().emitReadRegister(register, kind); } generator.setResult(this, result); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Thu Jul 25 21:51:13 2019 +0000 @@ -65,7 +65,7 @@ @Override public void generate(NodeLIRBuilderTool generator) { Value val = generator.operand(value); - generator.getLIRGeneratorTool().emitMove(register.asValue(val.getValueKind()), val); + generator.getLIRGeneratorTool().emitWriteRegister(register, val, val.getValueKind()); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Thu Jul 25 21:51:13 2019 +0000 @@ -531,11 +531,7 @@ return Math.fma(a, b, c); } - /** - * Set the flag in the {@link VirtualObject} that indicates that it is a boxed primitive that - * was produced as a result of a call to a {@code valueOf} method. - */ - public static void markVirtualObjectAsAutoBox(VirtualObject virtualObject) { - virtualObject.setIsAutoBox(true); + public static VirtualObject createVirtualObject(ResolvedJavaType type, int id, boolean isAutoBox) { + return VirtualObject.get(type, id, isAutoBox); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalUnsafeAccess.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalUnsafeAccess.java Thu Jul 25 21:51:13 2019 +0000 @@ -67,4 +67,3 @@ return UNSAFE; } } -
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -27,10 +27,16 @@ import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; import static org.graalvm.compiler.debug.DebugContext.NO_DESCRIPTION; +import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -499,4 +505,31 @@ public static TestRule createTimeoutMillis(long milliseconds) { return createTimeout(milliseconds, TimeUnit.MILLISECONDS); } + + /** + * Tries to recursively remove {@code directory}. If it fails with an {@link IOException}, the + * exception's {@code toString()} is printed to {@link System#err} and the exception is + * returned. + */ + public static IOException removeDirectory(Path directory) { + try { + Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + System.err.println(e); + return e; + } + return null; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Thu Jul 25 21:51:13 2019 +0000 @@ -217,7 +217,11 @@ long offset = store.offset().asJavaConstant().asLong(); boolean overflowAccess = isOverflowAccess(accessKind, componentKind); int index = overflowAccess ? -1 : VirtualArrayNode.entryIndexForOffset(tool.getMetaAccess(), offset, accessKind, type.getComponentType(), Integer.MAX_VALUE); - return processStore(store, store.object(), location, index, accessKind, overflowAccess, store.value(), state, effects); + if (index != -1) { + return processStore(store, store.object(), location, index, accessKind, overflowAccess, store.value(), state, effects); + } else { + state.killReadCache(location, index); + } } else { processIdentity(state, location); }
--- a/src/jdk.jsobject/share/classes/jdk/internal/netscape/javascript/spi/JSObjectProvider.java Thu Jul 25 02:16:49 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.internal.netscape.javascript.spi; - -import java.applet.Applet; -import netscape.javascript.JSException; -import netscape.javascript.JSObject; - -@SuppressWarnings("deprecation") -public interface JSObjectProvider { - /** - * Return a JSObject for the window containing the given applet. - * Implementations of this class should return null if not connected to a - * browser, for example, when running in AppletViewer. - * - * @param applet The applet. - * @return JSObject for the window containing the given applet or null if we - * are not connected to a browser. - * @throws JSException when an error is encountered. - */ - public JSObject getWindow(Applet applet) throws JSException; -}
--- a/src/jdk.jsobject/share/classes/module-info.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.jsobject/share/classes/module-info.java Thu Jul 25 21:51:13 2019 +0000 @@ -30,9 +30,5 @@ * @since 9 */ module jdk.jsobject { - requires java.desktop; - exports netscape.javascript; - - uses jdk.internal.netscape.javascript.spi.JSObjectProvider; }
--- a/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java Thu Jul 25 02:16:49 2019 +0000 +++ b/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java Thu Jul 25 21:51:13 2019 +0000 @@ -25,8 +25,6 @@ package netscape.javascript; -import jdk.internal.netscape.javascript.spi.JSObjectProvider; -import java.applet.Applet; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Iterator; @@ -139,52 +137,4 @@ */ public abstract void setSlot(int index, Object value) throws JSException; - /** - * Returns a JSObject for the window containing the given applet. This - * method only works when the Java code is running in a browser as an - * applet. The object returned may be used to access the HTML DOM directly. - * - * @param applet The applet. - * @return JSObject representing the window containing the given applet or - * {@code null} if we are not connected to a browser. - * @throws JSException when an error is reported from the browser or - * JavaScript engine or if applet is {@code null} - * - * @deprecated The Applet API is deprecated, no replacement. See the - * <a href="{@docRoot}/java.desktop/java/applet/package-summary.html"> - * java.applet package documentation</a> for further information. - */ - - @Deprecated(since="9", forRemoval=true) - @SuppressWarnings("exports") - public static JSObject getWindow(Applet applet) throws JSException { - return ProviderLoader.callGetWindow(applet); - } - - private static class ProviderLoader { - private static final JSObjectProvider provider; - - static { - provider = AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public JSObjectProvider run() { - Iterator<JSObjectProvider> providers = - ServiceLoader.loadInstalled(JSObjectProvider.class).iterator(); - if (providers.hasNext()) { - return providers.next(); - } - return null; - } - } - ); - } - - private static JSObject callGetWindow(Applet applet) { - if (provider != null) { - return provider.getWindow(applet); - } - return null; - } - } }
--- a/test/jdk/ProblemList.txt Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/ProblemList.txt Thu Jul 25 21:51:13 2019 +0000 @@ -185,7 +185,7 @@ java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java 8158801 windows-all java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801 windows-all java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all +java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all @@ -283,7 +283,6 @@ java/awt/PrintJob/PrinterException.java 8196301 windows-all,macosx-all java/awt/Choice/PopupPosTest/PopupPosTest.java 8197811 windows-all java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java 7100044 macosx-all,linux-all -java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java 8214469 macosx-all java/awt/Component/CreateImage/CreateImage.java 8198334 windows-all java/awt/Component/GetScreenLocTest/GetScreenLocTest.java 4753654 generic-all java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 macosx-all @@ -480,7 +479,6 @@ java/awt/Modal/OnTop/OnTopModal4Test.java 8198666 macosx-all java/awt/Modal/OnTop/OnTopModal5Test.java 8198666 macosx-all java/awt/Modal/OnTop/OnTopModal6Test.java 8198666 macosx-all -java/awt/Modal/OnTop/OnTopModal6Test.java 8198666 macosx-all java/awt/Modal/OnTop/OnTopModeless1Test.java 8198666 macosx-all java/awt/Modal/OnTop/OnTopModeless2Test.java 8198666 macosx-all java/awt/Modal/OnTop/OnTopModeless3Test.java 8198666 macosx-all @@ -507,7 +505,6 @@ java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java 8202860 linux-all java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java 8202790 macosx-all,linux-all java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java 8202882 linux-all -java/awt/Frame/FramesGC/FramesGC.java 8079069 macosx-all java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8030121 macosx-all,linux-all java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java 8202931 macosx-all,linux-all java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java 7124275 macosx-all @@ -744,7 +741,7 @@ javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-all javax/swing/Action/8133039/bug8133039.java 8196089 windows-all,macosx-all javax/swing/JComboBox/6559152/bug6559152.java 8196090 windows-all,macosx-all -javax/swing/JComboBox/8032878/bug8032878.java 8196092 windows-all,macosx-all +javax/swing/JComboBox/8032878/bug8032878.java 8196092,8196439 windows-all,macosx-all,linux-all javax/swing/JComboBox/8057893/bug8057893.java 8169953 windows-all,macosx-all javax/swing/JComboBox/8072767/bug8072767.java 8196093 windows-all,macosx-all javax/swing/JComponent/4337267/bug4337267.java 8146451 windows-all @@ -767,12 +764,11 @@ javax/swing/text/DefaultCaret/HidingSelection/MultiSelectionTest.java 8213562 linux-all javax/swing/text/JTextComponent/5074573/bug5074573.java 8196100 windows-all javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all -javax/swing/JComboBox/8032878/bug8032878.java 8196439 linux-all javax/swing/JComboBox/8182031/ComboPopupTest.java 8196465 linux-all,macosx-all javax/swing/JFileChooser/6738668/bug6738668.java 8194946 generic-all javax/swing/JFileChooser/8021253/bug8021253.java 8169954 windows-all,linux-all,macosx-all javax/swing/JFileChooser/8062561/bug8062561.java 8196466 linux-all,macosx-all -javax/swing/JInternalFrame/Test6325652.java 8196467 linux-all,macosx-all +javax/swing/JInternalFrame/Test6325652.java 8224977 macosx-all javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java 8194944 macosx-all javax/swing/JLabel/6596966/bug6596966.java 8040914 macosx-all javax/swing/JPopupMenu/4870644/bug4870644.java 8194130 macosx-all,linux-all @@ -791,7 +787,6 @@ javax/swing/text/AbstractDocument/DocumentInsert/DocumentInsertAtWrongPositionTest.java 8198396 generic-all javax/swing/JFileChooser/6868611/bug6868611.java 7059834 windows-all javax/swing/SwingWorker/6493680/bug6493680.java 8198410 windows-all -javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java 8042383 macosx-all javax/swing/PopupFactory/6276087/NonOpaquePopupMenuTest.java 8065099 macosx-all javax/swing/DataTransfer/8059739/bug8059739.java 8199074 generic-all javax/swing/JCheckBox/8032667/bug8032667_image_diff.java 8199063 macosx-all
--- a/test/jdk/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java Thu Jul 25 21:51:13 2019 +0000 @@ -24,6 +24,7 @@ /* * @test * @bug 4928019 + * @key headful * @summary Makes sure all the basic classes can be created with GTK. * @author Scott Violet */
--- a/test/jdk/com/sun/java/swing/plaf/gtk/Test6635110.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/com/sun/java/swing/plaf/gtk/Test6635110.java Thu Jul 25 21:51:13 2019 +0000 @@ -23,6 +23,7 @@ /* @test @bug 6635110 + @key headful @summary GTK icons should not throw NPE when called by non-GTK UI @author Peter Zhelezniakov @run main Test6635110
--- a/test/jdk/com/sun/java/swing/plaf/gtk/Test6963870.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/com/sun/java/swing/plaf/gtk/Test6963870.java Thu Jul 25 21:51:13 2019 +0000 @@ -23,6 +23,7 @@ /* @test @bug 6963870 + @key headful @summary Tests that GTKPainter.ListTableFocusBorder.getBorderInsets() doesn't return null @author Peter Zhelezniakov
--- a/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. 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 @@ -30,18 +30,18 @@ * @run main ChoiceKeyEventReaction */ +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; import java.awt.Robot; -import java.awt.Choice; -import java.awt.Point; +import java.awt.TextField; import java.awt.Toolkit; -import java.awt.TextField; -import java.awt.FlowLayout; import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.ItemEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.ItemListener; -import java.awt.Frame; public class ChoiceKeyEventReaction { @@ -60,6 +60,7 @@ try { robot = new Robot(); robot.setAutoDelay(100); + robot.waitForIdle(); moveFocusToTextField(); testKeyOnChoice(InputEvent.BUTTON1_MASK, KeyEvent.VK_UP); @@ -99,6 +100,7 @@ frame.add(choice1); frame.setLayout (new FlowLayout()); frame.setSize (200,200); + frame.setLocationRelativeTo(null); frame.setVisible(true); } @@ -108,33 +110,31 @@ robot.mousePress(button); robot.mouseRelease(button); + robot.waitForIdle(); robot.keyPress(key); robot.keyRelease(key); + robot.waitForIdle(); System.out.println("keyTypedOnTextField = "+keyTypedOnTextField +": itemChanged = " + itemChanged); if (itemChanged) { throw new RuntimeException("Test failed. ItemChanged event occur on Choice."); } - // We may just write - // if (toolkit.equals("sun.awt.windows.WToolkit") == keyTypedOnTextField) {fail;} - // but must report differently in these cases so put two separate if statements for simplicity. - if (toolkit.equals("sun.awt.windows.WToolkit") && - !keyTypedOnTextField) { - throw new RuntimeException("Test failed. (Win32) KeyEvent wasn't addressed to TextField. "); - } + // We may just write + // if (toolkit.equals("sun.awt.windows.WToolkit") == keyTypedOnTextField) {fail;} + // but must report differently in these cases so put two separate if statements for simplicity. + if (!toolkit.equals("sun.awt.X11.XToolkit") && + !keyTypedOnTextField) { + throw new RuntimeException("Test failed. (Win32/MacOS) KeyEvent wasn't addressed to TextField. "); + } - if (!toolkit.equals("sun.awt.windows.WToolkit") && - keyTypedOnTextField) { - throw new RuntimeException("Test failed. (XToolkit/MToolkit). KeyEvent was addressed to TextField."); + if (toolkit.equals("sun.awt.X11.XToolkit") && + keyTypedOnTextField) { + throw new RuntimeException("Test failed. (XToolkit/MToolkit). KeyEvent was addressed to TextField."); } System.out.println("Test passed. Unfocusable Choice doesn't react on keys."); - - //close opened choice - robot.keyPress(KeyEvent.VK_ESCAPE); - robot.keyRelease(KeyEvent.VK_ESCAPE); } public static void moveFocusToTextField() {
--- a/test/jdk/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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 @@ -46,6 +46,7 @@ GraphicsEnvironment.getLocalGraphicsEnvironment() .getScreenDevices(); if (devices.length < 2 || devices[0].getDisplayModes().length < 2 + || !devices[0].isDisplayChangeSupported() || !devices[0].isFullScreenSupported() || !devices[1].isFullScreenSupported()) { System.err.println("Testcase is not applicable");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/nio/channels/AsynchronousFileChannel/LockReadWriteStressTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. 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 8184157 + * @summary Ensure that correct PendingFuture is used in Iocp completion status event handler + * @requires (os.family == "windows") + */ + +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousFileChannel; +import java.nio.channels.FileLock; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static java.nio.file.StandardOpenOption.*; + +public class LockReadWriteStressTest { + public static void main(String[] args) throws Exception { + Path path = Path.of("blah"); + ByteBuffer buf = ByteBuffer.allocate(16); + for (int i=0; i < 1000; i++) { + try (AsynchronousFileChannel ch = AsynchronousFileChannel.open(path,READ, WRITE, CREATE)) { + FileLock lock = ch.lock().get(); + ch.read(buf, 0).get(); + buf.rewind(); + ch.write(buf, 0).get(); + lock.release(); + buf.clear(); + } + } + } +}
--- a/test/jdk/javax/swing/JInternalFrame/Test6325652.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/javax/swing/JInternalFrame/Test6325652.java Thu Jul 25 21:51:13 2019 +0000 @@ -63,6 +63,7 @@ public static void stepFirst() throws AWTException { robot = new Robot(); // initialize shared static field first time + robot.setAutoDelay(50); click(KeyEvent.VK_CONTROL, KeyEvent.VK_F9); // iconify internal frame }
--- a/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java Thu Jul 25 21:51:13 2019 +0000 @@ -78,10 +78,11 @@ }); Robot robot = new Robot(); + robot.setAutoDelay(50); robot.waitForIdle(); Util.hitMnemonics(robot, KeyEvent.VK_F); robot.waitForIdle(); - robot.delay(1000); + robot.delay(200); if (!bMenuSelected) { throw new RuntimeException("shortcuts on menus do not work");
--- a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -73,8 +73,7 @@ "jdk.internal.vm.ci/jdk.vm.ci.runtime", "jdk.internal.vm.ci/jdk.vm.ci.hotspot", "jdk.internal.vm.ci/jdk.vm.ci.meta", - "jdk.internal.vm.ci/jdk.vm.ci.code", - "jdk.jsobject/jdk.internal.netscape.javascript.spi"); + "jdk.internal.vm.ci/jdk.vm.ci.code"); static void checkExports(ModuleDescriptor md) { // build a map of upgradeable module to Exports that are qualified to it
--- a/test/jdk/sanity/client/SwingSet/src/ColorChooserDemoTest.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/sanity/client/SwingSet/src/ColorChooserDemoTest.java Thu Jul 25 21:51:13 2019 +0000 @@ -68,261 +68,262 @@ @Listeners(GuiTestListener.class) public class ColorChooserDemoTest { -private static final String OK_BUTTON_TITLE = "OK"; -private static final String CANCEL_BUTTON_TITLE = "Cancel"; -private static final String RESET_BUTTON_TITLE = "Reset"; -private static final String HSV = "HSV"; -private static final String RGB = "RGB"; -private static final String HSL = "HSL"; -private static final String CMYK = "CMYK"; -private static final int HSV_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; -private static final int RGB_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; -private static final int HSL_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; -private static final int CMYK_NUMBER_OF_SLIDERS_AND_SPINNERS = 5; -private static final int HSV_HUE_INDEX = 0; -private static final int HSV_SATURATION_INDEX = 1; -private static final int HSV_VALUE_INDEX = 2; -private static final int HSV_TRANSPARENCY_INDEX = 3; -private static final int HSL_HUE_INDEX = 0; -private static final int HSL_SATURATION_INDEX = 1; -private static final int HSL_LIGHTNESS_INDEX = 2; -private static final int HSL_TRANSPARENCY_INDEX = 3; -private static final int RGB_RED_INDEX = 0; -private static final int RGB_GREEN_INDEX = 1; -private static final int RGB_BLUE_INDEX = 2; -private static final int RGB_ALPHA_INDEX = 3; -private static final int RGB_COLORCODE_TEXT_FIELD_INDEX = 4; -private static final int CMYK_CYAN_INDEX = 0; -private static final int CMYK_MAGENTA_INDEX = 1; -private static final int CMYK_YELLOW_INDEX = 2; -private static final int CMYK_BLACK_INDEX = 3; -private static final int CMYK_ALPHA_INDEX = 4; + private static final String OK_BUTTON_TITLE = "OK"; + private static final String CANCEL_BUTTON_TITLE = "Cancel"; + private static final String RESET_BUTTON_TITLE = "Reset"; + private static final String HSV = "HSV"; + private static final String RGB = "RGB"; + private static final String HSL = "HSL"; + private static final String CMYK = "CMYK"; + private static final int HSV_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; + private static final int RGB_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; + private static final int HSL_NUMBER_OF_SLIDERS_AND_SPINNERS = 4; + private static final int CMYK_NUMBER_OF_SLIDERS_AND_SPINNERS = 5; + private static final int HSV_HUE_INDEX = 0; + private static final int HSV_SATURATION_INDEX = 1; + private static final int HSV_VALUE_INDEX = 2; + private static final int HSV_TRANSPARENCY_INDEX = 3; + private static final int HSL_HUE_INDEX = 0; + private static final int HSL_SATURATION_INDEX = 1; + private static final int HSL_LIGHTNESS_INDEX = 2; + private static final int HSL_TRANSPARENCY_INDEX = 3; + private static final int RGB_RED_INDEX = 0; + private static final int RGB_GREEN_INDEX = 1; + private static final int RGB_BLUE_INDEX = 2; + private static final int RGB_ALPHA_INDEX = 3; + private static final int RGB_COLORCODE_TEXT_FIELD_INDEX = 4; + private static final int CMYK_CYAN_INDEX = 0; + private static final int CMYK_MAGENTA_INDEX = 1; + private static final int CMYK_YELLOW_INDEX = 2; + private static final int CMYK_BLACK_INDEX = 3; + private static final int CMYK_ALPHA_INDEX = 4; -private final Color resetColor = new Color(125, 125, 125); + private final Color resetColor = new Color(125, 125, 125); -private JDialogOperator colorChooserDialog; -private JButtonOperator okButton; -private JButtonOperator cancelButton; -private JButtonOperator resetButton; -private JColorChooserOperator colorChooser; -private JButtonOperator backgroundButton; -private JButtonOperator gradient1Button; -private JButtonOperator gradient2Button; -private JButtonOperator perimeterButton; -private JTabbedPaneOperator tabOperator; -private JComponentOperator bezierAnimationPanel; -private JSliderOperator[] sliders = new JSliderOperator[5]; -private JSpinnerOperator[] spinners = new JSpinnerOperator[5]; -private JButtonOperator lastFocusedButton; + private JDialogOperator colorChooserDialog; + private JButtonOperator okButton; + private JButtonOperator cancelButton; + private JButtonOperator resetButton; + private JColorChooserOperator colorChooser; + private JButtonOperator backgroundButton; + private JButtonOperator gradient1Button; + private JButtonOperator gradient2Button; + private JButtonOperator perimeterButton; + private JTabbedPaneOperator tabOperator; + private JComponentOperator bezierAnimationPanel; + private JSliderOperator[] sliders = new JSliderOperator[5]; + private JSpinnerOperator[] spinners = new JSpinnerOperator[5]; + private JButtonOperator lastFocusedButton; -@Test -public void test() throws Exception { -new ClassReference(ColorChooserDemo.class.getCanonicalName()).startApplication(); -JFrameOperator frame = new JFrameOperator(DEMO_TITLE); -bezierAnimationPanel = new JComponentOperator(frame, new ByClassChooser(BezierAnimationPanel.class)); -initializePanelButtons(frame); -checkBackgroundColorChooser(); -checkGradient1ColorChooser(); -checkGradient2ColorChooser(); -checkPerimeterColorChooser(); + @Test + public void test() throws Exception { + new ClassReference(ColorChooserDemo.class.getCanonicalName()).startApplication(); + JFrameOperator frame = new JFrameOperator(DEMO_TITLE); + bezierAnimationPanel = new JComponentOperator(frame, new ByClassChooser(BezierAnimationPanel.class)); + initializePanelButtons(frame); + checkBackgroundColorChooser(); + checkGradient1ColorChooser(); + checkGradient2ColorChooser(); + checkPerimeterColorChooser(); + } + + private void checkBackgroundColorChooser() throws Exception { + basicCheck(backgroundButton, BezierColor.BACKGROUND); + checkAllColorChoosers(backgroundButton); + } + + private void checkGradient1ColorChooser() throws Exception { + basicCheck(gradient1Button, BezierColor.GRADIENT_A); + } + + private void checkGradient2ColorChooser() throws Exception { + basicCheck(gradient2Button, BezierColor.GRADIENT_B); + } + + private void checkPerimeterColorChooser() throws Exception { + basicCheck(perimeterButton, BezierColor.OUTER); + } + + private void pushButtonAndInitialize(JButtonOperator jbo) throws InterruptedException { + // Wait for focus to return to last focused button + lastFocusedButton.waitHasFocus(); + jbo.pushNoBlock(); + lastFocusedButton = jbo; + // Wait till the ColorChooserDemo Dialog Opens + new DialogWaiter().waitDialog(CHOOSER_TITLE, false, false); + initializeDialog(); + } + + private void initializePanelButtons(JFrameOperator frame) { + backgroundButton = new JButtonOperator(frame, BACKGROUND); + gradient1Button = new JButtonOperator(frame, GRADIENT_1); + gradient2Button = new JButtonOperator(frame, GRADIENT_2); + perimeterButton = new JButtonOperator(frame, PERIMETER); + lastFocusedButton = backgroundButton; + } + + private void initializeDialog() { + colorChooserDialog = new JDialogOperator(CHOOSER_TITLE); + tabOperator = new JTabbedPaneOperator(colorChooserDialog); + colorChooser = new JColorChooserOperator(colorChooserDialog); + okButton = new JButtonOperator(colorChooserDialog, OK_BUTTON_TITLE); + cancelButton = new JButtonOperator(colorChooserDialog, CANCEL_BUTTON_TITLE); + resetButton = new JButtonOperator(colorChooserDialog, RESET_BUTTON_TITLE); + } + + private void basicCheck(JButtonOperator jbo, BezierColor bezierColor) throws Exception { + Color testColor = new Color(100, 26, 155); + Color testColor2 = new Color(10, 40, 50); + checkDefaultColorChooser(jbo, testColor, bezierColor); + checkCancelButton(jbo, testColor2); + checkResetButton(jbo, testColor2); + } + + private void checkDefaultColorChooser(JButtonOperator jbo, Color testColor, BezierColor bezierColor) + throws Exception { + BezierAnimationPanel bezierPanel; + pushButtonAndInitialize(jbo); + // Check ColorChooser color is being set and used accordingly + // in the animation panel + setAndWaitColor(testColor); + pushButtonAndWaitDialogClosed(okButton); + bezierPanel = (BezierAnimationPanel) bezierAnimationPanel.getSource(); + colorChooser.waitStateOnQueue(jColorChooser -> (bezierPanel.getBezierColor(bezierColor).equals(testColor))); + } + + private void checkCancelButton(JButtonOperator jbo, Color testColor) throws Exception { + pushButtonAndInitialize(jbo); + setAndWaitColor(testColor); + pushButtonAndWaitDialogClosed(cancelButton); + } + + private void checkResetButton(JButtonOperator jbo, Color testColor) throws Exception { + pushButtonAndInitialize(jbo); + Color initialColor = colorChooser.getColor(); + setAndWaitColor(testColor); + resetButton.push(); + waitJColorChooserColor(initialColor); + pushButtonAndWaitDialogClosed(okButton); + } + + private void checkAllColorChoosers(JButtonOperator jbo) throws Exception { + pushButtonAndInitialize(jbo); + checkHSV(); + checkHSL(); + checkRGB(); + checkCMYK(); + pushButtonAndWaitDialogClosed(okButton); + } + + private void waitJColorChooserColor(Color expectedColor) { + colorChooser.waitStateOnQueue(jColorChooser -> colorChooser.getColor().equals(expectedColor)); + } + + private void setAndWaitColor(Color color) { + colorChooser.setColor(color); + // Wait for the Color to be set + waitJColorChooserColor(color); + } + + private void resetColor() { + colorChooser.setColor(resetColor); + // Wait for the Color to be reset + waitJColorChooserColor(resetColor); + } + + private void checkHSV() { + tabOperator.selectPage(HSV); + initializeSliderAndSpinner(HSV_NUMBER_OF_SLIDERS_AND_SPINNERS); + resetColor(); + setAndCheckSlider(sliders[HSV_SATURATION_INDEX], 50, new Color(125, 62, 62)); + setAndCheckSlider(sliders[HSV_VALUE_INDEX], 80, new Color(204, 102, 102)); + setAndCheckSlider(sliders[HSV_HUE_INDEX], 50, new Color(204, 187, 102)); + setAndCheckSlider(sliders[HSV_TRANSPARENCY_INDEX], 50, new Color(204, 187, 102, 127)); + setAndCheckSpinner(spinners[HSV_SATURATION_INDEX], 25, new Color(204, 195, 153, 127)); + setAndCheckSpinner(spinners[HSV_VALUE_INDEX], 40, new Color(102, 97, 76, 127)); + setAndCheckSpinner(spinners[HSV_HUE_INDEX], 25, new Color(102, 87, 76, 127)); + setAndCheckSpinner(spinners[HSV_TRANSPARENCY_INDEX], 100, new Color(102, 87, 76, 0)); + } + + private void checkHSL() { + tabOperator.selectPage(HSL); + initializeSliderAndSpinner(HSL_NUMBER_OF_SLIDERS_AND_SPINNERS); + resetColor(); + setAndCheckSlider(sliders[HSL_SATURATION_INDEX], 50, new Color(187, 62, 62)); + setAndCheckSlider(sliders[HSL_LIGHTNESS_INDEX], 80, new Color(229, 178, 178)); + setAndCheckSlider(sliders[HSL_HUE_INDEX], 180, new Color(178, 229, 229)); + setAndCheckSlider(sliders[HSL_TRANSPARENCY_INDEX], 50, new Color(178, 229, 229, 127)); + setAndCheckSpinner(spinners[HSL_SATURATION_INDEX], 25, new Color(191, 216, 216, 127)); + setAndCheckSpinner(spinners[HSL_LIGHTNESS_INDEX], 40, new Color(76, 127, 127, 127)); + setAndCheckSpinner(spinners[HSL_HUE_INDEX], 25, new Color(127, 97, 76, 127)); + setAndCheckSpinner(spinners[HSL_TRANSPARENCY_INDEX], 50, new Color(127, 97, 76, 127)); + } + + private void checkRGB() { + String sampleColor = "111111"; + tabOperator.selectPage(RGB); + initializeSliderAndSpinner(RGB_NUMBER_OF_SLIDERS_AND_SPINNERS); + JTextFieldOperator colorCode = new JTextFieldOperator(colorChooserDialog, RGB_COLORCODE_TEXT_FIELD_INDEX); + resetColor(); + setAndCheckSlider(sliders[RGB_GREEN_INDEX], 50, new Color(125, 50, 125, 255)); + setAndCheckSlider(sliders[RGB_BLUE_INDEX], 80, new Color(125, 50, 80, 255)); + setAndCheckSlider(sliders[RGB_RED_INDEX], 50, new Color(50, 50, 80, 255)); + setAndCheckSlider(sliders[RGB_ALPHA_INDEX], 125, new Color(50, 50, 80, 125)); + setAndCheckSpinner(spinners[RGB_GREEN_INDEX], 25, new Color(50, 25, 80, 125)); + setAndCheckSpinner(spinners[RGB_BLUE_INDEX], 40, new Color(50, 25, 40, 125)); + setAndCheckSpinner(spinners[RGB_RED_INDEX], 25, new Color(25, 25, 40, 125)); + setAndCheckSpinner(spinners[RGB_ALPHA_INDEX], 255, new Color(25, 25, 40, 255)); + + colorCode.setText(sampleColor); + // Wait for the sampleColor to be set in the color code text field. + colorCode.waitText(sampleColor); + colorCode.getFocus(); + colorCode.pressKey(KeyEvent.VK_TAB); + // Wait for the color to be set + waitJColorChooserColor(new Color(17, 17, 17, 255)); + } + + private void checkCMYK() { + tabOperator.selectPage(CMYK); + initializeSliderAndSpinner(CMYK_NUMBER_OF_SLIDERS_AND_SPINNERS); + resetColor(); + setAndCheckSlider(sliders[CMYK_MAGENTA_INDEX], 50, new Color(125, 100, 125, 255)); + setAndCheckSlider(sliders[CMYK_YELLOW_INDEX], 80, new Color(125, 100, 85, 255)); + setAndCheckSlider(sliders[CMYK_CYAN_INDEX], 50, new Color(100, 100, 85, 255)); + setAndCheckSlider(sliders[CMYK_BLACK_INDEX], 50, new Color(164, 164, 140, 255)); + setAndCheckSlider(sliders[CMYK_ALPHA_INDEX], 125, new Color(164, 164, 140, 125)); + setAndCheckSpinner(spinners[CMYK_MAGENTA_INDEX], 25, new Color(164, 184, 140, 125)); + setAndCheckSpinner(spinners[CMYK_YELLOW_INDEX], 40, new Color(164, 184, 172, 125)); + setAndCheckSpinner(spinners[CMYK_CYAN_INDEX], 25, new Color(184, 184, 172, 125)); + setAndCheckSpinner(spinners[CMYK_BLACK_INDEX], 100, new Color(139, 139, 130, 125)); + setAndCheckSpinner(spinners[CMYK_ALPHA_INDEX], 255, new Color(139, 139, 130, 255)); + } + + private void setAndCheckSlider(JSliderOperator slider, int sliderValue, Color expectedColor) { + slider.setValue(sliderValue); + // Wait for slider to attain the specified value + slider.waitStateOnQueue(jSlider -> slider.getValue() == sliderValue); + colorChooser.waitStateOnQueue(jColorChooser -> (colorChooser.getColor().equals(expectedColor))); + } + + private void setAndCheckSpinner(JSpinnerOperator spinner, int spinnerValue, Color expectedColor) { + spinner.setValue(spinnerValue); + // Wait for spinner to attain the specified value + spinner.waitStateOnQueue(jSpinner -> (int) spinner.getValue() == spinnerValue); + colorChooser.waitStateOnQueue(jColorChooser -> (colorChooser.getColor().equals(expectedColor))); + } + + private void initializeSliderAndSpinner(int numberOfSlidersAndSpinners) { + for (int i = 0; i < numberOfSlidersAndSpinners; i++) { + sliders[i] = new JSliderOperator(colorChooserDialog, i); + spinners[i] = new JSpinnerOperator(colorChooserDialog, i); + } + } + + private void pushButtonAndWaitDialogClosed(JButtonOperator button) { + button.push(); + // Wait for the color chooser dialog to close. + colorChooserDialog.waitClosed(); + } } -private void checkBackgroundColorChooser() throws Exception { -basicCheck(backgroundButton, BezierColor.BACKGROUND); -checkAllColorChoosers(backgroundButton); -} - -private void checkGradient1ColorChooser() throws Exception { -basicCheck(gradient1Button, BezierColor.GRADIENT_A); -} - -private void checkGradient2ColorChooser() throws Exception { -basicCheck(gradient2Button, BezierColor.GRADIENT_B); -} - -private void checkPerimeterColorChooser() throws Exception { -basicCheck(perimeterButton, BezierColor.OUTER); -} - -private void pushButtonAndInitialize(JButtonOperator jbo) throws InterruptedException { -// Wait for focus to return to last focused button -lastFocusedButton.waitHasFocus(); -jbo.pushNoBlock(); -lastFocusedButton = jbo; -// Wait till the ColorChooserDemo Dialog Opens -new DialogWaiter().waitDialog(CHOOSER_TITLE, false, false); -initializeDialog(); -} - -private void initializePanelButtons(JFrameOperator frame) { -backgroundButton = new JButtonOperator(frame, BACKGROUND); -gradient1Button = new JButtonOperator(frame, GRADIENT_1); -gradient2Button = new JButtonOperator(frame, GRADIENT_2); -perimeterButton = new JButtonOperator(frame, PERIMETER); -lastFocusedButton = backgroundButton; -} - -private void initializeDialog() { -colorChooserDialog = new JDialogOperator(CHOOSER_TITLE); -tabOperator = new JTabbedPaneOperator(colorChooserDialog); -colorChooser = new JColorChooserOperator(colorChooserDialog); -okButton = new JButtonOperator(colorChooserDialog, OK_BUTTON_TITLE); -cancelButton = new JButtonOperator(colorChooserDialog, CANCEL_BUTTON_TITLE); -resetButton = new JButtonOperator(colorChooserDialog, RESET_BUTTON_TITLE); -} - -private void basicCheck(JButtonOperator jbo, BezierColor bezierColor) throws Exception { -Color testColor = new Color(100, 26, 155); -Color testColor2 = new Color(10, 40, 50); -checkDefaultColorChooser(jbo, testColor, bezierColor); -checkCancelButton(jbo, testColor2); -checkResetButton(jbo, testColor2); -} - -private void checkDefaultColorChooser(JButtonOperator jbo, Color testColor, BezierColor bezierColor) -throws Exception { -BezierAnimationPanel bezierPanel; -pushButtonAndInitialize(jbo); -// Check ColorChooser color is being set and used accordingly -// in the animation panel -setAndWaitColor(testColor); -pushButtonAndWaitDialogClosed(okButton); -bezierPanel = (BezierAnimationPanel) bezierAnimationPanel.getSource(); -colorChooser.waitStateOnQueue(jColorChooser -> (bezierPanel.getBezierColor(bezierColor).equals(testColor))); -} - -private void checkCancelButton(JButtonOperator jbo, Color testColor) throws Exception { -pushButtonAndInitialize(jbo); -setAndWaitColor(testColor); -pushButtonAndWaitDialogClosed(cancelButton); -} - -private void checkResetButton(JButtonOperator jbo, Color testColor) throws Exception { -pushButtonAndInitialize(jbo); -Color initialColor = colorChooser.getColor(); -setAndWaitColor(testColor); -resetButton.push(); -waitJColorChooserColor(initialColor); -pushButtonAndWaitDialogClosed(okButton); -} - -private void checkAllColorChoosers(JButtonOperator jbo) throws Exception { -pushButtonAndInitialize(jbo); -checkHSV(); -checkHSL(); -checkRGB(); -checkCMYK(); -pushButtonAndWaitDialogClosed(okButton); -} - -private void waitJColorChooserColor(Color expectedColor) { -colorChooser.waitStateOnQueue(jColorChooser -> colorChooser.getColor().equals(expectedColor)); -} - -private void setAndWaitColor(Color color) { -colorChooser.setColor(color); -// Wait for the Color to be set -waitJColorChooserColor(color); -} - -private void resetColor() { -colorChooser.setColor(resetColor); -// Wait for the Color to be reset -waitJColorChooserColor(resetColor); -} - -private void checkHSV() { -tabOperator.selectPage(HSV); -initializeSliderAndSpinner(HSV_NUMBER_OF_SLIDERS_AND_SPINNERS); -resetColor(); -setAndCheckSlider(sliders[HSV_SATURATION_INDEX], 50, new Color(125, 62, 62)); -setAndCheckSlider(sliders[HSV_VALUE_INDEX], 80, new Color(204, 102, 102)); -setAndCheckSlider(sliders[HSV_HUE_INDEX], 50, new Color(204, 187, 102)); -setAndCheckSlider(sliders[HSV_TRANSPARENCY_INDEX], 50, new Color(204, 187, 102, 127)); -setAndCheckSpinner(spinners[HSV_SATURATION_INDEX], 25, new Color(204, 195, 153, 127)); -setAndCheckSpinner(spinners[HSV_VALUE_INDEX], 40, new Color(102, 97, 76, 127)); -setAndCheckSpinner(spinners[HSV_HUE_INDEX], 25, new Color(102, 87, 76, 127)); -setAndCheckSpinner(spinners[HSV_TRANSPARENCY_INDEX], 100, new Color(102, 87, 76, 0)); -} - -private void checkHSL() { -tabOperator.selectPage(HSL); -initializeSliderAndSpinner(HSL_NUMBER_OF_SLIDERS_AND_SPINNERS); -resetColor(); -setAndCheckSlider(sliders[HSL_SATURATION_INDEX], 50, new Color(187, 62, 62)); -setAndCheckSlider(sliders[HSL_LIGHTNESS_INDEX], 80, new Color(229, 178, 178)); -setAndCheckSlider(sliders[HSL_HUE_INDEX], 180, new Color(178, 229, 229)); -setAndCheckSlider(sliders[HSL_TRANSPARENCY_INDEX], 50, new Color(178, 229, 229, 127)); -setAndCheckSpinner(spinners[HSL_SATURATION_INDEX], 25, new Color(191, 216, 216, 127)); -setAndCheckSpinner(spinners[HSL_LIGHTNESS_INDEX], 40, new Color(76, 127, 127, 127)); -setAndCheckSpinner(spinners[HSL_HUE_INDEX], 25, new Color(127, 97, 76, 127)); -setAndCheckSpinner(spinners[HSL_TRANSPARENCY_INDEX], 50, new Color(127, 97, 76, 127)); -} - -private void checkRGB() { -String sampleColor = "111111"; -tabOperator.selectPage(RGB); -initializeSliderAndSpinner(RGB_NUMBER_OF_SLIDERS_AND_SPINNERS); -JTextFieldOperator colorCode = new JTextFieldOperator(colorChooserDialog, RGB_COLORCODE_TEXT_FIELD_INDEX); -resetColor(); -setAndCheckSlider(sliders[RGB_GREEN_INDEX], 50, new Color(125, 50, 125, 255)); -setAndCheckSlider(sliders[RGB_BLUE_INDEX], 80, new Color(125, 50, 80, 255)); -setAndCheckSlider(sliders[RGB_RED_INDEX], 50, new Color(50, 50, 80, 255)); -setAndCheckSlider(sliders[RGB_ALPHA_INDEX], 125, new Color(50, 50, 80, 125)); -setAndCheckSpinner(spinners[RGB_GREEN_INDEX], 25, new Color(50, 25, 80, 125)); -setAndCheckSpinner(spinners[RGB_BLUE_INDEX], 40, new Color(50, 25, 40, 125)); -setAndCheckSpinner(spinners[RGB_RED_INDEX], 25, new Color(25, 25, 40, 125)); -setAndCheckSpinner(spinners[RGB_ALPHA_INDEX], 255, new Color(25, 25, 40, 255)); - -colorCode.setText(sampleColor); -// Wait for the sampleColor to be set in the color code text field. -colorCode.waitText(sampleColor); -colorCode.getFocus(); -colorCode.pressKey(KeyEvent.VK_TAB); -// Wait for the color to be set -waitJColorChooserColor(new Color(17, 17, 17, 255)); -} - -private void checkCMYK() { -tabOperator.selectPage(CMYK); -initializeSliderAndSpinner(CMYK_NUMBER_OF_SLIDERS_AND_SPINNERS); -resetColor(); -setAndCheckSlider(sliders[CMYK_MAGENTA_INDEX], 50, new Color(125, 100, 125, 255)); -setAndCheckSlider(sliders[CMYK_YELLOW_INDEX], 80, new Color(125, 100, 85, 255)); -setAndCheckSlider(sliders[CMYK_CYAN_INDEX], 50, new Color(100, 100, 85, 255)); -setAndCheckSlider(sliders[CMYK_BLACK_INDEX], 50, new Color(164, 164, 140, 255)); -setAndCheckSlider(sliders[CMYK_ALPHA_INDEX], 125, new Color(164, 164, 140, 125)); -setAndCheckSpinner(spinners[CMYK_MAGENTA_INDEX], 25, new Color(164, 184, 140, 125)); -setAndCheckSpinner(spinners[CMYK_YELLOW_INDEX], 40, new Color(164, 184, 172, 125)); -setAndCheckSpinner(spinners[CMYK_CYAN_INDEX], 25, new Color(184, 184, 172, 125)); -setAndCheckSpinner(spinners[CMYK_BLACK_INDEX], 100, new Color(139, 139, 130, 125)); -setAndCheckSpinner(spinners[CMYK_ALPHA_INDEX], 255, new Color(139, 139, 130, 255)); -} - -private void setAndCheckSlider(JSliderOperator slider, int sliderValue, Color expectedColor) { -slider.setValue(sliderValue); -// Wait for slider to attain the specified value -slider.waitStateOnQueue(jSlider -> slider.getValue() == sliderValue); -colorChooser.waitStateOnQueue(jColorChooser -> (colorChooser.getColor().equals(expectedColor))); -} - -private void setAndCheckSpinner(JSpinnerOperator spinner, int spinnerValue, Color expectedColor) { -spinner.setValue(spinnerValue); -// Wait for spinner to attain the specified value -spinner.waitStateOnQueue(jSpinner -> (int) spinner.getValue() == spinnerValue); -colorChooser.waitStateOnQueue(jColorChooser -> (colorChooser.getColor().equals(expectedColor))); -} - -private void initializeSliderAndSpinner(int numberOfSlidersAndSpinners) { -for (int i = 0; i < numberOfSlidersAndSpinners; i++) { -sliders[i] = new JSliderOperator(colorChooserDialog, i); -spinners[i] = new JSpinnerOperator(colorChooserDialog, i); -} -} - -private void pushButtonAndWaitDialogClosed(JButtonOperator button) { -button.push(); -// Wait for the color chooser dialog to close. -colorChooserDialog.waitClosed(); -} -}
--- a/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/colorchooser/BezierAnimationPanel.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/colorchooser/BezierAnimationPanel.java Thu Jul 25 21:51:13 2019 +0000 @@ -35,220 +35,221 @@ import static com.sun.swingset3.demos.colorchooser.BezierAnimationPanel.BezierColor.*; /** -* BezierAnimationPanel -* -* @author Jim Graham -* @author Jeff Dinkins (removed dynamic setting changes, made swing friendly) -* @version 1.16 11/17/05 -*/ + * BezierAnimationPanel + * + * @author Jim Graham + * @author Jeff Dinkins (removed dynamic setting changes, made swing friendly) + * @version 1.16 11/17/05 + */ public class BezierAnimationPanel extends JPanel implements Runnable { -public static enum BezierColor { -BACKGROUND, OUTER, GRADIENT_A, GRADIENT_B + public static enum BezierColor { + BACKGROUND, OUTER, GRADIENT_A, GRADIENT_B + } + + private final Map<BezierColor, Color> colors = new Hashtable<BezierColor, Color>(); + + private GradientPaint gradient = null; + + private static final int NUMPTS = 6; + + private final float[] animpts = new float[NUMPTS * 2]; + + private final float[] deltas = new float[NUMPTS * 2]; + + private BufferedImage img; + + private Thread anim; + + private final Object lock = new Object(); + + /** + * BezierAnimationPanel Constructor + */ + public BezierAnimationPanel() { + setOpaque(true); + + colors.put(BACKGROUND, new Color(0, 0, 153)); + colors.put(OUTER, new Color(255, 255, 255)); + colors.put(GRADIENT_A, new Color(255, 0, 101)); + colors.put(GRADIENT_B, new Color(255, 255, 0)); + + addHierarchyListener(new HierarchyListener() { + public void hierarchyChanged(HierarchyEvent e) { + if (isShowing()) { + start(); + } else { + stop(); + } + } + }); + } + + public Color getBezierColor(BezierColor bezierColor) { + return colors.get(bezierColor); + } + + public void setBezierColor(BezierColor bezierColor, Color value) { + if (value != null) { + colors.put(bezierColor, value); + } + } + + public void start() { + Dimension size = getSize(); + for (int i = 0; i < animpts.length; i += 2) { + animpts[i] = (float) (Math.random() * size.width); + animpts[i + 1] = (float) (Math.random() * size.height); + deltas[i] = (float) (Math.random() * 4.0 + 2.0); + deltas[i + 1] = (float) (Math.random() * 4.0 + 2.0); + if (animpts[i] > size.width / 6.0f) { + deltas[i] = -deltas[i]; + } + if (animpts[i + 1] > size.height / 6.0f) { + deltas[i + 1] = -deltas[i + 1]; + } + } + anim = new Thread(this); + anim.setPriority(Thread.MIN_PRIORITY); + anim.start(); + } + + public synchronized void stop() { + anim = null; + notify(); + } + + private static void animate(float[] pts, float[] deltas, int index, int limit) { + float newpt = pts[index] + deltas[index]; + if (newpt <= 0) { + newpt = -newpt; + deltas[index] = (float) (Math.random() * 3.0 + 2.0); + } else if (newpt >= (float) limit) { + newpt = 2.0f * limit - newpt; + deltas[index] = -(float) (Math.random() * 3.0 + 2.0); + } + pts[index] = newpt; + } + + public void run() { + Thread me = Thread.currentThread(); + while (getSize().width <= 0) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + return; + } + } + + Graphics2D g2d = null; + Graphics2D bufferG2D = null; + BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f); + GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO); + int rule = AlphaComposite.SRC_OVER; + AlphaComposite opaque = AlphaComposite.SrcOver; + AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f); + AlphaComposite set = AlphaComposite.Src; + Dimension oldSize = getSize(); + Shape clippath = null; + while (anim == me) { + Dimension size = getSize(); + if (size.width != oldSize.width || size.height != oldSize.height) { + img = null; + clippath = null; + if (bufferG2D != null) { + bufferG2D.dispose(); + bufferG2D = null; + } + } + oldSize = size; + + if (img == null) { + img = (BufferedImage) createImage(size.width, size.height); + } + + if (bufferG2D == null) { + bufferG2D = img.createGraphics(); + bufferG2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT); + bufferG2D.setClip(clippath); + } + g2d = bufferG2D; + + float[] ctrlpts; + for (int i = 0; i < animpts.length; i += 2) { + animate(animpts, deltas, i, size.width); + animate(animpts, deltas, i + 1, size.height); + } + ctrlpts = animpts; + int len = ctrlpts.length; + gp.reset(); + float prevx = ctrlpts[len - 2]; + float prevy = ctrlpts[len - 1]; + float curx = ctrlpts[0]; + float cury = ctrlpts[1]; + float midx = (curx + prevx) / 2.0f; + float midy = (cury + prevy) / 2.0f; + gp.moveTo(midx, midy); + for (int i = 2; i <= ctrlpts.length; i += 2) { + float x1 = (midx + curx) / 2.0f; + float y1 = (midy + cury) / 2.0f; + prevx = curx; + prevy = cury; + if (i < ctrlpts.length) { + curx = ctrlpts[i]; + cury = ctrlpts[i + 1]; + } else { + curx = ctrlpts[0]; + cury = ctrlpts[1]; + } + midx = (curx + prevx) / 2.0f; + midy = (cury + prevy) / 2.0f; + float x2 = (prevx + midx) / 2.0f; + float y2 = (prevy + midy) / 2.0f; + gp.curveTo(x1, y1, x2, y2, midx, midy); + } + gp.closePath(); + + synchronized (lock) { + g2d.setComposite(set); + g2d.setBackground(getBezierColor(BACKGROUND)); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + + // g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width + // + 5, bounds.y + bounds.height + 5); + g2d.clearRect(0, 0, getWidth(), getHeight()); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(getBezierColor(OUTER)); + g2d.setComposite(opaque); + g2d.setStroke(solid); + g2d.draw(gp); + g2d.setPaint(gradient); + + Rectangle bounds = gp.getBounds(); + + gradient = new GradientPaint(bounds.x, bounds.y, getBezierColor(GRADIENT_A), bounds.x + bounds.width, + bounds.y + bounds.height, getBezierColor(GRADIENT_B), true); + + g2d.setComposite(blend); + g2d.fill(gp); + } + + repaint(); + + Thread.yield(); + } + if (g2d != null) { + g2d.dispose(); + } + } + + public void paint(Graphics g) { + synchronized (lock) { + Graphics2D g2d = (Graphics2D) g; + if (img != null) { + g2d.setComposite(AlphaComposite.Src); + g2d.drawImage(img, null, 0, 0); + } + } + } } -private final Map<BezierColor, Color> colors = new Hashtable<BezierColor, Color>(); - -private GradientPaint gradient = null; - -private static final int NUMPTS = 6; - -private final float[] animpts = new float[NUMPTS * 2]; - -private final float[] deltas = new float[NUMPTS * 2]; - -private BufferedImage img; - -private Thread anim; - -private final Object lock = new Object(); - -/** -* BezierAnimationPanel Constructor -*/ -public BezierAnimationPanel() { -setOpaque(true); - -colors.put(BACKGROUND, new Color(0, 0, 153)); -colors.put(OUTER, new Color(255, 255, 255)); -colors.put(GRADIENT_A, new Color(255, 0, 101)); -colors.put(GRADIENT_B, new Color(255, 255, 0)); - -addHierarchyListener(new HierarchyListener() { -public void hierarchyChanged(HierarchyEvent e) { -if (isShowing()) { -start(); -} else { -stop(); -} -} -}); -} - -public Color getBezierColor(BezierColor bezierColor) { -return colors.get(bezierColor); -} - -public void setBezierColor(BezierColor bezierColor, Color value) { -if (value != null) { -colors.put(bezierColor, value); -} -} - -public void start() { -Dimension size = getSize(); -for (int i = 0; i < animpts.length; i += 2) { -animpts[i] = (float) (Math.random() * size.width); -animpts[i + 1] = (float) (Math.random() * size.height); -deltas[i] = (float) (Math.random() * 4.0 + 2.0); -deltas[i + 1] = (float) (Math.random() * 4.0 + 2.0); -if (animpts[i] > size.width / 6.0f) { -deltas[i] = -deltas[i]; -} -if (animpts[i + 1] > size.height / 6.0f) { -deltas[i + 1] = -deltas[i + 1]; -} -} -anim = new Thread(this); -anim.setPriority(Thread.MIN_PRIORITY); -anim.start(); -} - -public synchronized void stop() { -anim = null; -notify(); -} - -private static void animate(float[] pts, float[] deltas, int index, int limit) { -float newpt = pts[index] + deltas[index]; -if (newpt <= 0) { -newpt = -newpt; -deltas[index] = (float) (Math.random() * 3.0 + 2.0); -} else if (newpt >= (float) limit) { -newpt = 2.0f * limit - newpt; -deltas[index] = -(float) (Math.random() * 3.0 + 2.0); -} -pts[index] = newpt; -} - -public void run() { -Thread me = Thread.currentThread(); -while (getSize().width <= 0) { -try { -Thread.sleep(500); -} catch (InterruptedException e) { -return; -} -} - -Graphics2D g2d = null; -Graphics2D bufferG2D = null; -BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f); -GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO); -int rule = AlphaComposite.SRC_OVER; -AlphaComposite opaque = AlphaComposite.SrcOver; -AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f); -AlphaComposite set = AlphaComposite.Src; -Dimension oldSize = getSize(); -Shape clippath = null; -while (anim == me) { -Dimension size = getSize(); -if (size.width != oldSize.width || size.height != oldSize.height) { -img = null; -clippath = null; -if (bufferG2D != null) { -bufferG2D.dispose(); -bufferG2D = null; -} -} -oldSize = size; - -if (img == null) { -img = (BufferedImage) createImage(size.width, size.height); -} - -if (bufferG2D == null) { -bufferG2D = img.createGraphics(); -bufferG2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT); -bufferG2D.setClip(clippath); -} -g2d = bufferG2D; - -float[] ctrlpts; -for (int i = 0; i < animpts.length; i += 2) { -animate(animpts, deltas, i, size.width); -animate(animpts, deltas, i + 1, size.height); -} -ctrlpts = animpts; -int len = ctrlpts.length; -gp.reset(); -float prevx = ctrlpts[len - 2]; -float prevy = ctrlpts[len - 1]; -float curx = ctrlpts[0]; -float cury = ctrlpts[1]; -float midx = (curx + prevx) / 2.0f; -float midy = (cury + prevy) / 2.0f; -gp.moveTo(midx, midy); -for (int i = 2; i <= ctrlpts.length; i += 2) { -float x1 = (midx + curx) / 2.0f; -float y1 = (midy + cury) / 2.0f; -prevx = curx; -prevy = cury; -if (i < ctrlpts.length) { -curx = ctrlpts[i]; -cury = ctrlpts[i + 1]; -} else { -curx = ctrlpts[0]; -cury = ctrlpts[1]; -} -midx = (curx + prevx) / 2.0f; -midy = (cury + prevy) / 2.0f; -float x2 = (prevx + midx) / 2.0f; -float y2 = (prevy + midy) / 2.0f; -gp.curveTo(x1, y1, x2, y2, midx, midy); -} -gp.closePath(); - -synchronized (lock) { -g2d.setComposite(set); -g2d.setBackground(getBezierColor(BACKGROUND)); -g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - -// g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width -// + 5, bounds.y + bounds.height + 5); -g2d.clearRect(0, 0, getWidth(), getHeight()); - -g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); -g2d.setColor(getBezierColor(OUTER)); -g2d.setComposite(opaque); -g2d.setStroke(solid); -g2d.draw(gp); -g2d.setPaint(gradient); - -Rectangle bounds = gp.getBounds(); - -gradient = new GradientPaint(bounds.x, bounds.y, getBezierColor(GRADIENT_A), bounds.x + bounds.width, -bounds.y + bounds.height, getBezierColor(GRADIENT_B), true); - -g2d.setComposite(blend); -g2d.fill(gp); -} - -repaint(); - -Thread.yield(); -} -if (g2d != null) { -g2d.dispose(); -} -} - -public void paint(Graphics g) { -synchronized (lock) { -Graphics2D g2d = (Graphics2D) g; -if (img != null) { -g2d.setComposite(AlphaComposite.Src); -g2d.drawImage(img, null, 0, 0); -} -} -} -} \ No newline at end of file
--- a/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java Thu Jul 25 21:51:13 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. 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 @@ -83,7 +83,7 @@ private JTree createTree() { DefaultMutableTreeNode top = new DefaultMutableTreeNode(resourceManager.getString("TreeDemo.music")); - DefaultMutableTreeNode catagory = null; + DefaultMutableTreeNode category = null; DefaultMutableTreeNode artist = null; DefaultMutableTreeNode record = null; @@ -103,12 +103,12 @@ char linetype = line.charAt(0); switch (linetype) { case 'C': - catagory = new DefaultMutableTreeNode(line.substring(2)); - top.add(catagory); + category = new DefaultMutableTreeNode(line.substring(2)); + top.add(category); break; case 'A': - if (catagory != null) { - catagory.add(artist = new DefaultMutableTreeNode(line.substring(2))); + if (category != null) { + category.add(artist = new DefaultMutableTreeNode(line.substring(2))); } break; case 'R':
--- a/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/tree.txt Thu Jul 25 02:16:49 2019 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/tree.txt Thu Jul 25 21:51:13 2019 +0000 @@ -8,7 +8,7 @@ # A = Artist / Composer # # R = Record / Style # # S = Song Name / Composition # -# C = Catagory # +# C = Category # # # ################################################################################ C Classical @@ -195,49 +195,49 @@ A The Beatles R A Hard Day's Night S A Hard Day's Night -S I Should Have Known Better -S If I Fell -S I'm Happy Just To Dance With You -S And I Love Her -S Tell Me Why -S Can't Buy Me Love -S Any Time At All -S I'll Cry Instead -S Things We Said Today -S When I Get Home -S You Can't Do That +S I Should Have Known Better +S If I Fell +S I'm Happy Just To Dance With You +S And I Love Her +S Tell Me Why +S Can't Buy Me Love +S Any Time At All +S I'll Cry Instead +S Things We Said Today +S When I Get Home +S You Can't Do That R Beatles For Sale -S No Reply -S I'm a Loser -S Baby's In Black -S Rock And Roll Music -S I'll Follow the Sun -S Mr. Moonlight -S Kansas City/Hey Hey Hey Hey -S Eight Days a Week -S Words Of Love -S Honey Don't -S Every Little Thing -S I Don't Want To Spoil the Party -S What You're Doing -S Everybody's Trying To Be My Baby +S No Reply +S I'm a Loser +S Baby's In Black +S Rock And Roll Music +S I'll Follow the Sun +S Mr. Moonlight +S Kansas City/Hey Hey Hey Hey +S Eight Days a Week +S Words Of Love +S Honey Don't +S Every Little Thing +S I Don't Want To Spoil the Party +S What You're Doing +S Everybody's Trying To Be My Baby R Help! -S Help! -S The Night Before -S You've Got To Hide Your Love Away -S I Need You -S Another Girl -S You're Going To Lose That Girl -S Ticket To Ride -S Act Naturally -S It's Only Love -S You Like Me Too Much -S Tell Me What You See -S I've Just Seen a Face -S Yesterday -S Dizzy Miss Lizzie +S Help! +S The Night Before +S You've Got To Hide Your Love Away +S I Need You +S Another Girl +S You're Going To Lose That Girl +S Ticket To Ride +S Act Naturally +S It's Only Love +S You Like Me Too Much +S Tell Me What You See +S I've Just Seen a Face +S Yesterday +S Dizzy Miss Lizzie R Rubber Soul -S Drive My Car +S Drive My Car S Norwegian Wood S You Won't See Me S Nowhere Man @@ -245,27 +245,27 @@ S The Word S Michelle S What Goes On? -S Girl -S I'm Looking Through You -S In My Life -S Wait -S If I Needed Someone -S Run For Your Life +S Girl +S I'm Looking Through You +S In My Life +S Wait +S If I Needed Someone +S Run For Your Life R Revolver -S Taxman -S Rigby -S I'm Only Sleeping -S For You To -S Here There And Everywhere +S Taxman +S Rigby +S I'm Only Sleeping +S For You To +S Here There And Everywhere S Yellow Submarine -S She Said She Said -S Good Day Sunshine -S And Your Bird Can Sing -S For No One -S Doctor Robert -S I Want To Tell You -S Got To Get You Into My Life -S Tomorrow Never Knows +S She Said She Said +S Good Day Sunshine +S And Your Bird Can Sing +S For No One +S Doctor Robert +S I Want To Tell You +S Got To Get You Into My Life +S Tomorrow Never Knows R Sgt. Pepper's Lonely Hearts Club Band S Sgt. Pepper's Lonely Hearts Club Band S With a Little Help From My Friends @@ -554,35 +554,35 @@ S What A Life A Komeda R Plan 714 Till -S Fuego De La Vida -S Herbamore -S Som I Fjol +S Fuego De La Vida +S Herbamore +S Som I Fjol S En Spricka I Taket R Genius Of -S More Is More -S Fire -S Rocket Plane (Music On The Moon) -S Boogie Woogie/Rock 'N' Roll -S Disko -S Top Star -S Light O' My Life -S If -S Frolic -S In Orbit -S Arbogast +S More Is More +S Fire +S Rocket Plane (Music On The Moon) +S Boogie Woogie/Rock 'N' Roll +S Disko +S Top Star +S Light O' My Life +S If +S Frolic +S In Orbit +S Arbogast S New New No R What Makes It Go -S Binario -S It's Alright, Baby -S Curious -S Cul de Sac -S Living Things -S Flabbergast -S Campfire -S Happyment -S Our Hospitality -S Focus -S A Simple Formality +S Binario +S It's Alright, Baby +S Curious +S Cul de Sac +S Living Things +S Flabbergast +S Campfire +S Happyment +S Our Hospitality +S Focus +S A Simple Formality A Steve Miller Band R Circle Of Love S Heart Like A Wheel
--- a/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java Thu Jul 25 02:16:49 2019 +0000 +++ b/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java Thu Jul 25 21:51:13 2019 +0000 @@ -26,6 +26,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -157,7 +158,24 @@ private static long getLongValueFromFile(SubSystem subSystem, String fileName) { String data = getFileContents(subSystem, fileName); - return data.isEmpty() ? 0L : Long.parseLong(data); + return data.isEmpty() ? 0L : convertStringToLong(data); + } + + private static long convertStringToLong(String strval) { + long retval = 0; + if (strval == null) return 0L; + + try { + retval = Long.parseLong(strval); + } catch (NumberFormatException e) { + // For some properties (e.g. memory.limit_in_bytes) we may overflow the range of signed long. + // In this case, return Long.MAX_VALUE + BigInteger b = new BigInteger(strval); + if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { + return Long.MAX_VALUE; + } + } + return retval; } private static long getLongValueFromFile(SubSystem subSystem, String metric, String subMetric) { @@ -165,7 +183,8 @@ String[] tokens = stats.split("[\\r\\n]+"); for (int i = 0; i < tokens.length; i++) { if (tokens[i].startsWith(subMetric)) { - return Long.parseLong(tokens[i].split("\\s+")[1]); + String strval = tokens[i].split("\\s+")[1]; + return convertStringToLong(strval); } } return 0L;