diff --git a/.hgtags b/.hgtags index 92fa13c8e58209f64996bb32ebe2eb0b86d095cf..4d8c782d55074e36f85d1066ce671ebbcbb93458 100644 --- a/.hgtags +++ b/.hgtags @@ -1266,3 +1266,4 @@ b2000ea410b0aa80d94a89105ba3dc8bdebd80b7 jdk8u212-b04 32bc598624bd33a1a8847e84f791559f18a69a49 jdk8u222-b02 af43bab3c5d022f0e0b7890f732d8b365b4364cc jdk8u222-b03 d690709cc3398f8cfd6ffebb89a229105fb3e69a jdk8u222-b04 +1ec20e8a3d8a7a29e9113b14567abec9f0240e9d jdk8u222-b05 diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README index 2543b7193fb953edc579fc9cdd3d967fe8b48f64..814e5f234580c3f1b7267dc11e189ea10ca95d5f 100644 --- a/THIRD_PARTY_README +++ b/THIRD_PARTY_README @@ -1612,7 +1612,7 @@ July 15, 2018 ------------------------------------------------------------------------------- -%% This notice is provided with respect to GIFLIB 5.1.1 & libungif 4.1.3, +%% This notice is provided with respect to GIFLIB 5.1.8 & libungif 4.1.3, which may be included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE --- @@ -1682,7 +1682,7 @@ which may be included with JRE 8, JDK 8, and OpenJDK 8 source distributions. --- begin of LICENSE --- Mesa 3-D graphics library - Version: 4.1 + Version: 5.0 Copyright (C) 1999-2002 Brian Paul All Rights Reserved. @@ -2797,61 +2797,8 @@ Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. -___________________________ -The files in motif/lib/Xm/util included this copyright:mkdirhier.man, -xmkmf.man, chownxterm.c, makeg.man, mergelib.cpp, lndir.man, makestrs.man, -checktree.c, lndir.c, makestrs.c -Copyright (c) 1993, 1994 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not -be used in advertising or otherwise to promote the sale, use or other -dealing in this Software without prior written authorization from the -X Consortium. -_____________________________ -Xmos_r.h: -/* -Copyright (c) 1996 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. -*/ +--- end of LICENSE --- _____________________________ Copyright notice for HPkeysym.h: /* @@ -2951,7 +2898,7 @@ included with JRE 8, JDK 8, and OpenJDK 8. Apache Jakarta BCEL 5.1 Apache Jakarta Regexp 1.4 Apache Santuario XML Security for Java 1.5.4 - Apache Xalan-Java 2.7.1 + Apache Xalan-Java 2.7.2 Apache Xerces Java 2.10.0 Apache XML Resolver 1.1 diff --git a/src/cpu/ppc/vm/assembler_ppc.hpp b/src/cpu/ppc/vm/assembler_ppc.hpp index 1c742edaeda2035b7a718d1d95b0a9091be4a852..b14f2b6d0ac13603e2cb542c5f0a14ea26ebcc46 100644 --- a/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.hpp @@ -472,7 +472,12 @@ class Assembler : public AbstractAssembler { LXVD2X_OPCODE = (31u << OPCODE_SHIFT | 844u << 1), STXVD2X_OPCODE = (31u << OPCODE_SHIFT | 972u << 1), MTVSRD_OPCODE = (31u << OPCODE_SHIFT | 179u << 1), + MTVSRWZ_OPCODE = (31u << OPCODE_SHIFT | 243u << 1), MFVSRD_OPCODE = (31u << OPCODE_SHIFT | 51u << 1), + MFVSRWZ_OPCODE = (31u << OPCODE_SHIFT | 115u << 1), + XXPERMDI_OPCODE= (60u << OPCODE_SHIFT | 10u << 3), + XXMRGHW_OPCODE = (60u << OPCODE_SHIFT | 18u << 3), + XXMRGLW_OPCODE = (60u << OPCODE_SHIFT | 50u << 3), // Vector Permute and Formatting VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ), @@ -522,6 +527,7 @@ class Assembler : public AbstractAssembler { VADDUBM_OPCODE = (4u << OPCODE_SHIFT | 0u ), VADDUWM_OPCODE = (4u << OPCODE_SHIFT | 128u ), VADDUHM_OPCODE = (4u << OPCODE_SHIFT | 64u ), + VADDUDM_OPCODE = (4u << OPCODE_SHIFT | 192u ), VADDUBS_OPCODE = (4u << OPCODE_SHIFT | 512u ), VADDUWS_OPCODE = (4u << OPCODE_SHIFT | 640u ), VADDUHS_OPCODE = (4u << OPCODE_SHIFT | 576u ), @@ -1056,16 +1062,19 @@ class Assembler : public AbstractAssembler { static int vrs( VectorRegister r) { return vrs(r->encoding());} static int vrt( VectorRegister r) { return vrt(r->encoding());} + // Only used on SHA sigma instructions (VX-form) + static int vst( int x) { return opp_u_field(x, 16, 16); } + static int vsix( int x) { return opp_u_field(x, 20, 17); } + // Support Vector-Scalar (VSX) instructions. - static int vsra( int x) { return opp_u_field(x, 15, 11); } - static int vsrb( int x) { return opp_u_field(x, 20, 16); } - static int vsrc( int x) { return opp_u_field(x, 25, 21); } - static int vsrs( int x) { return opp_u_field(x, 10, 6); } - static int vsrt( int x) { return opp_u_field(x, 10, 6); } + static int vsra( int x) { return opp_u_field(x & 0x1F, 15, 11) | opp_u_field((x & 0x20) >> 5, 29, 29); } + static int vsrb( int x) { return opp_u_field(x & 0x1F, 20, 16) | opp_u_field((x & 0x20) >> 5, 30, 30); } + static int vsrs( int x) { return opp_u_field(x & 0x1F, 10, 6) | opp_u_field((x & 0x20) >> 5, 31, 31); } + static int vsrt( int x) { return vsrs(x); } + static int vsdm( int x) { return opp_u_field(x, 23, 22); } static int vsra( VectorSRegister r) { return vsra(r->encoding());} static int vsrb( VectorSRegister r) { return vsrb(r->encoding());} - static int vsrc( VectorSRegister r) { return vsrc(r->encoding());} static int vsrs( VectorSRegister r) { return vsrs(r->encoding());} static int vsrt( VectorSRegister r) { return vsrt(r->encoding());} @@ -1869,6 +1878,7 @@ class Assembler : public AbstractAssembler { inline void vaddubm( VectorRegister d, VectorRegister a, VectorRegister b); inline void vadduwm( VectorRegister d, VectorRegister a, VectorRegister b); inline void vadduhm( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vaddudm( VectorRegister d, VectorRegister a, VectorRegister b); inline void vaddubs( VectorRegister d, VectorRegister a, VectorRegister b); inline void vadduws( VectorRegister d, VectorRegister a, VectorRegister b); inline void vadduhs( VectorRegister d, VectorRegister a, VectorRegister b); @@ -1944,6 +1954,7 @@ class Assembler : public AbstractAssembler { inline void vandc( VectorRegister d, VectorRegister a, VectorRegister b); inline void vnor( VectorRegister d, VectorRegister a, VectorRegister b); inline void vor( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vmr( VectorRegister d, VectorRegister a); inline void vxor( VectorRegister d, VectorRegister a, VectorRegister b); inline void vrld( VectorRegister d, VectorRegister a, VectorRegister b); inline void vrlb( VectorRegister d, VectorRegister a, VectorRegister b); @@ -1963,10 +1974,23 @@ class Assembler : public AbstractAssembler { inline void mfvscr( VectorRegister d); // Vector-Scalar (VSX) instructions. + inline void lxvd2x( VectorSRegister d, Register a); inline void lxvd2x( VectorSRegister d, Register a, Register b); + inline void stxvd2x( VectorSRegister d, Register a); inline void stxvd2x( VectorSRegister d, Register a, Register b); + inline void mtvrwz( VectorRegister d, Register a); + inline void mfvrwz( Register a, VectorRegister d); inline void mtvrd( VectorRegister d, Register a); inline void mfvrd( Register a, VectorRegister d); + inline void xxpermdi( VectorSRegister d, VectorSRegister a, VectorSRegister b, int dm); + inline void xxmrghw( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xxmrglw( VectorSRegister d, VectorSRegister a, VectorSRegister b); + + // VSX Extended Mnemonics + inline void xxspltd( VectorSRegister d, VectorSRegister a, int x); + inline void xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xxmrgld( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xxswapd( VectorSRegister d, VectorSRegister a); // AES (introduced with Power 8) inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b); diff --git a/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/src/cpu/ppc/vm/assembler_ppc.inline.hpp index c86e016273420c10884217998339a28fe259ce8f..1d2c05e2ab038da16b6bd7fbfd9cd143ca0e344c 100644 --- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -627,10 +627,23 @@ inline void Assembler::lvsl( VectorRegister d, Register s1, Register s2) { emit inline void Assembler::lvsr( VectorRegister d, Register s1, Register s2) { emit_int32( LVSR_OPCODE | vrt(d) | ra0mem(s1) | rb(s2)); } // Vector-Scalar (VSX) instructions. -inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); } -inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); } -inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec). -inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec). +inline void Assembler::lxvd2x( VectorSRegister d, Register s1) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); } +inline void Assembler::lxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::stxvd2x( VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); } +inline void Assembler::stxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } +inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } +inline void Assembler::mtvrwz( VectorRegister d, Register a) { emit_int32( MTVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); } +inline void Assembler::mfvrwz( Register a, VectorRegister d) { emit_int32( MFVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); } +inline void Assembler::xxpermdi(VectorSRegister d, VectorSRegister a, VectorSRegister b, int dm) { emit_int32( XXPERMDI_OPCODE | vsrt(d) | vsra(a) | vsrb(b) | vsdm(dm)); } +inline void Assembler::xxmrghw( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXMRGHW_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xxmrglw( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXMRGHW_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } + +// VSX Extended Mnemonics +inline void Assembler::xxspltd( VectorSRegister d, VectorSRegister a, int x) { xxpermdi(d, a, a, x ? 3 : 0); } +inline void Assembler::xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b) { xxpermdi(d, a, b, 0); } +inline void Assembler::xxmrgld( VectorSRegister d, VectorSRegister a, VectorSRegister b) { xxpermdi(d, a, b, 3); } +inline void Assembler::xxswapd( VectorSRegister d, VectorSRegister a) { xxpermdi(d, a, a, 2); } inline void Assembler::vpkpx( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKPX_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vpkshss( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKSHSS_OPCODE | vrt(d) | vra(a) | vrb(b)); } @@ -673,6 +686,7 @@ inline void Assembler::vaddsws( VectorRegister d, VectorRegister a, VectorRegist inline void Assembler::vaddubm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUBM_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vadduwm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUWM_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vadduhm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUHM_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vaddudm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUDM_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vaddubs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUBS_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vadduws( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUWS_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vadduhs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUHS_OPCODE | vrt(d) | vra(a) | vrb(b)); } @@ -749,6 +763,7 @@ inline void Assembler::vand( VectorRegister d, VectorRegister a, VectorRegist inline void Assembler::vandc( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VANDC_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vnor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNOR_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VOR_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vmr( VectorRegister d, VectorRegister a) { emit_int32( VOR_OPCODE | vrt(d) | vra(a) | vrb(a)); } inline void Assembler::vxor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VXOR_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vrld( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VRLD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vrlb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VRLB_OPCODE | vrt(d) | vra(a) | vrb(b)); } diff --git a/src/cpu/ppc/vm/register_ppc.cpp b/src/cpu/ppc/vm/register_ppc.cpp index 60ba9ed9182a9060db4c1814216b1a4e53fc086b..e24176b7ea68df0a64d06a922eb203d87a378810 100644 --- a/src/cpu/ppc/vm/register_ppc.cpp +++ b/src/cpu/ppc/vm/register_ppc.cpp @@ -81,8 +81,17 @@ const char* VectorSRegisterImpl::name() const { "VSR0", "VSR1", "VSR2", "VSR3", "VSR4", "VSR5", "VSR6", "VSR7", "VSR8", "VSR9", "VSR10", "VSR11", "VSR12", "VSR13", "VSR14", "VSR15", "VSR16", "VSR17", "VSR18", "VSR19", "VSR20", "VSR21", "VSR22", "VSR23", - "VSR24", "VSR25", "VSR26", "VSR27", "VSR28", "VSR29", "VSR30", "VSR31" + "VSR24", "VSR25", "VSR26", "VSR27", "VSR28", "VSR29", "VSR30", "VSR31", + "VSR32", "VSR33", "VSR34", "VSR35", "VSR36", "VSR37", "VSR38", "VSR39", + "VSR40", "VSR41", "VSR42", "VSR43", "VSR44", "VSR45", "VSR46", "VSR47", + "VSR48", "VSR49", "VSR50", "VSR51", "VSR52", "VSR53", "VSR54", "VSR55", + "VSR56", "VSR57", "VSR58", "VSR59", "VSR60", "VSR61", "VSR62", "VSR63" }; return is_valid() ? names[encoding()] : "vsnoreg"; } +// Method to convert a VectorRegister to a Vector-Scalar Register (VectorSRegister) +VectorSRegister VectorRegisterImpl::to_vsr() const { + if (this == vnoreg) { return vsnoregi; } + return as_VectorSRegister(encoding() + 32); +} diff --git a/src/cpu/ppc/vm/register_ppc.hpp b/src/cpu/ppc/vm/register_ppc.hpp index 9fa72a32bd6214954646c8e4b97277005be30a61..ed46fb2b77de66f84ebdd2e4b1f8f495590c13ab 100644 --- a/src/cpu/ppc/vm/register_ppc.hpp +++ b/src/cpu/ppc/vm/register_ppc.hpp @@ -399,6 +399,11 @@ inline VectorRegister as_VectorRegister(int encoding) { return (VectorRegister)(intptr_t)encoding; } +// Forward declaration +// Use VectorSRegister as a shortcut. +class VectorSRegisterImpl; +typedef VectorSRegisterImpl* VectorSRegister; + // The implementation of vector registers for the Power architecture class VectorRegisterImpl: public AbstractRegisterImpl { public: @@ -416,6 +421,9 @@ class VectorRegisterImpl: public AbstractRegisterImpl { bool is_valid() const { return 0 <= value() && value() < number_of_registers; } const char* name() const; + + // convert to VSR + VectorSRegister to_vsr() const; }; // The Vector registers of the Power architecture @@ -492,10 +500,6 @@ CONSTANT_REGISTER_DECLARATION(VectorRegister, VR31, (31)); #endif // DONT_USE_REGISTER_DEFINES -// Use VectorSRegister as a shortcut. -class VectorSRegisterImpl; -typedef VectorSRegisterImpl* VectorSRegister; - inline VectorSRegister as_VectorSRegister(int encoding) { return (VectorSRegister)(intptr_t)encoding; } @@ -504,7 +508,7 @@ inline VectorSRegister as_VectorSRegister(int encoding) { class VectorSRegisterImpl: public AbstractRegisterImpl { public: enum { - number_of_registers = 32 + number_of_registers = 64 }; // construction @@ -555,6 +559,38 @@ CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR28, (28)); CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR29, (29)); CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR30, (30)); CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR31, (31)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR32, (32)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR33, (33)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR34, (34)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR35, (35)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR36, (36)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR37, (37)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR38, (38)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR39, (39)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR40, (40)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR41, (41)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR42, (42)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR43, (43)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR44, (44)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR45, (45)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR46, (46)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR47, (47)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR48, (48)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR49, (49)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR50, (50)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR51, (51)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR52, (52)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR53, (53)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR54, (54)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR55, (55)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR56, (56)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR57, (57)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR58, (58)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR59, (59)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR60, (60)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR61, (61)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR62, (62)); +CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR63, (63)); #ifndef DONT_USE_REGISTER_DEFINES #define vsnoregi ((VectorSRegister)(vsnoreg_VectorSRegisterEnumValue)) @@ -590,6 +626,38 @@ CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR31, (31)); #define VSR29 ((VectorSRegister)( VSR29_VectorSRegisterEnumValue)) #define VSR30 ((VectorSRegister)( VSR30_VectorSRegisterEnumValue)) #define VSR31 ((VectorSRegister)( VSR31_VectorSRegisterEnumValue)) +#define VSR32 ((VectorSRegister)( VSR32_VectorSRegisterEnumValue)) +#define VSR33 ((VectorSRegister)( VSR33_VectorSRegisterEnumValue)) +#define VSR34 ((VectorSRegister)( VSR34_VectorSRegisterEnumValue)) +#define VSR35 ((VectorSRegister)( VSR35_VectorSRegisterEnumValue)) +#define VSR36 ((VectorSRegister)( VSR36_VectorSRegisterEnumValue)) +#define VSR37 ((VectorSRegister)( VSR37_VectorSRegisterEnumValue)) +#define VSR38 ((VectorSRegister)( VSR38_VectorSRegisterEnumValue)) +#define VSR39 ((VectorSRegister)( VSR39_VectorSRegisterEnumValue)) +#define VSR40 ((VectorSRegister)( VSR40_VectorSRegisterEnumValue)) +#define VSR41 ((VectorSRegister)( VSR41_VectorSRegisterEnumValue)) +#define VSR42 ((VectorSRegister)( VSR42_VectorSRegisterEnumValue)) +#define VSR43 ((VectorSRegister)( VSR43_VectorSRegisterEnumValue)) +#define VSR44 ((VectorSRegister)( VSR44_VectorSRegisterEnumValue)) +#define VSR45 ((VectorSRegister)( VSR45_VectorSRegisterEnumValue)) +#define VSR46 ((VectorSRegister)( VSR46_VectorSRegisterEnumValue)) +#define VSR47 ((VectorSRegister)( VSR47_VectorSRegisterEnumValue)) +#define VSR48 ((VectorSRegister)( VSR48_VectorSRegisterEnumValue)) +#define VSR49 ((VectorSRegister)( VSR49_VectorSRegisterEnumValue)) +#define VSR50 ((VectorSRegister)( VSR50_VectorSRegisterEnumValue)) +#define VSR51 ((VectorSRegister)( VSR51_VectorSRegisterEnumValue)) +#define VSR52 ((VectorSRegister)( VSR52_VectorSRegisterEnumValue)) +#define VSR53 ((VectorSRegister)( VSR53_VectorSRegisterEnumValue)) +#define VSR54 ((VectorSRegister)( VSR54_VectorSRegisterEnumValue)) +#define VSR55 ((VectorSRegister)( VSR55_VectorSRegisterEnumValue)) +#define VSR56 ((VectorSRegister)( VSR56_VectorSRegisterEnumValue)) +#define VSR57 ((VectorSRegister)( VSR57_VectorSRegisterEnumValue)) +#define VSR58 ((VectorSRegister)( VSR58_VectorSRegisterEnumValue)) +#define VSR59 ((VectorSRegister)( VSR59_VectorSRegisterEnumValue)) +#define VSR60 ((VectorSRegister)( VSR60_VectorSRegisterEnumValue)) +#define VSR61 ((VectorSRegister)( VSR61_VectorSRegisterEnumValue)) +#define VSR62 ((VectorSRegister)( VSR62_VectorSRegisterEnumValue)) +#define VSR63 ((VectorSRegister)( VSR63_VectorSRegisterEnumValue)) #endif // DONT_USE_REGISTER_DEFINES // Maximum number of incoming arguments that can be passed in i registers. @@ -610,7 +678,7 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl { * 2 // register halves + ConditionRegisterImpl::number_of_registers // condition code registers + SpecialRegisterImpl::number_of_registers // special registers - + VectorRegisterImpl::number_of_registers // vector registers + + VectorRegisterImpl::number_of_registers // VSX registers }; static const int max_gpr; diff --git a/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/src/cpu/ppc/vm/stubGenerator_ppc.cpp index 01fd08d4a887839693c15a864098edb03d50213f..12dd846cefa2ab01347fd3463bbc8846a6bfb0da 100644 --- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -1228,8 +1228,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_10); // Use loop with VSX load/store instructions to // copy 32 elements a time. - __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src - __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16 __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16 __ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32 @@ -1496,8 +1496,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_9); // Use loop with VSX load/store instructions to // copy 16 elements a time. - __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load from src. - __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst. + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load from src. + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst. __ lxvd2x(tmp_vsr2, R3_ARG1, tmp1); // Load from src + 16. __ stxvd2x(tmp_vsr2, R4_ARG2, tmp1); // Store to dst + 16. __ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32. @@ -1690,8 +1690,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_7); // Use loop with VSX load/store instructions to // copy 8 elements a time. - __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src - __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16 __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16 __ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32 @@ -1756,13 +1756,16 @@ class StubGenerator: public StubCodeGenerator { // Do reverse copy. We assume the case of actual overlap is rare enough // that we don't have to optimize it. - Label l_1, l_2, l_3, l_4, l_5, l_6; + Label l_1, l_2, l_3, l_4, l_5, l_6, l_7; Register tmp1 = R6_ARG4; Register tmp2 = R7_ARG5; Register tmp3 = R8_ARG6; Register tmp4 = R0; + VectorSRegister tmp_vsr1 = VSR1; + VectorSRegister tmp_vsr2 = VSR2; + { // FasterArrayCopy __ cmpwi(CCR0, R5_ARG3, 0); __ beq(CCR0, l_6); @@ -1772,6 +1775,25 @@ class StubGenerator: public StubCodeGenerator { __ add(R4_ARG2, R4_ARG2, R5_ARG3); __ srdi(R5_ARG3, R5_ARG3, 2); + if (!aligned) { + // check if arrays have same alignment mod 8. + __ xorr(tmp1, R3_ARG1, R4_ARG2); + __ andi_(R0, tmp1, 7); + // Not the same alignment, but ld and std just need to be 4 byte aligned. + __ bne(CCR0, l_7); // to OR from is 8 byte aligned -> copy 2 at a time + + // copy 1 element to align to and from on an 8 byte boundary + __ andi_(R0, R3_ARG1, 7); + __ beq(CCR0, l_7); + + __ addi(R3_ARG1, R3_ARG1, -4); + __ addi(R4_ARG2, R4_ARG2, -4); + __ addi(R5_ARG3, R5_ARG3, -1); + __ lwzx(tmp2, R3_ARG1); + __ stwx(tmp2, R4_ARG2); + __ bind(l_7); + } + __ cmpwi(CCR0, R5_ARG3, 7); __ ble(CCR0, l_5); // copy 1 at a time if less than 8 elements remain @@ -1779,6 +1801,7 @@ class StubGenerator: public StubCodeGenerator { __ andi(R5_ARG3, R5_ARG3, 7); __ mtctr(tmp1); + if (!VM_Version::has_vsx()) { __ bind(l_4); // Use unrolled version for mass copying (copy 4 elements a time). // Load feeding store gets zero latency on Power6, however not on Power5. @@ -1794,6 +1817,40 @@ class StubGenerator: public StubCodeGenerator { __ std(tmp2, 8, R4_ARG2); __ std(tmp1, 0, R4_ARG2); __ bdnz(l_4); + } else { // Processor supports VSX, so use it to mass copy. + // Prefetch the data into the L2 cache. + __ dcbt(R3_ARG1, 0); + + // If supported set DSCR pre-fetch to deepest. + if (VM_Version::has_mfdscr()) { + __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7); + __ mtdscr(tmp2); + } + + __ li(tmp1, 16); + + // Backbranch target aligned to 32-byte. Not 16-byte align as + // loop contains < 8 instructions that fit inside a single + // i-cache sector. + __ align(32); + + __ bind(l_4); + // Use loop with VSX load/store instructions to + // copy 8 elements a time. + __ addi(R3_ARG1, R3_ARG1, -32); // Update src-=32 + __ addi(R4_ARG2, R4_ARG2, -32); // Update dsc-=32 + __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src+16 + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src + __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst+16 + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst + __ bdnz(l_4); + + // Restore DSCR pre-fetch value. + if (VM_Version::has_mfdscr()) { + __ load_const_optimized(tmp2, VM_Version::_dscr_val); + __ mtdscr(tmp2); + } + } __ cmpwi(CCR0, R5_ARG3, 0); __ beq(CCR0, l_6); @@ -1908,8 +1965,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_5); // Use loop with VSX load/store instructions to // copy 4 elements a time. - __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src - __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16 __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16 __ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32 @@ -1976,6 +2033,9 @@ class StubGenerator: public StubCodeGenerator { Register tmp3 = R8_ARG6; Register tmp4 = R0; + VectorSRegister tmp_vsr1 = VSR1; + VectorSRegister tmp_vsr2 = VSR2; + Label l_1, l_2, l_3, l_4, l_5; __ cmpwi(CCR0, R5_ARG3, 0); @@ -1994,6 +2054,7 @@ class StubGenerator: public StubCodeGenerator { __ andi(R5_ARG3, R5_ARG3, 3); __ mtctr(tmp1); + if (!VM_Version::has_vsx()) { __ bind(l_4); // Use unrolled version for mass copying (copy 4 elements a time). // Load feeding store gets zero latency on Power6, however not on Power5. @@ -2009,6 +2070,40 @@ class StubGenerator: public StubCodeGenerator { __ std(tmp2, 8, R4_ARG2); __ std(tmp1, 0, R4_ARG2); __ bdnz(l_4); + } else { // Processor supports VSX, so use it to mass copy. + // Prefetch the data into the L2 cache. + __ dcbt(R3_ARG1, 0); + + // If supported set DSCR pre-fetch to deepest. + if (VM_Version::has_mfdscr()) { + __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7); + __ mtdscr(tmp2); + } + + __ li(tmp1, 16); + + // Backbranch target aligned to 32-byte. Not 16-byte align as + // loop contains < 8 instructions that fit inside a single + // i-cache sector. + __ align(32); + + __ bind(l_4); + // Use loop with VSX load/store instructions to + // copy 4 elements a time. + __ addi(R3_ARG1, R3_ARG1, -32); // Update src-=32 + __ addi(R4_ARG2, R4_ARG2, -32); // Update dsc-=32 + __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src+16 + __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src + __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst+16 + __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst + __ bdnz(l_4); + + // Restore DSCR pre-fetch value. + if (VM_Version::has_mfdscr()) { + __ load_const_optimized(tmp2, VM_Version::_dscr_val); + __ mtdscr(tmp2); + } + } __ cmpwi(CCR0, R5_ARG3, 0); __ beq(CCR0, l_1); diff --git a/src/cpu/ppc/vm/vm_version_ppc.cpp b/src/cpu/ppc/vm/vm_version_ppc.cpp index 5620895c09d1dd60d809e60196b20aef2fbc4638..6761c02a231157e0261e090ae35929cc6a6d4473 100644 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -502,7 +502,7 @@ void VM_Version::determine_features() { a->vcipher(VR0, VR1, VR2); // code[11] -> vcipher a->vpmsumb(VR0, VR1, VR2); // code[12] -> vpmsumb a->mfdscr(R0); // code[13] -> mfdscr - a->lxvd2x(VSR0, 0, R3_ARG1); // code[14] -> vsx + a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx a->blr(); // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp index 104aaaef77b1d4a2863c02b8f390c1c39d71339f..da380e622edb4841f730caeb8ba9f39dc81c7b30 100644 --- a/src/share/vm/compiler/compileBroker.cpp +++ b/src/share/vm/compiler/compileBroker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -751,7 +751,9 @@ CompileTask* CompileQueue::get() { No_Safepoint_Verifier nsv; task = CompilationPolicy::policy()->select_task(this); } - remove(task); + if (task != NULL) { + remove(task); + } purge_stale_tasks(); // may temporarily release MCQ lock return task; } diff --git a/src/share/vm/compiler/compileBroker.hpp b/src/share/vm/compiler/compileBroker.hpp index 7a381cd3addfb778b54ac1830558ba2ed5d726e4..ad37ff173adb7bfc327dd535dec4efe1294d986f 100644 --- a/src/share/vm/compiler/compileBroker.hpp +++ b/src/share/vm/compiler/compileBroker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -339,7 +339,6 @@ class CompileBroker: AllStatic { static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS); static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); - static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); static bool is_compile_blocking (); static void preload_classes (methodHandle method, TRAPS); @@ -389,6 +388,7 @@ class CompileBroker: AllStatic { return NULL; } + static bool compilation_is_complete(methodHandle method, int osr_bci, int comp_level); static bool compilation_is_in_queue(methodHandle method); static int queue_size(int comp_level) { CompileQueue *q = compile_queue(comp_level); diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index 2cff42cc39fa8da29f0bacf988160f7ae1316dbb..6aff230b6227a8725116504f6809377d0f421a11 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -2925,6 +2925,13 @@ void InstanceKlass::adjust_default_methods(InstanceKlass* holder, bool* trace_na // On-stack replacement stuff void InstanceKlass::add_osr_nmethod(nmethod* n) { +#ifndef PRODUCT + if (TieredCompilation) { + nmethod * prev = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), n->comp_level(), true); + assert(prev == NULL || !prev->is_in_use(), + "redundunt OSR recompilation detected. memory leak in CodeCache!"); + } +#endif // only one compilation can be active NEEDS_CLEANUP // This is a short non-blocking critical region, so the no safepoint check is ok. @@ -3046,7 +3053,9 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le osr = osr->osr_link(); } OsrList_lock->unlock(); - if (best != NULL && best->comp_level() >= comp_level && match_level == false) { + + assert(match_level == false || best == NULL, "shouldn't pick up anything if match_level is set"); + if (best != NULL && best->comp_level() >= comp_level) { return best; } return NULL; diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp index af5693749371636ed3e2e51865ef8e74156499ad..14b0ff9a9761dd26ad8f611e518a56de7e592b11 100644 --- a/src/share/vm/opto/memnode.cpp +++ b/src/share/vm/opto/memnode.cpp @@ -3353,9 +3353,6 @@ bool InitializeNode::detect_init_independence(Node* n, int& count) { // within the initialized memory. intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape) { const int FAIL = 0; - if (st->is_unaligned_access()) { - return FAIL; - } if (st->req() != MemNode::ValueIn + 1) return FAIL; // an inscrutable StoreNode (card mark?) Node* ctl = st->in(MemNode::Control); @@ -3371,6 +3368,10 @@ intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, return FAIL; // inscrutable address if (alloc != allocation()) return FAIL; // wrong allocation! (store needs to float up) + int size_in_bytes = st->memory_size(); + if ((size_in_bytes != 0) && (offset % size_in_bytes) != 0) { + return FAIL; // mismatched access + } Node* val = st->in(MemNode::ValueIn); int complexity_count = 0; if (!detect_init_independence(val, complexity_count)) diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp index e44e17d0bc7e69d9c35bfc654ff917b2ec31fff8..116d0f37c908d8ba8989eec6cd6fa5fd3169ee7c 100644 --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -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 @@ -633,6 +633,25 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) } WB_END +WB_ENTRY(void, WB_MarkMethodProfiled(JNIEnv* env, jobject o, jobject method)) + jmethodID jmid = reflected_method_to_jmid(thread, env, method); + CHECK_JNI_EXCEPTION(env); + methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); + + MethodData* mdo = mh->method_data(); + if (mdo == NULL) { + Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR); + mdo = mh->method_data(); + } + mdo->init(); + InvocationCounter* icnt = mdo->invocation_counter(); + InvocationCounter* bcnt = mdo->backedge_counter(); + // set i-counter according to AdvancedThresholdPolicy::is_method_profiled + // because SimpleThresholdPolicy::call_predicate_helper uses > in jdk8u, that's why we need to plus one. + icnt->set(InvocationCounter::wait_for_compile, Tier4MinInvocationThreshold + 1); + bcnt->set(InvocationCounter::wait_for_compile, Tier4CompileThreshold + 1); +WB_END + template static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { if (name == NULL) { @@ -848,19 +867,23 @@ WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jbo ThreadToNativeFromVM ttn(thread); jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); CHECK_JNI_EXCEPTION_(env, NULL); - result = env->NewObjectArray(2, clazz, NULL); + result = env->NewObjectArray(3, clazz, NULL); if (result == NULL) { return result; } - jobject obj = integerBox(thread, env, code->comp_level()); + jobject level = integerBox(thread, env, code->comp_level()); + CHECK_JNI_EXCEPTION_(env, NULL); + env->SetObjectArrayElement(result, 0, level); + + jobject id = integerBox(thread, env, code->compile_id()); CHECK_JNI_EXCEPTION_(env, NULL); - env->SetObjectArrayElement(result, 0, obj); + env->SetObjectArrayElement(result, 1, id); jbyteArray insts = env->NewByteArray(insts_size); CHECK_JNI_EXCEPTION_(env, NULL); env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin()); - env->SetObjectArrayElement(result, 1, insts); + env->SetObjectArrayElement(result, 2, insts); return result; WB_END @@ -1119,6 +1142,8 @@ static JNINativeMethod methods[] = { CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, {CC"clearMethodState", CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, + {CC"markMethodProfiled", + CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_MarkMethodProfiled}, {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag}, diff --git a/src/share/vm/runtime/advancedThresholdPolicy.cpp b/src/share/vm/runtime/advancedThresholdPolicy.cpp index 2119f0c4f17e3578fbc63c0098f516e6981f329d..c43528322816b802f3b51236f08021c4a793607f 100644 --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -196,6 +196,16 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile && is_method_profiled(max_method)) { + + if (CompileBroker::compilation_is_complete(max_method, max_task->osr_bci(), CompLevel_limited_profile)) { + if (PrintTieredEvents) { + print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); + } + compile_queue->remove_and_mark_stale(max_task); + max_method->clear_queued_for_compilation(); + return NULL; + } + max_task->set_comp_level(CompLevel_limited_profile); if (PrintTieredEvents) { print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); diff --git a/test/compiler/c2/Test8202414.java b/test/compiler/c2/Test8202414.java new file mode 100644 index 0000000000000000000000000000000000000000..1d8ef8d936a478a4f03887959a4ecfb772f524db --- /dev/null +++ b/test/compiler/c2/Test8202414.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019, Huawei Technologies Co. Ltd. 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 8202414 + * @summary Unsafe write after primitive array creation may result in array length change + * @requires (os.arch != "sparc") & (os.arch != "sparcv9") + * @run main/othervm compiler.c2.Test8202414 + */ + +package compiler.c2; + +import sun.misc.Unsafe; +import java.lang.reflect.Field; +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class Test8202414 { + + public static void main(String[] args) { + System.err.close(); + int count = 0; + while (count++ < 120000) { + test(); + } + } + + public static void test() { + byte[] newBufb = serByte(397); + short[] newBufs = serShort(397); + int[] newBufi = serInt(397); + long[] newBufl = serLong(397); + if (newBufb.length != 397 || newBufs.length != 397 + || newBufi.length != 397 || newBufl.length != 397) { + System.out.println("array length internal error"); + throw new RuntimeException("Test failed"); + } + + } + + public static byte[] serByte(int bufLen) { + byte[] buf = new byte[bufLen]; + THE_UNSAFE.putByte(buf, BYTE_ARRAY_BASE_OFFSET + 1, (byte) buf.length); + System.err.println("ref " + buf); + return buf; + } + + public static short[] serShort(int bufLen) { + short[] buf = new short[bufLen]; + THE_UNSAFE.putShort(buf, SHORT_ARRAY_BASE_OFFSET + 1, (short) buf.length); + System.err.println("ref " + buf); + return buf; + } + + public static int[] serInt(int bufLen) { + int[] buf = new int[bufLen]; + THE_UNSAFE.putInt(buf, INT_ARRAY_BASE_OFFSET + 1, buf.length); + System.err.println("ref " + buf); + return buf; + } + + public static long[] serLong(int bufLen) { + long[] buf = new long[bufLen]; + THE_UNSAFE.putLong(buf, LONG_ARRAY_BASE_OFFSET + 1, buf.length); + System.err.println("ref " + buf); + return buf; + } + + /* Unsafe fields and initialization + */ + static final Unsafe THE_UNSAFE; + static final long BYTE_ARRAY_BASE_OFFSET; + static final long SHORT_ARRAY_BASE_OFFSET; + static final long INT_ARRAY_BASE_OFFSET; + static final long LONG_ARRAY_BASE_OFFSET; + static { + THE_UNSAFE = (Unsafe) AccessController.doPrivileged ( + new PrivilegedAction() { + @Override + public Object run() { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return f.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new Error(); + } + } + } + ); + BYTE_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(byte[].class); + SHORT_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(short[].class); + INT_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(int[].class); + LONG_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(long[].class); + } +} diff --git a/test/compiler/tiered/ConstantGettersTransitionsTest.java b/test/compiler/tiered/ConstantGettersTransitionsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2de9dc57843e435565dabdd4a33c29ec38632e14 --- /dev/null +++ b/test/compiler/tiered/ConstantGettersTransitionsTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Executable; +import java.util.concurrent.Callable; + +/** + * @test ConstantGettersTransitionsTest + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @build TransitionsTestExecutor ConstantGettersTransitionsTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=240 -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * -XX:CompileCommand=compileonly,ConstantGettersTestCase$TrivialMethods::* + * TransitionsTestExecutor ConstantGettersTransitionsTest + * @summary Test the correctness of compilation level transitions for constant getters methods + */ +public class ConstantGettersTransitionsTest extends LevelTransitionTest { + public static void main(String[] args) { + assert (!CompilerWhiteBoxTest.skipOnTieredCompilation(false)); + + // run test cases + for (TestCase testCase : ConstantGettersTestCase.values()) { + new ConstantGettersTransitionsTest(testCase).runTest(); + } + } + + @Override + protected boolean isTrivial() { + return true; + } + + private ConstantGettersTransitionsTest(TestCase testCase) { + super(testCase); + } +} + +enum ConstantGettersTestCase implements CompilerWhiteBoxTest.TestCase { + ICONST_M1, + ICONST_0, + ICONST_1, + ICONST_2, + ICONST_3, + ICONST_4, + ICONST_5, + LCONST_0, + LCONST_1, + FCONST_0, + FCONST_1, + FCONST_2, + DCONST_0, + DCONST_1, + DCONST_W, + BYTE, + SHORT, + CHAR; + + private final Executable executable; + private final Callable callable; + + @Override + public Executable getExecutable() { + return executable; + } + + @Override + public Callable getCallable() { + return callable; + } + + @Override + public boolean isOsr() { + return false; + } + + private ConstantGettersTestCase() { + String name = "make" + this.name(); + this.executable = LevelTransitionTest.Helper.getMethod(TrivialMethods.class, name); + this.callable = LevelTransitionTest.Helper.getCallable(new TrivialMethods(), name); + } + + /** + * Contains methods that load constants with certain types of bytecodes + * See JVMS 2.11.2. Load and Store Instructions + * Note that it doesn't have a method for ldc_w instruction + */ + private static class TrivialMethods { + public static int makeICONST_M1() { + return -1; + } + + public static int makeICONST_0() { + return 0; + } + + public static int makeICONST_1() { + return 1; + } + + public static int makeICONST_2() { + return 2; + } + + public static int makeICONST_3() { + return 3; + } + + public static int makeICONST_4() { + return 4; + } + + public static int makeICONST_5() { + return 5; + } + + public static long makeLCONST_0() { + return 0L; + } + + public static long makeLCONST_1() { + return 1L; + } + + public static float makeFCONST_0() { + return 0F; + } + + public static float makeFCONST_1() { + return 1F; + } + + public static float makeFCONST_2() { + return 2F; + } + + public static double makeDCONST_0() { + return 0D; + } + + public static double makeDCONST_1() { + return 1D; + } + + public static double makeDCONST_W() { + // ldc2_w + return Double.MAX_VALUE; + } + + public static Object makeOBJECT() { + // aconst_null + return null; + } + + public static byte makeBYTE() { + // bipush + return (byte) 0x7F; + } + + public static short makeSHORT() { + // sipush + return (short) 0x7FFF; + } + + public static char makeCHAR() { + // ldc + return (char) 0xFFFF; + } + + public static boolean makeBOOLEAN() { + return true; + } + } +} diff --git a/test/compiler/tiered/Level2RecompilationTest.java b/test/compiler/tiered/Level2RecompilationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..eb3b6b2f466eef5eebb0cf6140085d688234c724 --- /dev/null +++ b/test/compiler/tiered/Level2RecompilationTest.java @@ -0,0 +1,92 @@ +/* + * 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 Level2RecompilationTest + * @summary Test downgrading mechanism from level 3 to level 2 for those profiled methods. + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @build Level2RecompilationTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-UseCounterDecay + * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* + * -XX:CompileCommand=print,SimpleTestCase$Helper::* + * Level2RecompilationTest + */ +public class Level2RecompilationTest extends CompLevelsTest { + public static void main(String[] args) throws Throwable { + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { + throw new RuntimeException("Test isn't applicable for non-tiered mode"); + } + String[] testcases = {"METHOD_TEST", "OSR_STATIC_TEST"}; + CompilerWhiteBoxTest.main(Level2RecompilationTest::new, testcases); + } + + protected Level2RecompilationTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); + } + + @Override + protected void test() throws Exception { + if (skipXcompOSR()) { + return; + } + + checkNotCompiled(); + int bci = WHITE_BOX.getMethodEntryBci(method); + WHITE_BOX.markMethodProfiled(method); + if (testCase.isOsr()) { + // for OSR compilation, it must be the begin of a BB. + // c1_GraphBulider.cpp:153 assert(method()->bci_block_start().at(cur_bci), ... + bci = 0; + } + + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci); + checkCompiled(); + checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel()); + + for (int i=0; i<100; ++i) { + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci); + waitBackgroundCompilation(); + checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel()); + } + } + + @Override + protected void checkLevel(int expected, int actual) { + if (expected == COMP_LEVEL_FULL_PROFILE + && actual == COMP_LEVEL_LIMITED_PROFILE) { + // for simple method full_profile may be replaced by limited_profile + if (IS_VERBOSE) { + System.out.printf("Level check: full profiling was replaced " + + "by limited profiling. Expected: %d, actual:%d\n", + expected, actual); + } + return; + } + super.checkLevel(expected, actual); + } +} + diff --git a/test/compiler/tiered/LevelTransitionTest.java b/test/compiler/tiered/LevelTransitionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..84ead05d1ea5e96f1b251414e569413c4e015bb6 --- /dev/null +++ b/test/compiler/tiered/LevelTransitionTest.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.Callable; + +/** + * @test LevelTransitionTest + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @build TransitionsTestExecutor LevelTransitionTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=240 -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* + * -XX:CompileCommand=compileonly,ExtendedTestCase$CompileMethodHolder::* + * TransitionsTestExecutor LevelTransitionTest + * @summary Test the correctness of compilation level transitions for different methods + */ +public class LevelTransitionTest extends TieredLevelsTest { + /** Shows if method was profiled by being executed on levels 2 or 3 */ + protected boolean isMethodProfiled; + private int transitionCount; + + public static void main(String[] args) throws Throwable { + assert (!CompilerWhiteBoxTest.skipOnTieredCompilation(false)); + + CompilerWhiteBoxTest.main(LevelTransitionTest::new, args); + // run extended test cases + for (TestCase testCase : ExtendedTestCase.values()) { + new LevelTransitionTest(testCase).runTest(); + } + } + + protected LevelTransitionTest(TestCase testCase) { + super(testCase); + isMethodProfiled = testCase.isOsr(); // OSR methods were already profiled by warmup + transitionCount = 0; + } + + @Override + protected void test() throws Exception { + checkTransitions(); + deoptimize(); + printInfo(); + if (testCase.isOsr()) { + // deoptimization makes the following transitions be unstable + // methods go to level 3 before 4 because of uncommon_trap and reprofile + return; + } + checkTransitions(); + } + + /** + * Makes and verifies transitions between compilation levels + */ + protected void checkTransitions() { + checkNotCompiled(); + boolean finish = false; + while (!finish) { + System.out.printf("Level transition #%d%n", ++transitionCount); + int newLevel; + int current = getCompLevel(); + int expected = getNextLevel(current); + if (current == expected) { + // if we are on expected level, just execute it more + // to ensure that the level won't change + System.out.printf("Method %s is already on expected level %d%n", method, expected); + compile(); + newLevel = getCompLevel(); + finish = true; + } else { + newLevel = changeCompLevel(); + finish = false; + } + System.out.printf("Method %s is compiled on level %d. Expected level is %d%n", method, newLevel, expected); + checkLevel(expected, newLevel); + printInfo(); + }; + } + + /** + * Gets next expected level for the test case on each transition. + * + * @param currentLevel a level the test case is compiled on + * @return expected compilation level + */ + protected int getNextLevel(int currentLevel) { + int nextLevel = currentLevel; + switch (currentLevel) { + case CompilerWhiteBoxTest.COMP_LEVEL_NONE: + nextLevel = isMethodProfiled ? CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION + : CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE; + break; + case CompilerWhiteBoxTest.COMP_LEVEL_LIMITED_PROFILE: + case CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE: + nextLevel = CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION; + isMethodProfiled = true; + break; + } + nextLevel = isTrivial() ? CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE : nextLevel; + return Math.min(nextLevel, CompilerWhiteBoxTest.TIERED_STOP_AT_LEVEL); + } + + /** + * Determines if tested method should be handled as trivial + * + * @return {@code true} for trivial methods, {@code false} otherwise + */ + protected boolean isTrivial() { + return testCase == ExtendedTestCase.ACCESSOR_TEST + || testCase == SimpleTestCase.METHOD_TEST + || testCase == SimpleTestCase.STATIC_TEST + || (testCase == ExtendedTestCase.TRIVIAL_CODE_TEST && isMethodProfiled); + } + + /** + * Invokes {@linkplain #method} until its compilation level is changed. + * Note that if the level won't change, it will be an endless loop + * + * @return compilation level the {@linkplain #method} was compiled on + */ + protected int changeCompLevel() { + int currentLevel = getCompLevel(); + int newLevel = currentLevel; + int result = 0; + while (currentLevel == newLevel) { + result = compile(1); + if (WHITE_BOX.isMethodCompiled(method, testCase.isOsr())) { + newLevel = getCompLevel(); + } + } + return newLevel; + } + + protected static class Helper { + /** + * Gets method from a specified class using its name + * + * @param aClass type method belongs to + * @param name the name of the method + * @return {@link Method} that represents corresponding class method + */ + public static Method getMethod(Class aClass, String name) { + Method method; + try { + method = aClass.getDeclaredMethod(name); + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG: Unable to get method " + name, e); + } + return method; + } + + /** + * Gets {@link Callable} that invokes given method from the given object + * + * @param object the object the specified method is invoked from + * @param name the name of the method + */ + public static Callable getCallable(Object object, String name) { + Method method = getMethod(object.getClass(), name); + return () -> { + try { + return Objects.hashCode(method.invoke(object)); + } catch (ReflectiveOperationException e) { + throw new Error("TESTBUG: Invocation failure", e); + } + }; + } + } +} + +enum ExtendedTestCase implements CompilerWhiteBoxTest.TestCase { + ACCESSOR_TEST("accessor"), + NONTRIVIAL_METHOD_TEST("nonTrivialMethod"), + TRIVIAL_CODE_TEST("trivialCode"); + + private final Executable executable; + private final Callable callable; + + @Override + public Executable getExecutable() { + return executable; + } + + @Override + public Callable getCallable() { + return callable; + } + + @Override + public boolean isOsr() { + return false; + } + + private ExtendedTestCase(String methodName) { + this.executable = LevelTransitionTest.Helper.getMethod(CompileMethodHolder.class, methodName); + this.callable = LevelTransitionTest.Helper.getCallable(new CompileMethodHolder(), methodName); + } + + private static class CompileMethodHolder { + private final int iter = 10; + private int field = 42; + + /** Non-trivial method for threshold policy: contains loops */ + public int nonTrivialMethod() { + int acc = 0; + for (int i = 0; i < iter; i++) { + acc += i; + } + return acc; + } + + /** Field accessor method */ + public int accessor() { + return field; + } + + /** Method considered as trivial by amount of code */ + public int trivialCode() { + int var = 0xBAAD_C0DE; + var *= field; + return var; + } + } +} diff --git a/test/compiler/tiered/NonTieredLevelsTest.java b/test/compiler/tiered/NonTieredLevelsTest.java index 13411a0dd733dff999044923cd2929613e7b2013..c089792e92708d446c58fca62aedb5ea9a3c7782 100644 --- a/test/compiler/tiered/NonTieredLevelsTest.java +++ b/test/compiler/tiered/NonTieredLevelsTest.java @@ -54,9 +54,7 @@ public class NonTieredLevelsTest extends CompLevelsTest { } public static void main(String[] args) throws Exception { - if (TIERED_COMPILATION) { - System.err.println("Test isn't applicable w/ enabled " - + "TieredCompilation. Skip test."); + if (CompilerWhiteBoxTest.skipOnTieredCompilation(true)) { return; } CompilerWhiteBoxTest.main(NonTieredLevelsTest::new, args); diff --git a/test/compiler/tiered/TieredLevelsTest.java b/test/compiler/tiered/TieredLevelsTest.java index 9fb2254d0b54a8c3f3603c8ab5fa75bfa4c4b844..28d2f76acb4dc438525b5899b2a143bbce4db126 100644 --- a/test/compiler/tiered/TieredLevelsTest.java +++ b/test/compiler/tiered/TieredLevelsTest.java @@ -34,16 +34,14 @@ * @author igor.ignatyev@oracle.com */ public class TieredLevelsTest extends CompLevelsTest { - public static void main(String[] args) throws Exception { - if (!TIERED_COMPILATION) { - System.err.println("Test isn't applicable w/ disabled " - + "TieredCompilation. Skip test."); + public static void main(String[] args) throws Exception, Throwable { + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { return; } CompilerWhiteBoxTest.main(TieredLevelsTest::new, args); } - private TieredLevelsTest(TestCase testCase) { + protected TieredLevelsTest(TestCase testCase) { super(testCase); // to prevent inlining of #method WHITE_BOX.testSetDontInlineMethod(method, true); @@ -76,14 +74,18 @@ public class TieredLevelsTest extends CompLevelsTest { } } - @Override protected void checkLevel(int expected, int actual) { if (expected == COMP_LEVEL_FULL_PROFILE && actual == COMP_LEVEL_LIMITED_PROFILE) { // for simple method full_profile may be replaced by limited_profile + if (IS_VERBOSE) { + System.out.printf("Level check: full profiling was replaced " + + "by limited profiling. Expected: %d, actual:%d", + expected, actual); + } return; } super.checkLevel(expected, actual); - } + } } diff --git a/test/compiler/tiered/TransitionsTestExecutor.java b/test/compiler/tiered/TransitionsTestExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..15f731b503fd8dc47423db19339043c5424c9efb --- /dev/null +++ b/test/compiler/tiered/TransitionsTestExecutor.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Executes given test in a separate VM with enabled Tiered Compilation for + * CompilationPolicyChoice 2 and 3 + */ +public class TransitionsTestExecutor { + public static void main(String[] args) throws Throwable { + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { + return; + } + if (args.length != 1) { + throw new Error("TESTBUG: Test name should be specified"); + } + executeTestFor(2, args[0]); + executeTestFor(3, args[0]); + } + + private static void executeTestFor(int compilationPolicy, String testName) throws Throwable { + String policy = "-XX:CompilationPolicyChoice=" + compilationPolicy; + + // Get runtime arguments including VM options given to this executor + RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); + List vmArgs = runtime.getInputArguments(); + + // Construct execution command with compilation policy choice and test name + List args = new ArrayList<>(vmArgs); + Collections.addAll(args, policy, testName); + + OutputAnalyzer out = ProcessTools.executeTestJvm(args.toArray(new String[args.size()])); + int exitCode = out.getExitValue(); + if (exitCode != 0) { + throw new Error("Test execution failed with exit code " + exitCode); + } + } +} diff --git a/test/compiler/whitebox/CompilerWhiteBoxTest.java b/test/compiler/whitebox/CompilerWhiteBoxTest.java index a391ba20e0b5c8eaa58b3d039fe81538f8a5a835..1bea0033a83d8bb21cc52a329e195ad9c27957e2 100644 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java @@ -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 @@ -41,19 +41,19 @@ import java.util.function.Function; */ public abstract class CompilerWhiteBoxTest { /** {@code CompLevel::CompLevel_none} -- Interpreter */ - protected static int COMP_LEVEL_NONE = 0; + protected static final int COMP_LEVEL_NONE = 0; /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ - protected static int COMP_LEVEL_ANY = -1; + protected static final int COMP_LEVEL_ANY = -1; /** {@code CompLevel::CompLevel_simple} -- C1 */ - protected static int COMP_LEVEL_SIMPLE = 1; + protected static final int COMP_LEVEL_SIMPLE = 1; /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */ - protected static int COMP_LEVEL_LIMITED_PROFILE = 2; + protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */ - protected static int COMP_LEVEL_FULL_PROFILE = 3; + protected static final int COMP_LEVEL_FULL_PROFILE = 3; /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ - protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4; + protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; /** Maximal value for CompLevel */ - protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; + protected static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; /** Instance of WhiteBox */ protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); @@ -328,11 +328,11 @@ public abstract class CompilerWhiteBoxTest { return; } final Object obj = new Object(); - for (int i = 0; i < 10 + for (int i = 0; i < 100 && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { synchronized (obj) { try { - obj.wait(1000); + obj.wait(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -347,14 +347,22 @@ public abstract class CompilerWhiteBoxTest { System.out.printf("%n%s:%n", method); System.out.printf("\tcompilable:\t%b%n", WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false)); - System.out.printf("\tcompiled:\t%b%n", - WHITE_BOX.isMethodCompiled(method, false)); + boolean isCompiled = WHITE_BOX.isMethodCompiled(method, false); + System.out.printf("\tcompiled:\t%b%n", isCompiled); + if (isCompiled) { + System.out.printf("\tcompile_id:\t%d%n", + NMethod.get(method, false).compile_id); + } System.out.printf("\tcomp_level:\t%d%n", WHITE_BOX.getMethodCompilationLevel(method, false)); System.out.printf("\tosr_compilable:\t%b%n", WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true)); - System.out.printf("\tosr_compiled:\t%b%n", - WHITE_BOX.isMethodCompiled(method, true)); + isCompiled = WHITE_BOX.isMethodCompiled(method, true); + System.out.printf("\tosr_compiled:\t%b%n", isCompiled); + if (isCompiled) { + System.out.printf("\tosr_compile_id:\t%d%n", + NMethod.get(method, true).compile_id); + } System.out.printf("\tosr_comp_level:\t%d%n", WHITE_BOX.getMethodCompilationLevel(method, true)); System.out.printf("\tin_queue:\t%b%n", @@ -437,6 +445,22 @@ public abstract class CompilerWhiteBoxTest { } return result; } + + /** + * Skip the test for the specified value of Tiered Compilation + * @param value of TieredCompilation the test should not run with + * @return {@code true} if the test should be skipped, + * {@code false} otherwise + */ + protected static boolean skipOnTieredCompilation(boolean value) { + if (value == CompilerWhiteBoxTest.TIERED_COMPILATION) { + System.err.println("Test isn't applicable w/ " + + (value ? "enabled" : "disabled") + + "TieredCompilation. Skip test."); + return true; + } + return false; + } } enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { diff --git a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index 694e3dade761fe96f9979fbaeb21da6afb40ace0..1327bd30da5ee2b391961cc235d7e84fadf45e2d 100644 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -162,6 +162,7 @@ public class WhiteBox { } public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci); public native void clearMethodState(Executable method); + public native void markMethodProfiled(Executable method); public native int getMethodEntryBci(Executable method); public native Object[] getNMethod(Executable method, boolean isOsr); diff --git a/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java b/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java index 4bdb49d0b3e4984516eb9580f5fed87f2fb96830..7cd36c25ac8b681ad82c8df4069080e76e9fbd03 100644 --- a/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java +++ b/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java @@ -34,18 +34,21 @@ public class NMethod { return obj == null ? null : new NMethod(obj); } private NMethod(Object[] obj) { - assert obj.length == 2; + assert obj.length == 3; comp_level = (Integer) obj[0]; - insts = (byte[]) obj[1]; + compile_id = (Integer) obj[1]; + insts = (byte[]) obj[2]; } - public byte[] insts; - public int comp_level; + public final byte[] insts; + public final int comp_level; + public final int compile_id; @Override public String toString() { return "NMethod{" + "insts=" + insts + ", comp_level=" + comp_level + + ", compile_id=" + compile_id + '}'; } }