8213754: PPC64: Add Intrinsics for isDigit/isLowerCase/isUpperCase/isWhitespace
Reviewed-by: kvn, rriggs, mdoerr, gromero
--- a/make/data/characterdata/CharacterData00.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterData00.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -754,6 +754,21 @@
return retval;
}
+ boolean isDigit(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
+ }
+
+ boolean isLowerCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.LOWERCASE_LETTER;
+ }
+
+ boolean isUpperCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.UPPERCASE_LETTER;
+ }
+
boolean isWhitespace(int ch) {
int props = getProperties(ch);
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
--- a/make/data/characterdata/CharacterData01.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterData01.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -460,6 +460,21 @@
return retval;
}
+ boolean isDigit(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
+ }
+
+ boolean isLowerCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.LOWERCASE_LETTER;
+ }
+
+ boolean isUpperCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.UPPERCASE_LETTER;
+ }
+
boolean isWhitespace(int ch) {
int props = getProperties(ch);
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
--- a/make/data/characterdata/CharacterData02.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterData02.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -217,6 +217,21 @@
return retval;
}
+ boolean isDigit(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
+ }
+
+ boolean isLowerCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.LOWERCASE_LETTER;
+ }
+
+ boolean isUpperCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.UPPERCASE_LETTER;
+ }
+
boolean isWhitespace(int ch) {
return (getProperties(ch) & $$maskIdentifierInfo) == $$valueJavaWhitespace;
}
--- a/make/data/characterdata/CharacterData0E.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterData0E.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -217,6 +217,21 @@
return retval;
}
+ boolean isDigit(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
+ }
+
+ boolean isLowerCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.LOWERCASE_LETTER;
+ }
+
+ boolean isUpperCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.UPPERCASE_LETTER;
+ }
+
boolean isWhitespace(int ch) {
int props = getProperties(ch);
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
--- a/make/data/characterdata/CharacterDataLatin1.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterDataLatin1.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -25,6 +25,8 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/** The CharacterData class encapsulates the large tables found in
Java.lang.Character. */
@@ -78,6 +80,23 @@
return props;
}
+ @HotSpotIntrinsicCandidate
+ boolean isDigit(int ch) {
+ return '0' <= ch && ch <= '9';
+ }
+
+ @HotSpotIntrinsicCandidate
+ boolean isLowerCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.LOWERCASE_LETTER;
+ }
+
+ @HotSpotIntrinsicCandidate
+ boolean isUpperCase(int ch) {
+ int props = getProperties(ch);
+ return (props & $$maskType) == Character.UPPERCASE_LETTER;
+ }
+
boolean isOtherLowercase(int ch) {
int props = getPropertiesEx(ch);
return (props & $$maskOtherLowercase) != 0;
@@ -214,6 +233,7 @@
return retval;
}
+ @HotSpotIntrinsicCandidate
boolean isWhitespace(int ch) {
int props = getProperties(ch);
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
--- a/make/data/characterdata/CharacterDataPrivateUse.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterDataPrivateUse.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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,47 +41,59 @@
}
boolean isJavaIdentifierStart(int ch) {
- return false;
+ return false;
}
boolean isJavaIdentifierPart(int ch) {
- return false;
+ return false;
}
boolean isUnicodeIdentifierStart(int ch) {
- return false;
+ return false;
}
boolean isUnicodeIdentifierPart(int ch) {
- return false;
+ return false;
}
boolean isIdentifierIgnorable(int ch) {
- return false;
+ return false;
}
int toLowerCase(int ch) {
- return ch;
+ return ch;
}
int toUpperCase(int ch) {
- return ch;
+ return ch;
}
int toTitleCase(int ch) {
- return ch;
+ return ch;
}
int digit(int ch, int radix) {
- return -1;
+ return -1;
}
int getNumericValue(int ch) {
- return -1;
+ return -1;
+ }
+
+ boolean isDigit(int ch) {
+ return false;
+ }
+
+ boolean isLowerCase(int ch) {
+ return false;
+ }
+
+ boolean isUpperCase(int ch) {
+ return false;
}
boolean isWhitespace(int ch) {
- return false;
+ return false;
}
byte getDirectionality(int ch) {
@@ -91,7 +103,7 @@
}
boolean isMirrored(int ch) {
- return false;
+ return false;
}
static final CharacterData instance = new CharacterDataPrivateUse();
--- a/make/data/characterdata/CharacterDataUndefined.java.template Wed Dec 12 13:28:50 2018 +0100
+++ b/make/data/characterdata/CharacterDataUndefined.java.template Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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,59 +35,71 @@
}
int getType(int ch) {
- return Character.UNASSIGNED;
+ return Character.UNASSIGNED;
}
boolean isJavaIdentifierStart(int ch) {
- return false;
+ return false;
}
boolean isJavaIdentifierPart(int ch) {
- return false;
+ return false;
}
boolean isUnicodeIdentifierStart(int ch) {
- return false;
+ return false;
}
boolean isUnicodeIdentifierPart(int ch) {
- return false;
+ return false;
}
boolean isIdentifierIgnorable(int ch) {
- return false;
+ return false;
}
int toLowerCase(int ch) {
- return ch;
+ return ch;
}
int toUpperCase(int ch) {
- return ch;
+ return ch;
}
int toTitleCase(int ch) {
- return ch;
+ return ch;
}
int digit(int ch, int radix) {
- return -1;
+ return -1;
}
int getNumericValue(int ch) {
- return -1;
+ return -1;
+ }
+
+ boolean isDigit(int ch) {
+ return false;
+ }
+
+ boolean isLowerCase(int ch) {
+ return false;
+ }
+
+ boolean isUpperCase(int ch) {
+ return false;
}
boolean isWhitespace(int ch) {
- return false;
+ return false;
}
byte getDirectionality(int ch) {
- return Character.DIRECTIONALITY_UNDEFINED;
+ return Character.DIRECTIONALITY_UNDEFINED;
}
boolean isMirrored(int ch) {
- return false;
+ return false;
}
static final CharacterData instance = new CharacterDataUndefined();
--- a/src/hotspot/cpu/ppc/assembler_ppc.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2018 SAP SE. 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
@@ -299,6 +299,8 @@
CMPI_OPCODE = (11u << OPCODE_SHIFT),
CMPL_OPCODE = (31u << OPCODE_SHIFT | 32u << 1),
CMPLI_OPCODE = (10u << OPCODE_SHIFT),
+ CMPRB_OPCODE = (31u << OPCODE_SHIFT | 192u << 1),
+ CMPEQB_OPCODE = (31u << OPCODE_SHIFT | 224u << 1),
ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1),
@@ -336,6 +338,7 @@
MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1),
MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1),
MCRF_OPCODE = (19u << OPCODE_SHIFT | 0u << 1),
+ SETB_OPCODE = (31u << OPCODE_SHIFT | 128u << 1),
// condition register logic instructions
CRAND_OPCODE = (19u << OPCODE_SHIFT | 257u << 1),
@@ -1076,7 +1079,7 @@
static int frs( int x) { return opp_u_field(x, 10, 6); }
static int frt( int x) { return opp_u_field(x, 10, 6); }
static int fxm( int x) { return opp_u_field(x, 19, 12); }
- static int l10( int x) { return opp_u_field(x, 10, 10); }
+ static int l10( int x) { assert(x == 0 || x == 1, "must be 0 or 1"); return opp_u_field(x, 10, 10); }
static int l14( int x) { return opp_u_field(x, 15, 14); }
static int l15( int x) { return opp_u_field(x, 15, 15); }
static int l910( int x) { return opp_u_field(x, 10, 9); }
@@ -1443,6 +1446,10 @@
inline void cmplw( ConditionRegister crx, Register a, Register b);
inline void cmpld( ConditionRegister crx, Register a, Register b);
+ // >= Power9
+ inline void cmprb( ConditionRegister bf, int l, Register a, Register b);
+ inline void cmpeqb(ConditionRegister bf, Register a, Register b);
+
inline void isel( Register d, Register a, Register b, int bc);
// Convenient version which takes: Condition register, Condition code and invert flag. Omit b to keep old value.
inline void isel( Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b = noreg);
@@ -1642,6 +1649,8 @@
inline void mfcr( Register d);
inline void mcrf( ConditionRegister crd, ConditionRegister cra);
inline void mtcr( Register s);
+ // >= Power9
+ inline void setb( Register d, ConditionRegister cra);
// Special purpose registers
// Exception Register
--- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -171,6 +171,8 @@
inline void Assembler::cmp( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMP_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
inline void Assembler::cmpli( ConditionRegister f, int l, Register a, int ui16) { emit_int32( CMPLI_OPCODE | bf(f) | l10(l) | ra(a) | uimm(ui16,16)); }
inline void Assembler::cmpl( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMPL_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
+inline void Assembler::cmprb( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMPRB_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
+inline void Assembler::cmpeqb(ConditionRegister f, Register a, Register b) { emit_int32( CMPEQB_OPCODE| bf(f) | ra(a) | rb(b)); }
// extended mnemonics of Compare Instructions
inline void Assembler::cmpwi( ConditionRegister crx, Register a, int si16) { Assembler::cmpi( crx, 0, a, si16); }
@@ -371,6 +373,8 @@
inline void Assembler::mcrf( ConditionRegister crd, ConditionRegister cra)
{ emit_int32(MCRF_OPCODE | bf(crd) | bfa(cra)); }
inline void Assembler::mtcr( Register s) { Assembler::mtcrf(0xff, s); }
+inline void Assembler::setb(Register d, ConditionRegister cra)
+ { emit_int32(SETB_OPCODE | rt(d) | bfa(cra)); }
// Special purpose registers
// Exception Register
--- a/src/hotspot/cpu/ppc/ppc.ad Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/cpu/ppc/ppc.ad Tue Dec 11 20:31:18 2018 -0500
@@ -2257,6 +2257,11 @@
return SuperwordUseVSX;
case Op_PopCountVI:
return (SuperwordUseVSX && UsePopCountInstruction);
+ case Op_Digit:
+ case Op_LowerCase:
+ case Op_UpperCase:
+ case Op_Whitespace:
+ return UseCharacterCompareIntrinsics;
}
return true; // Per default match rules are supported.
@@ -12400,6 +12405,132 @@
%}
%}
+// Compare char
+instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
+ match(Set dst (Digit src1));
+ effect(TEMP src2, TEMP crx);
+ ins_cost(3 * DEFAULT_COST);
+
+ format %{ "LI $src2, 0x3930\n\t"
+ "CMPRB $crx, 0, $src1, $src2\n\t"
+ "SETB $dst, $crx" %}
+ size(12);
+ ins_encode %{
+ // 0x30: 0, 0x39: 9
+ __ li($src2$$Register, 0x3930);
+ // compare src1 with ranges 0x30 to 0x39
+ __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
+ __ setb($dst$$Register, $crx$$CondRegister);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
+ match(Set dst (LowerCase src1));
+ effect(TEMP src2, TEMP crx);
+ ins_cost(12 * DEFAULT_COST);
+
+ format %{ "LI $src2, 0x7A61\n\t"
+ "CMPRB $crx, 0, $src1, $src2\n\t"
+ "BGT $crx, done\n\t"
+ "LIS $src2, (signed short)0xF6DF\n\t"
+ "ORI $src2, $src2, 0xFFF8\n\t"
+ "CMPRB $crx, 1, $src1, $src2\n\t"
+ "BGT $crx, done\n\t"
+ "LIS $src2, (signed short)0xAAB5\n\t"
+ "ORI $src2, $src2, 0xBABA\n\t"
+ "INSRDI $src2, $src2, 32, 0\n\t"
+ "CMPEQB $crx, 1, $src1, $src2\n"
+ "done:\n\t"
+ "SETB $dst, $crx" %}
+
+ size(48);
+ ins_encode %{
+ Label done;
+ // 0x61: a, 0x7A: z
+ __ li($src2$$Register, 0x7A61);
+ // compare src1 with ranges 0x61 to 0x7A
+ __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
+ __ bgt($crx$$CondRegister, done);
+
+ // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
+ __ lis($src2$$Register, (signed short)0xF6DF);
+ __ ori($src2$$Register, $src2$$Register, 0xFFF8);
+ // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
+ __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
+ __ bgt($crx$$CondRegister, done);
+
+ // 0xAA: feminine ordinal indicator
+ // 0xB5: micro sign
+ // 0xBA: masculine ordinal indicator
+ __ lis($src2$$Register, (signed short)0xAAB5);
+ __ ori($src2$$Register, $src2$$Register, 0xBABA);
+ __ insrdi($src2$$Register, $src2$$Register, 32, 0);
+ // compare src1 with 0xAA, 0xB5, and 0xBA
+ __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
+
+ __ bind(done);
+ __ setb($dst$$Register, $crx$$CondRegister);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
+ match(Set dst (UpperCase src1));
+ effect(TEMP src2, TEMP crx);
+ ins_cost(7 * DEFAULT_COST);
+
+ format %{ "LI $src2, 0x5A41\n\t"
+ "CMPRB $crx, 0, $src1, $src2\n\t"
+ "BGT $crx, done\n\t"
+ "LIS $src2, (signed short)0xD6C0\n\t"
+ "ORI $src2, $src2, 0xDED8\n\t"
+ "CMPRB $crx, 1, $src1, $src2\n"
+ "done:\n\t"
+ "SETB $dst, $crx" %}
+
+ size(28);
+ ins_encode %{
+ Label done;
+ // 0x41: A, 0x5A: Z
+ __ li($src2$$Register, 0x5A41);
+ // compare src1 with a range 0x41 to 0x5A
+ __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
+ __ bgt($crx$$CondRegister, done);
+
+ // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
+ __ lis($src2$$Register, (signed short)0xD6C0);
+ __ ori($src2$$Register, $src2$$Register, 0xDED8);
+ // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
+ __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
+
+ __ bind(done);
+ __ setb($dst$$Register, $crx$$CondRegister);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
+ match(Set dst (Whitespace src1));
+ effect(TEMP src2, TEMP crx);
+ ins_cost(4 * DEFAULT_COST);
+
+ format %{ "LI $src2, 0x0D09\n\t"
+ "ADDIS $src2, 0x201C\n\t"
+ "CMPRB $crx, 1, $src1, $src2\n\t"
+ "SETB $dst, $crx" %}
+ size(16);
+ ins_encode %{
+ // 0x09 to 0x0D, 0x1C to 0x20
+ __ li($src2$$Register, 0x0D09);
+ __ addis($src2$$Register, $src2$$Register, 0x0201C);
+ // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
+ __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
+ __ setb($dst$$Register, $crx$$CondRegister);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
//----------Branches---------------------------------------------------------
// Jump
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Tue Dec 11 20:31:18 2018 -0500
@@ -134,11 +134,18 @@
if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
FLAG_SET_ERGO(bool, UseCountTrailingZerosInstructionsPPC64, true);
}
+ if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
+ FLAG_SET_ERGO(bool, UseCharacterCompareIntrinsics, true);
+ }
} else {
if (UseCountTrailingZerosInstructionsPPC64) {
warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9.");
FLAG_SET_DEFAULT(UseCountTrailingZerosInstructionsPPC64, false);
}
+ if (UseCharacterCompareIntrinsics) {
+ warning("UseCharacterCompareIntrinsics specified, but needs at least Power9.");
+ FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false);
+ }
}
#endif
--- a/src/hotspot/share/classfile/vmSymbols.cpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.cpp Tue Dec 11 20:31:18 2018 -0500
@@ -379,6 +379,10 @@
case vmIntrinsics::_vectorizedMismatch:
case vmIntrinsics::_fmaD:
case vmIntrinsics::_fmaF:
+ case vmIntrinsics::_isDigit:
+ case vmIntrinsics::_isLowerCase:
+ case vmIntrinsics::_isUpperCase:
+ case vmIntrinsics::_isWhitespace:
return true;
default:
return false;
@@ -828,6 +832,12 @@
case vmIntrinsics::_subtractExactL:
if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
break;
+ case vmIntrinsics::_isDigit:
+ case vmIntrinsics::_isLowerCase:
+ case vmIntrinsics::_isUpperCase:
+ case vmIntrinsics::_isWhitespace:
+ if (!UseCharacterCompareIntrinsics) return true;
+ break;
#endif // COMPILER2
default:
return false;
--- a/src/hotspot/share/classfile/vmSymbols.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -71,6 +71,7 @@
template(java_lang_Boolean, "java/lang/Boolean") \
template(java_lang_Character, "java/lang/Character") \
template(java_lang_Character_CharacterCache, "java/lang/Character$CharacterCache") \
+ template(java_lang_CharacterDataLatin1, "java/lang/CharacterDataLatin1") \
template(java_lang_Float, "java/lang/Float") \
template(java_lang_Double, "java/lang/Double") \
template(java_lang_Byte, "java/lang/Byte") \
@@ -933,6 +934,15 @@
do_intrinsic(_equalsL, java_lang_StringLatin1,equals_name, equalsB_signature, F_S) \
do_intrinsic(_equalsU, java_lang_StringUTF16, equals_name, equalsB_signature, F_S) \
\
+ do_intrinsic(_isDigit, java_lang_CharacterDataLatin1, isDigit_name, int_bool_signature, F_R) \
+ do_name( isDigit_name, "isDigit") \
+ do_intrinsic(_isLowerCase, java_lang_CharacterDataLatin1, isLowerCase_name, int_bool_signature, F_R) \
+ do_name( isLowerCase_name, "isLowerCase") \
+ do_intrinsic(_isUpperCase, java_lang_CharacterDataLatin1, isUpperCase_name, int_bool_signature, F_R) \
+ do_name( isUpperCase_name, "isUpperCase") \
+ do_intrinsic(_isWhitespace, java_lang_CharacterDataLatin1, isWhitespace_name, int_bool_signature, F_R) \
+ do_name( isWhitespace_name, "isWhitespace") \
+ \
do_intrinsic(_Preconditions_checkIndex, jdk_internal_util_Preconditions, checkIndex_name, Preconditions_checkIndex_signature, F_S) \
do_signature(Preconditions_checkIndex_signature, "(IILjava/util/function/BiFunction;)I") \
\
--- a/src/hotspot/share/opto/c2_globals.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/opto/c2_globals.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -710,6 +710,9 @@
diagnostic(bool, UseMathExactIntrinsics, true, \
"Enables intrinsification of various java.lang.Math functions") \
\
+ diagnostic(bool, UseCharacterCompareIntrinsics, false, \
+ "Enables intrinsification of java.lang.Character functions") \
+ \
diagnostic(bool, UseMultiplyToLenIntrinsic, false, \
"Enables intrinsification of BigInteger.multiplyToLen()") \
\
--- a/src/hotspot/share/opto/c2compiler.cpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/opto/c2compiler.cpp Tue Dec 11 20:31:18 2018 -0500
@@ -428,6 +428,18 @@
case vmIntrinsics::_fmaF:
if (!UseFMA || !Matcher::match_rule_supported(Op_FmaF)) return false;
break;
+ case vmIntrinsics::_isDigit:
+ if (!Matcher::match_rule_supported(Op_Digit)) return false;
+ break;
+ case vmIntrinsics::_isLowerCase:
+ if (!Matcher::match_rule_supported(Op_LowerCase)) return false;
+ break;
+ case vmIntrinsics::_isUpperCase:
+ if (!Matcher::match_rule_supported(Op_UpperCase)) return false;
+ break;
+ case vmIntrinsics::_isWhitespace:
+ if (!Matcher::match_rule_supported(Op_Whitespace)) return false;
+ break;
case vmIntrinsics::_hashCode:
case vmIntrinsics::_identityHashCode:
case vmIntrinsics::_getClass:
--- a/src/hotspot/share/opto/classes.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/opto/classes.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -394,3 +394,7 @@
macro(ExtractL)
macro(ExtractF)
macro(ExtractD)
+macro(Digit)
+macro(LowerCase)
+macro(UpperCase)
+macro(Whitespace)
--- a/src/hotspot/share/opto/intrinsicnode.hpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/opto/intrinsicnode.hpp Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -180,4 +180,40 @@
virtual const Type* Value(PhaseGVN* phase) const;
};
+//-------------------------------DigitNode----------------------------------------
+class DigitNode : public Node {
+public:
+ DigitNode(Node* control, Node *in1) : Node(control, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::BOOL; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
+
+//------------------------------LowerCaseNode------------------------------------
+class LowerCaseNode : public Node {
+public:
+ LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::BOOL; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
+
+//------------------------------UpperCaseNode------------------------------------
+class UpperCaseNode : public Node {
+public:
+ UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::BOOL; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
+
+//------------------------------WhitespaceCode-----------------------------------
+class WhitespaceNode : public Node {
+public:
+ WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::BOOL; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
+
#endif // SHARE_VM_OPTO_INTRINSICNODE_HPP
--- a/src/hotspot/share/opto/library_call.cpp Wed Dec 12 13:28:50 2018 +0100
+++ b/src/hotspot/share/opto/library_call.cpp Tue Dec 11 20:31:18 2018 -0500
@@ -324,6 +324,7 @@
bool inline_montgomerySquare();
bool inline_vectorizedMismatch();
bool inline_fma(vmIntrinsics::ID id);
+ bool inline_character_compare(vmIntrinsics::ID id);
bool inline_profileBoolean();
bool inline_isCompileConstant();
@@ -867,6 +868,12 @@
case vmIntrinsics::_fmaF:
return inline_fma(intrinsic_id());
+ case vmIntrinsics::_isDigit:
+ case vmIntrinsics::_isLowerCase:
+ case vmIntrinsics::_isUpperCase:
+ case vmIntrinsics::_isWhitespace:
+ return inline_character_compare(intrinsic_id());
+
default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmSymbols.hpp without implementing it here.
@@ -6555,6 +6562,32 @@
return true;
}
+bool LibraryCallKit::inline_character_compare(vmIntrinsics::ID id) {
+ // argument(0) is receiver
+ Node* codePoint = argument(1);
+ Node* n = NULL;
+
+ switch (id) {
+ case vmIntrinsics::_isDigit :
+ n = new DigitNode(control(), codePoint);
+ break;
+ case vmIntrinsics::_isLowerCase :
+ n = new LowerCaseNode(control(), codePoint);
+ break;
+ case vmIntrinsics::_isUpperCase :
+ n = new UpperCaseNode(control(), codePoint);
+ break;
+ case vmIntrinsics::_isWhitespace :
+ n = new WhitespaceNode(control(), codePoint);
+ break;
+ default:
+ fatal_unexpected_iid(id);
+ }
+
+ set_result(_gvn.transform(n));
+ return true;
+}
+
bool LibraryCallKit::inline_profileBoolean() {
Node* counts = argument(1);
const TypeAryPtr* ary = NULL;
--- a/src/java.base/share/classes/java/lang/Character.java Wed Dec 12 13:28:50 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Character.java Tue Dec 11 20:31:18 2018 -0500
@@ -9085,7 +9085,7 @@
* @since 1.5
*/
public static boolean isLowerCase(int codePoint) {
- return getType(codePoint) == Character.LOWERCASE_LETTER ||
+ return CharacterData.of(codePoint).isLowerCase(codePoint) ||
CharacterData.of(codePoint).isOtherLowercase(codePoint);
}
@@ -9151,7 +9151,7 @@
* @since 1.5
*/
public static boolean isUpperCase(int codePoint) {
- return getType(codePoint) == Character.UPPERCASE_LETTER ||
+ return CharacterData.of(codePoint).isUpperCase(codePoint) ||
CharacterData.of(codePoint).isOtherUppercase(codePoint);
}
@@ -9302,7 +9302,7 @@
* @since 1.5
*/
public static boolean isDigit(int codePoint) {
- return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
+ return CharacterData.of(codePoint).isDigit(codePoint);
}
/**
--- a/src/java.base/share/classes/java/lang/CharacterData.java Wed Dec 12 13:28:50 2018 +0100
+++ b/src/java.base/share/classes/java/lang/CharacterData.java Tue Dec 11 20:31:18 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, 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
@@ -28,6 +28,9 @@
abstract class CharacterData {
abstract int getProperties(int ch);
abstract int getType(int ch);
+ abstract boolean isDigit(int ch);
+ abstract boolean isLowerCase(int ch);
+ abstract boolean isUpperCase(int ch);
abstract boolean isWhitespace(int ch);
abstract boolean isMirrored(int ch);
abstract boolean isJavaIdentifierStart(int ch);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Characters.java Tue Dec 11 20:31:18 2018 -0500
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, 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 org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Characters {
+
+ @Param({"9", "48", "65", "97", "128", "170", "192", "223"})
+ private int codePoint;
+
+ @Benchmark
+ public boolean isDigit() {
+ return Character.isDigit(codePoint);
+ }
+
+ @Benchmark
+ public boolean isLowerCase() {
+ return Character.isLowerCase(codePoint);
+ }
+
+ @Benchmark
+ public boolean isUpperCase() {
+ return Character.isUpperCase(codePoint);
+ }
+
+ @Benchmark
+ public boolean isWhitespace() {
+ return Character.isWhitespace(codePoint);
+ }
+}