mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
8145336: PPC64: fix string intrinsics after CompactStrings change
Reviewed-by: mdoerr, aph, kvn
This commit is contained in:
parent
fdb6716fd4
commit
f3dca540d8
9 changed files with 815 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
// Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
// Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
|
|
|
@ -121,7 +121,6 @@ void VM_Version::get_processor_features() {
|
||||||
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 256);
|
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 256);
|
||||||
FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256);
|
FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256);
|
||||||
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256);
|
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256);
|
||||||
FLAG_SET_DEFAULT(UseSSE42Intrinsics, true);
|
|
||||||
|
|
||||||
unsigned long auxv = getauxval(AT_HWCAP);
|
unsigned long auxv = getauxval(AT_HWCAP);
|
||||||
|
|
||||||
|
|
|
@ -3172,11 +3172,12 @@ void MacroAssembler::clear_memory_doubleword(Register base_ptr, Register cnt_dwo
|
||||||
//
|
//
|
||||||
// Assumes that result differs from all other registers.
|
// Assumes that result differs from all other registers.
|
||||||
//
|
//
|
||||||
// Haystack, needle are the addresses of jchar-arrays.
|
// 'haystack' is the addresses of a jchar-array.
|
||||||
// NeedleChar is needle[0] if it is known at compile time.
|
// 'needle' is either the character to search for or R0.
|
||||||
// Haycnt is the length of the haystack. We assume haycnt >=1.
|
// 'needleChar' is the character to search for if 'needle' == R0..
|
||||||
|
// 'haycnt' is the length of the haystack. We assume 'haycnt' >=1.
|
||||||
//
|
//
|
||||||
// Preserves haystack, haycnt, kills all other registers.
|
// Preserves haystack, haycnt, needle and kills all other registers.
|
||||||
//
|
//
|
||||||
// If needle == R0, we search for the constant needleChar.
|
// If needle == R0, we search for the constant needleChar.
|
||||||
void MacroAssembler::string_indexof_1(Register result, Register haystack, Register haycnt,
|
void MacroAssembler::string_indexof_1(Register result, Register haystack, Register haycnt,
|
||||||
|
@ -3186,13 +3187,11 @@ void MacroAssembler::string_indexof_1(Register result, Register haystack, Regist
|
||||||
assert_different_registers(result, haystack, haycnt, needle, tmp1, tmp2);
|
assert_different_registers(result, haystack, haycnt, needle, tmp1, tmp2);
|
||||||
|
|
||||||
Label L_InnerLoop, L_FinalCheck, L_Found1, L_Found2, L_Found3, L_NotFound, L_End;
|
Label L_InnerLoop, L_FinalCheck, L_Found1, L_Found2, L_Found3, L_NotFound, L_End;
|
||||||
Register needle0 = needle, // Contains needle[0].
|
Register addr = tmp1,
|
||||||
addr = tmp1,
|
|
||||||
ch1 = tmp2,
|
ch1 = tmp2,
|
||||||
ch2 = R0;
|
ch2 = R0;
|
||||||
|
|
||||||
//2 (variable) or 3 (const):
|
//3:
|
||||||
if (needle != R0) lhz(needle0, 0, needle); // Preload needle character, needle has len==1.
|
|
||||||
dcbtct(haystack, 0x00); // Indicate R/O access to haystack.
|
dcbtct(haystack, 0x00); // Indicate R/O access to haystack.
|
||||||
|
|
||||||
srwi_(tmp2, haycnt, 1); // Shift right by exact_log2(UNROLL_FACTOR).
|
srwi_(tmp2, haycnt, 1); // Shift right by exact_log2(UNROLL_FACTOR).
|
||||||
|
@ -3203,8 +3202,8 @@ void MacroAssembler::string_indexof_1(Register result, Register haystack, Regist
|
||||||
bind(L_InnerLoop); // Main work horse (2x unrolled search loop).
|
bind(L_InnerLoop); // Main work horse (2x unrolled search loop).
|
||||||
lhz(ch1, 0, addr); // Load characters from haystack.
|
lhz(ch1, 0, addr); // Load characters from haystack.
|
||||||
lhz(ch2, 2, addr);
|
lhz(ch2, 2, addr);
|
||||||
(needle != R0) ? cmpw(CCR0, ch1, needle0) : cmplwi(CCR0, ch1, needleChar);
|
(needle != R0) ? cmpw(CCR0, ch1, needle) : cmplwi(CCR0, ch1, needleChar);
|
||||||
(needle != R0) ? cmpw(CCR1, ch2, needle0) : cmplwi(CCR1, ch2, needleChar);
|
(needle != R0) ? cmpw(CCR1, ch2, needle) : cmplwi(CCR1, ch2, needleChar);
|
||||||
beq(CCR0, L_Found1); // Did we find the needle?
|
beq(CCR0, L_Found1); // Did we find the needle?
|
||||||
beq(CCR1, L_Found2);
|
beq(CCR1, L_Found2);
|
||||||
addi(addr, addr, 4);
|
addi(addr, addr, 4);
|
||||||
|
@ -3214,7 +3213,7 @@ void MacroAssembler::string_indexof_1(Register result, Register haystack, Regist
|
||||||
andi_(R0, haycnt, 1);
|
andi_(R0, haycnt, 1);
|
||||||
beq(CCR0, L_NotFound);
|
beq(CCR0, L_NotFound);
|
||||||
lhz(ch1, 0, addr); // One position left at which we have to compare.
|
lhz(ch1, 0, addr); // One position left at which we have to compare.
|
||||||
(needle != R0) ? cmpw(CCR1, ch1, needle0) : cmplwi(CCR1, ch1, needleChar);
|
(needle != R0) ? cmpw(CCR1, ch1, needle) : cmplwi(CCR1, ch1, needleChar);
|
||||||
beq(CCR1, L_Found3);
|
beq(CCR1, L_Found3);
|
||||||
//21:
|
//21:
|
||||||
bind(L_NotFound);
|
bind(L_NotFound);
|
||||||
|
@ -3399,7 +3398,15 @@ void MacroAssembler::string_compare(Register str1_reg, Register str2_reg, Regist
|
||||||
chr2_reg = cnt2_reg,
|
chr2_reg = cnt2_reg,
|
||||||
addr_diff = str2_reg;
|
addr_diff = str2_reg;
|
||||||
|
|
||||||
|
// 'cnt_reg' contains the number of characters in the string's character array for the
|
||||||
|
// pre-CompactStrings strings implementation and the number of bytes in the string's
|
||||||
|
// byte array for the CompactStrings strings implementation.
|
||||||
|
const int HAS_COMPACT_STRING = java_lang_String::has_coder_field() ? 1 : 0; // '1' = byte array, '0' = char array
|
||||||
|
|
||||||
// Offset 0 should be 32 byte aligned.
|
// Offset 0 should be 32 byte aligned.
|
||||||
|
//-6:
|
||||||
|
srawi(cnt1_reg, cnt1_reg, HAS_COMPACT_STRING);
|
||||||
|
srawi(cnt2_reg, cnt2_reg, HAS_COMPACT_STRING);
|
||||||
//-4:
|
//-4:
|
||||||
dcbtct(str1_reg, 0x00); // Indicate R/O access to str1.
|
dcbtct(str1_reg, 0x00); // Indicate R/O access to str1.
|
||||||
dcbtct(str2_reg, 0x00); // Indicate R/O access to str2.
|
dcbtct(str2_reg, 0x00); // Indicate R/O access to str2.
|
||||||
|
@ -3478,14 +3485,21 @@ void MacroAssembler::char_arrays_equals(Register str1_reg, Register str2_reg, Re
|
||||||
Register index_reg = tmp5_reg;
|
Register index_reg = tmp5_reg;
|
||||||
Register cbc_iter = tmp4_reg;
|
Register cbc_iter = tmp4_reg;
|
||||||
|
|
||||||
|
// 'cnt_reg' contains the number of characters in the string's character array for the
|
||||||
|
// pre-CompactStrings strings implementation and the number of bytes in the string's
|
||||||
|
// byte array for the CompactStrings strings implementation.
|
||||||
|
const int HAS_COMPACT_STRING = java_lang_String::has_coder_field() ? 1 : 0; // '1' = byte array, '0' = char array
|
||||||
|
|
||||||
//-1:
|
//-1:
|
||||||
dcbtct(str1_reg, 0x00); // Indicate R/O access to str1.
|
dcbtct(str1_reg, 0x00); // Indicate R/O access to str1.
|
||||||
dcbtct(str2_reg, 0x00); // Indicate R/O access to str2.
|
dcbtct(str2_reg, 0x00); // Indicate R/O access to str2.
|
||||||
//1:
|
//1:
|
||||||
andi(cbc_iter, cnt_reg, 4-1); // Remaining iterations after 4 java characters per iteration loop.
|
// cbc_iter: remaining characters after the '4 java characters per iteration' loop.
|
||||||
|
rlwinm(cbc_iter, cnt_reg, 32 - HAS_COMPACT_STRING, 30, 31); // (cnt_reg % (HAS_COMPACT_STRING ? 8 : 4)) >> HAS_COMPACT_STRING
|
||||||
li(index_reg, 0); // init
|
li(index_reg, 0); // init
|
||||||
li(result_reg, 0); // assume false
|
li(result_reg, 0); // assume false
|
||||||
srwi_(tmp2_reg, cnt_reg, exact_log2(4)); // Div: 4 java characters per iteration (main loop).
|
// tmp2_reg: units of 4 java characters (i.e. 8 bytes) per iteration (main loop).
|
||||||
|
srwi_(tmp2_reg, cnt_reg, exact_log2(4 << HAS_COMPACT_STRING)); // cnt_reg / (HAS_COMPACT_STRING ? 8 : 4)
|
||||||
|
|
||||||
cmpwi(CCR1, cbc_iter, 0); // CCR1 = (cbc_iter==0)
|
cmpwi(CCR1, cbc_iter, 0); // CCR1 = (cbc_iter==0)
|
||||||
beq(CCR0, Linit_cbc); // too short
|
beq(CCR0, Linit_cbc); // too short
|
||||||
|
@ -3526,6 +3540,11 @@ void MacroAssembler::char_arrays_equalsImm(Register str1_reg, Register str2_reg,
|
||||||
assert(sizeof(jchar) == 2, "must be");
|
assert(sizeof(jchar) == 2, "must be");
|
||||||
assert(cntval >= 0 && ((cntval & 0x7fff) == cntval), "wrong immediate");
|
assert(cntval >= 0 && ((cntval & 0x7fff) == cntval), "wrong immediate");
|
||||||
|
|
||||||
|
// 'cntval' contains the number of characters in the string's character array for the
|
||||||
|
// pre-CompactStrings strings implementation and the number of bytes in the string's
|
||||||
|
// byte array for the CompactStrings strings implementation.
|
||||||
|
cntval >>= (java_lang_String::has_coder_field() ? 1 : 0); // '1' = byte array strings, '0' = char array strings
|
||||||
|
|
||||||
Label Ldone_false;
|
Label Ldone_false;
|
||||||
|
|
||||||
if (cntval < 16) { // short case
|
if (cntval < 16) { // short case
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
// Copyright 2012, 2015 SAP AG. All rights reserved.
|
// Copyright 2012, 2015 SAP AG. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
|
@ -956,36 +956,40 @@ static int cc_to_biint(int cc, int flags_reg) {
|
||||||
// the instruction. The padding must match the size of a NOP instruction.
|
// the instruction. The padding must match the size of a NOP instruction.
|
||||||
|
|
||||||
int string_indexOf_imm1_charNode::compute_padding(int current_offset) const {
|
int string_indexOf_imm1_charNode::compute_padding(int current_offset) const {
|
||||||
return (3*4-current_offset)&31;
|
return (3*4-current_offset)&31; // see MacroAssembler::string_indexof_1
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_indexOf_imm1Node::compute_padding(int current_offset) const {
|
int string_indexOf_imm1Node::compute_padding(int current_offset) const {
|
||||||
return (2*4-current_offset)&31;
|
return (3*4-current_offset)&31; // see MacroAssembler::string_indexof_1
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_indexOfCharNode::compute_padding(int current_offset) const {
|
||||||
|
return (3*4-current_offset)&31; // see MacroAssembler::string_indexof_1
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_indexOf_immNode::compute_padding(int current_offset) const {
|
int string_indexOf_immNode::compute_padding(int current_offset) const {
|
||||||
return (3*4-current_offset)&31;
|
return (3*4-current_offset)&31; // see MacroAssembler::string_indexof(constant needlecount)
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_indexOfNode::compute_padding(int current_offset) const {
|
int string_indexOfNode::compute_padding(int current_offset) const {
|
||||||
return (1*4-current_offset)&31;
|
return (1*4-current_offset)&31; // see MacroAssembler::string_indexof(variable needlecount)
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_compareNode::compute_padding(int current_offset) const {
|
int string_compareNode::compute_padding(int current_offset) const {
|
||||||
return (4*4-current_offset)&31;
|
return (2*4-current_offset)&31; // see MacroAssembler::string_compare
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_equals_immNode::compute_padding(int current_offset) const {
|
int string_equals_immNode::compute_padding(int current_offset) const {
|
||||||
if (opnd_array(3)->constant() < 16) return 0; // Don't insert nops for short version (loop completely unrolled).
|
if (opnd_array(3)->constant() < 16) return 0; // For strlen < 16 no nops because loop completely unrolled
|
||||||
return (2*4-current_offset)&31;
|
return (2*4-current_offset)&31; // Genral case - see MacroAssembler::char_arrays_equalsImm
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_equalsNode::compute_padding(int current_offset) const {
|
int string_equalsNode::compute_padding(int current_offset) const {
|
||||||
return (7*4-current_offset)&31;
|
return (7*4-current_offset)&31; // see MacroAssembler::char_arrays_equals
|
||||||
}
|
}
|
||||||
|
|
||||||
int inlineCallClearArrayNode::compute_padding(int current_offset) const {
|
int inlineCallClearArrayNode::compute_padding(int current_offset) const {
|
||||||
return (2*4-current_offset)&31;
|
return (2*4-current_offset)&31; // see MacroAssembler::clear_memory_doubleword
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -2025,6 +2029,8 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||||
return SpecialStringEquals && !CompactStrings;
|
return SpecialStringEquals && !CompactStrings;
|
||||||
case Op_StrIndexOf:
|
case Op_StrIndexOf:
|
||||||
return SpecialStringIndexOf && !CompactStrings;
|
return SpecialStringIndexOf && !CompactStrings;
|
||||||
|
case Op_StrIndexOfChar:
|
||||||
|
return SpecialStringIndexOf && !CompactStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true; // Per default match rules are supported.
|
return true; // Per default match rules are supported.
|
||||||
|
@ -11034,11 +11040,11 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, reg
|
||||||
instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
|
instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
|
||||||
immP needleImm, immL offsetImm, immI_1 needlecntImm,
|
immP needleImm, immL offsetImm, immI_1 needlecntImm,
|
||||||
iRegIdst tmp1, iRegIdst tmp2,
|
iRegIdst tmp1, iRegIdst tmp2,
|
||||||
flagsRegCR0 cr0, flagsRegCR1 cr1) %{
|
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
|
||||||
predicate(SpecialStringIndexOf && !CompactStrings); // type check implicit by parameter type, See Matcher::match_rule_supported
|
predicate(SpecialStringIndexOf && !CompactStrings); // type check implicit by parameter type, See Matcher::match_rule_supported
|
||||||
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
|
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
|
||||||
|
|
||||||
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
|
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
|
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
|
||||||
|
@ -11050,10 +11056,23 @@ instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc h
|
||||||
immPOper *needleOper = (immPOper *)$needleImm;
|
immPOper *needleOper = (immPOper *)$needleImm;
|
||||||
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
|
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
|
||||||
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
|
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
|
||||||
|
jchar chr;
|
||||||
|
if (java_lang_String::has_coder_field()) {
|
||||||
|
// New compact strings byte array strings
|
||||||
|
#ifdef VM_LITTLE_ENDIAN
|
||||||
|
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
|
||||||
|
(jchar)needle_values->element_value(0).as_byte();
|
||||||
|
#else
|
||||||
|
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
|
||||||
|
(jchar)needle_values->element_value(1).as_byte();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// Old char array strings
|
||||||
|
chr = needle_values->char_at(0);
|
||||||
|
}
|
||||||
__ string_indexof_1($result$$Register,
|
__ string_indexof_1($result$$Register,
|
||||||
$haystack$$Register, $haycnt$$Register,
|
$haystack$$Register, $haycnt$$Register,
|
||||||
R0, needle_values->char_at(0),
|
R0, chr,
|
||||||
$tmp1$$Register, $tmp2$$Register);
|
$tmp1$$Register, $tmp2$$Register);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_compare);
|
ins_pipe(pipe_class_compare);
|
||||||
|
@ -11073,12 +11092,13 @@ instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc h
|
||||||
instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
|
instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
|
||||||
rscratch2RegP needle, immI_1 needlecntImm,
|
rscratch2RegP needle, immI_1 needlecntImm,
|
||||||
iRegIdst tmp1, iRegIdst tmp2,
|
iRegIdst tmp1, iRegIdst tmp2,
|
||||||
flagsRegCR0 cr0, flagsRegCR1 cr1) %{
|
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
|
||||||
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
|
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
|
||||||
effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
|
effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
|
||||||
TEMP tmp1, TEMP tmp2);
|
TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
|
||||||
// Required for EA: check if it is still a type_array.
|
// Required for EA: check if it is still a type_array.
|
||||||
predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
|
predicate(SpecialStringIndexOf && !CompactStrings &&
|
||||||
|
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
|
||||||
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
|
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
|
||||||
ins_cost(180);
|
ins_cost(180);
|
||||||
|
|
||||||
|
@ -11091,17 +11111,54 @@ instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
|
||||||
Node *ndl = in(operand_index($needle)); // The node that defines needle.
|
Node *ndl = in(operand_index($needle)); // The node that defines needle.
|
||||||
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
|
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
|
||||||
guarantee(needle_values, "sanity");
|
guarantee(needle_values, "sanity");
|
||||||
if (needle_values != NULL) {
|
jchar chr;
|
||||||
__ string_indexof_1($result$$Register,
|
if (java_lang_String::has_coder_field()) {
|
||||||
$haystack$$Register, $haycnt$$Register,
|
// New compact strings byte array strings
|
||||||
R0, needle_values->char_at(0),
|
#ifdef VM_LITTLE_ENDIAN
|
||||||
$tmp1$$Register, $tmp2$$Register);
|
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
|
||||||
|
(jchar)needle_values->element_value(0).as_byte();
|
||||||
|
#else
|
||||||
|
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
|
||||||
|
(jchar)needle_values->element_value(1).as_byte();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
// Old char array strings
|
||||||
|
chr = needle_values->char_at(0);
|
||||||
|
}
|
||||||
__ string_indexof_1($result$$Register,
|
__ string_indexof_1($result$$Register,
|
||||||
$haystack$$Register, $haycnt$$Register,
|
$haystack$$Register, $haycnt$$Register,
|
||||||
$needle$$Register, 0,
|
R0, chr,
|
||||||
|
$tmp1$$Register, $tmp2$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// String_IndexOfChar
|
||||||
|
//
|
||||||
|
// Assumes register result differs from all input registers.
|
||||||
|
//
|
||||||
|
// Preserves registers haystack, haycnt
|
||||||
|
// Kills registers tmp1, tmp2
|
||||||
|
// Defines registers result
|
||||||
|
//
|
||||||
|
// Use dst register classes if register gets killed, as it is the case for tmp registers!
|
||||||
|
instruct string_indexOfChar(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
|
||||||
|
iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
|
||||||
|
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
|
||||||
|
match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
|
||||||
|
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
|
||||||
|
predicate(SpecialStringIndexOf && !CompactStrings);
|
||||||
|
ins_cost(180);
|
||||||
|
|
||||||
|
ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
|
||||||
|
|
||||||
|
format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
|
||||||
|
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ string_indexof_1($result$$Register,
|
||||||
|
$haystack$$Register, $haycnt$$Register,
|
||||||
|
$ch$$Register, 0 /* this is not used if the character is already in a register */,
|
||||||
$tmp1$$Register, $tmp2$$Register);
|
$tmp1$$Register, $tmp2$$Register);
|
||||||
}
|
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_compare);
|
ins_pipe(pipe_class_compare);
|
||||||
%}
|
%}
|
||||||
|
@ -11120,10 +11177,10 @@ instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
|
||||||
instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
|
instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
|
||||||
iRegPsrc needle, uimmI15 needlecntImm,
|
iRegPsrc needle, uimmI15 needlecntImm,
|
||||||
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
|
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
|
||||||
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
|
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
|
||||||
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
|
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
|
||||||
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
|
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
|
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
|
||||||
// Required for EA: check if it is still a type_array.
|
// Required for EA: check if it is still a type_array.
|
||||||
predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
|
predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
|
||||||
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
|
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
|
||||||
|
@ -11153,11 +11210,11 @@ instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI ha
|
||||||
// Use dst register classes if register gets killed, as it is the case for tmp registers!
|
// Use dst register classes if register gets killed, as it is the case for tmp registers!
|
||||||
instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
|
instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
|
||||||
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
|
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
|
||||||
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
|
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
|
||||||
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
|
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
|
||||||
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
|
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
|
||||||
TEMP_DEF result,
|
TEMP_DEF result,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
|
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
|
||||||
predicate(SpecialStringIndexOf && !CompactStrings); // See Matcher::match_rule_supported.
|
predicate(SpecialStringIndexOf && !CompactStrings); // See Matcher::match_rule_supported.
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -184,6 +184,9 @@ define_pd_global(bool, PreserveFramePointer, false);
|
||||||
product(bool, UseCountTrailingZerosInstruction, false, \
|
product(bool, UseCountTrailingZerosInstruction, false, \
|
||||||
"Use count trailing zeros instruction") \
|
"Use count trailing zeros instruction") \
|
||||||
\
|
\
|
||||||
|
product(bool, UseSSE42Intrinsics, false, \
|
||||||
|
"SSE4.2 versions of intrinsics") \
|
||||||
|
\
|
||||||
product(bool, UseBMI1Instructions, false, \
|
product(bool, UseBMI1Instructions, false, \
|
||||||
"Use BMI1 instructions") \
|
"Use BMI1 instructions") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1711,6 +1711,14 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||||
if (UseAVX < 1 || UseAVX > 2)
|
if (UseAVX < 1 || UseAVX > 2)
|
||||||
ret_value = false;
|
ret_value = false;
|
||||||
break;
|
break;
|
||||||
|
case Op_StrIndexOf:
|
||||||
|
if (!UseSSE42Intrinsics)
|
||||||
|
ret_value = false;
|
||||||
|
break;
|
||||||
|
case Op_StrIndexOfChar:
|
||||||
|
if (!(UseSSE > 4))
|
||||||
|
ret_value = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_value; // Per default match rules are supported.
|
return ret_value; // Per default match rules are supported.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -971,8 +971,10 @@ Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node
|
||||||
str1_start, cnt1, str2_start, cnt2, ae);
|
str1_start, cnt1, str2_start, cnt2, ae);
|
||||||
break;
|
break;
|
||||||
case Op_StrEquals:
|
case Op_StrEquals:
|
||||||
|
// We already know that cnt1 == cnt2 here (checked in 'inline_string_equals').
|
||||||
|
// Use the constant length if there is one because optimized match rule may exist.
|
||||||
result = new StrEqualsNode(control(), memory(TypeAryPtr::BYTES),
|
result = new StrEqualsNode(control(), memory(TypeAryPtr::BYTES),
|
||||||
str1_start, str2_start, cnt1, ae);
|
str1_start, str2_start, cnt2->is_Con() ? cnt2 : cnt1, ae);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
@ -1131,7 +1133,7 @@ bool LibraryCallKit::inline_objects_checkIndex() {
|
||||||
|
|
||||||
//------------------------------inline_string_indexOf------------------------
|
//------------------------------inline_string_indexOf------------------------
|
||||||
bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
|
bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
|
||||||
if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
|
if (!Matcher::match_rule_supported(Op_StrIndexOf)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Node* src = argument(0);
|
Node* src = argument(0);
|
||||||
|
@ -1175,7 +1177,7 @@ bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
|
||||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
|
if (!Matcher::match_rule_supported(Op_StrIndexOf)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
|
assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
|
||||||
|
@ -1260,7 +1262,7 @@ bool LibraryCallKit::inline_string_indexOfChar() {
|
||||||
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Matcher::has_match_rule(Op_StrIndexOfChar) || !(UseSSE > 4)) {
|
if (!Matcher::match_rule_supported(Op_StrIndexOfChar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments");
|
assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -829,9 +829,6 @@ public:
|
||||||
notproduct(bool, StressCriticalJNINatives, false, \
|
notproduct(bool, StressCriticalJNINatives, false, \
|
||||||
"Exercise register saving code in critical natives") \
|
"Exercise register saving code in critical natives") \
|
||||||
\
|
\
|
||||||
product(bool, UseSSE42Intrinsics, false, \
|
|
||||||
"SSE4.2 versions of intrinsics") \
|
|
||||||
\
|
|
||||||
product(bool, UseAESIntrinsics, false, \
|
product(bool, UseAESIntrinsics, false, \
|
||||||
"Use intrinsics for AES versions of crypto") \
|
"Use intrinsics for AES versions of crypto") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -0,0 +1,674 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright 2016 SAP AG. 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 8145336
|
||||||
|
* @summary PPC64: fix string intrinsics after CompactStrings change
|
||||||
|
* @library /testlibrary /../../test/lib
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
*
|
||||||
|
* @run main/othervm
|
||||||
|
* -Xbootclasspath/a:.
|
||||||
|
* -XX:+UnlockDiagnosticVMOptions
|
||||||
|
* -XX:+WhiteBoxAPI
|
||||||
|
* -XX:MaxInlineSize=100
|
||||||
|
* -XX:MinInliningThreshold=0
|
||||||
|
* TestStringIntrinsics2
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.*;
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
public class TestStringIntrinsics2 {
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We test the following cases:
|
||||||
|
// - no match in string. Do we miss the end condition? Will crash if we read
|
||||||
|
// past the string.
|
||||||
|
// - no match in string, but after the string there is a match.
|
||||||
|
// Do we incorrectly report this match? We had a case where we stepped
|
||||||
|
// a few chars past the string, this test would report that error. The
|
||||||
|
// one above would not.
|
||||||
|
// - The needle is exactly at the end of the string.
|
||||||
|
// - The needle spans the end of the string
|
||||||
|
//
|
||||||
|
// A special case are needles of length 1. For these we test:
|
||||||
|
// - needle is first char
|
||||||
|
// - needle is last char
|
||||||
|
// - no match
|
||||||
|
// - match behind string.
|
||||||
|
//
|
||||||
|
// We test all these for an unknown needle, and needles known to the compiler
|
||||||
|
// of lengths 5, 2 and 1.
|
||||||
|
|
||||||
|
|
||||||
|
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||||
|
|
||||||
|
public enum Role {
|
||||||
|
TEST_ENTRY,
|
||||||
|
TEST_HELPER
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@interface Test {
|
||||||
|
Role role();
|
||||||
|
int compileAt() default 0;
|
||||||
|
int warmup() default 0;
|
||||||
|
String[] warmupArgs() default {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// All this mess is needed to avoid try/catch inside the lambdas below.
|
||||||
|
// See: http://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams
|
||||||
|
@SuppressWarnings ("unchecked")
|
||||||
|
private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
|
||||||
|
throw (E)exception;
|
||||||
|
}
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Consumer_WithExceptions<T, E extends Exception> {
|
||||||
|
void accept(T t) throws E;
|
||||||
|
}
|
||||||
|
public static <T, E extends Exception> Consumer<T> rethrowConsumer(Consumer_WithExceptions<T, E> consumer) {
|
||||||
|
return t -> {
|
||||||
|
try { consumer.accept(t); }
|
||||||
|
catch (Exception exception) { throwAsUnchecked(exception); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// Warmup helper methods
|
||||||
|
Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
|
||||||
|
.filter(m -> m.isAnnotationPresent(Test.class))
|
||||||
|
.filter(m -> m.getAnnotation(Test.class).warmup() > 0)
|
||||||
|
.forEach(rethrowConsumer(m -> {
|
||||||
|
Test a = m.getAnnotation(Test.class);
|
||||||
|
System.out.println("Warming up " + m + " " + a.warmup() + " time(s) ");
|
||||||
|
for (int i=0; i < a.warmup(); i++) {
|
||||||
|
m.invoke(null, (Object[])a.warmupArgs());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Compile helper methods
|
||||||
|
Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
|
||||||
|
.filter(m -> m.isAnnotationPresent(Test.class))
|
||||||
|
.filter(m -> m.getAnnotation(Test.class).compileAt() > 0)
|
||||||
|
.forEach(rethrowConsumer(m -> {
|
||||||
|
Test a = m.getAnnotation(Test.class);
|
||||||
|
if (WB.isMethodCompilable(m, a.compileAt())) {
|
||||||
|
WB.enqueueMethodForCompilation(m, a.compileAt());
|
||||||
|
while (WB.isMethodQueuedForCompilation(m)) Thread.sleep(10);
|
||||||
|
System.out.println(m + " compiled at " + WB.getMethodCompilationLevel(m));
|
||||||
|
} else {
|
||||||
|
System.out.println("Can't compile " + m + " at level " + a.compileAt());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Run test methods
|
||||||
|
Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
|
||||||
|
.filter(m -> m.isAnnotationPresent(Test.class))
|
||||||
|
.filter(m -> m.getAnnotation(Test.class).role() == Role.TEST_ENTRY)
|
||||||
|
.forEach(rethrowConsumer(m -> {
|
||||||
|
System.out.print("Executing " + m);
|
||||||
|
m.invoke(null, (Object[])null);
|
||||||
|
System.out.println(" - OK");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
static String text = "<t><t><t><t><t><t>\n" + "<hit>";
|
||||||
|
static String text2 = "<t><t><t><t><t><t><t>\n" + "<hit>";
|
||||||
|
static String[] ss = text.split("\n");
|
||||||
|
static String[] ss2 = null;
|
||||||
|
static String needle = "<miss>";
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_indexOf_no_match() {
|
||||||
|
int res = indexOf_no_match_unknown_needle(ss[0], "<miss>");
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_unknown_needle matched at: " + res);
|
||||||
|
res = indexOf_no_match_imm_needle(ss[0]);
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_imm_needle matched at: " + res);
|
||||||
|
res = indexOf_no_match_imm2_needle(ss[0]);
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_imm2_needle matched at: " + res);
|
||||||
|
|
||||||
|
if (ss2 == null) ss2 = text.split("\n");
|
||||||
|
res = indexOf_no_match_unknown_needle(ss2[0], "<miss>");
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_unknown_needle matched at: " + res);
|
||||||
|
res = indexOf_no_match_imm_needle(ss2[0]);
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_imm_needle matched at: " + res);
|
||||||
|
res = indexOf_no_match_imm2_needle(ss2[0]);
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_imm2_needle matched at: " + res);
|
||||||
|
res = indexOf_no_match_imm1_needle(ss2[0]);
|
||||||
|
assertEquals(res, -1, "test_indexOf_no_match_imm1_needle matched at: " + res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>", "<miss>" })
|
||||||
|
static int indexOf_no_match_unknown_needle(String s, String needle) {
|
||||||
|
int index = s.indexOf(needle);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static int indexOf_no_match_imm_needle(String s) {
|
||||||
|
int index = s.indexOf("<hitt>");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static int indexOf_no_match_imm2_needle(String s) {
|
||||||
|
int index = s.indexOf("<m");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static int indexOf_no_match_imm1_needle(String s) {
|
||||||
|
int index = s.indexOf("m");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_indexOf_reads_past_string() {
|
||||||
|
if (ss == null) ss = text.split("\n");
|
||||||
|
String res = indexOf_reads_past_string_unknown_needle(ss[0], "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_reads_past_string_unknown_needle " + res);
|
||||||
|
res = indexOf_reads_past_string_imm_needle(ss[0]);
|
||||||
|
assertEquals(res, null, "test_indexOf_reads_past_string_imm_needle " + res);
|
||||||
|
res = indexOf_reads_past_string_imm2_needle(ss[0]);
|
||||||
|
assertEquals(res, null, "test_indexOf_reads_past_string_imm2_needle " + res);
|
||||||
|
res = indexOf_reads_past_string_imm1_needle(ss[0]);
|
||||||
|
assertEquals(res, null, "test_indexOf_reads_past_string_imm1_needle " + res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>", "<hit>" })
|
||||||
|
static String indexOf_reads_past_string_unknown_needle(String s, String needle) {
|
||||||
|
int index = s.indexOf(needle);
|
||||||
|
if (index > s.length()) {
|
||||||
|
return "Found needle \"" + needle + "\" behind string of length " + s.length()
|
||||||
|
+ " at position " + index + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static String indexOf_reads_past_string_imm_needle(String s) {
|
||||||
|
int index = s.indexOf("<hit>");
|
||||||
|
if (index > s.length()) {
|
||||||
|
return "Found needle \"<hit>\" behind string of length " + s.length() + " at position " + index + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static String indexOf_reads_past_string_imm2_needle(String s) {
|
||||||
|
int index = s.indexOf("<h");
|
||||||
|
if (index > s.length()) {
|
||||||
|
return "Found needle \"<h\" behind string of length " + s.length() + " at position " + index + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
|
||||||
|
static String indexOf_reads_past_string_imm1_needle(String s) {
|
||||||
|
int index = s.indexOf("h");
|
||||||
|
if (index > s.length()) {
|
||||||
|
return "Found needle \"<h\" behind string of length " + s.length() + " at position " + index + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String text3 = "<t><hi><t><h><hit<t><hit>";
|
||||||
|
static String text4 = "a<t><hi><t><h><hit<t><hit>";
|
||||||
|
static String text5 = "gg<t><hi><t><h><hit<t><hit>";
|
||||||
|
static String text6 = "ccc<t><hi><t><h><hit<t><hit>";
|
||||||
|
static int len3 = text3.length();
|
||||||
|
static int len4 = text4.length();
|
||||||
|
static int len5 = text5.length();
|
||||||
|
static int len6 = text6.length();
|
||||||
|
|
||||||
|
static String text7 = "<t><t><t><t><t<t><h";
|
||||||
|
static String text8 = "a<t><t><t><t><t<t><h";
|
||||||
|
static String text9 = "gg<t><t><t><t><t<t><h";
|
||||||
|
static String text10 = "ccc<t><t><t><t><t<t><h";
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_indexOf_match_at_end_of_string() {
|
||||||
|
String testname = "test_indexOf_match_at_end_of_string";
|
||||||
|
int res = 0;
|
||||||
|
res = indexOf_match_at_end_of_string_unknown_needle(text3, "<hit>");
|
||||||
|
assertEquals(len3, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_unknown_needle(text4, "<hit>");
|
||||||
|
assertEquals(len4, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_unknown_needle(text5, "<hit>");
|
||||||
|
assertEquals(len5, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_unknown_needle(text6, "<hit>");
|
||||||
|
assertEquals(len6, res + 5, testname);
|
||||||
|
|
||||||
|
res = indexOf_match_at_end_of_string_imm_needle(text3);
|
||||||
|
assertEquals(len3, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm_needle(text4);
|
||||||
|
assertEquals(len4, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm_needle(text5);
|
||||||
|
assertEquals(len5, res + 5, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm_needle(text6);
|
||||||
|
assertEquals(len6, res + 5, testname);
|
||||||
|
|
||||||
|
res = indexOf_match_at_end_of_string_imm2_needle(text7);
|
||||||
|
assertEquals(text7.length(), res + 2, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm2_needle(text8);
|
||||||
|
assertEquals(text8.length(), res + 2, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm2_needle(text9);
|
||||||
|
assertEquals(text9.length(), res + 2, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm2_needle(text10);
|
||||||
|
assertEquals(text10.length(), res + 2, testname);
|
||||||
|
|
||||||
|
res = indexOf_match_at_end_of_string_imm1_needle(text7);
|
||||||
|
assertEquals(text7.length(), res + 1, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm1_needle(text8);
|
||||||
|
assertEquals(text8.length(), res + 1, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm1_needle(text9);
|
||||||
|
assertEquals(text9.length(), res + 1, testname);
|
||||||
|
res = indexOf_match_at_end_of_string_imm1_needle(text10);
|
||||||
|
assertEquals(text10.length(), res + 1, testname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>", "<hit>" })
|
||||||
|
static int indexOf_match_at_end_of_string_unknown_needle(String s, String needle) {
|
||||||
|
int index = s.indexOf(needle);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
|
||||||
|
static int indexOf_match_at_end_of_string_imm_needle(String s) {
|
||||||
|
int index = s.indexOf("<hit>");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
|
||||||
|
static int indexOf_match_at_end_of_string_imm2_needle(String s) {
|
||||||
|
int index = s.indexOf("<h");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
|
||||||
|
static int indexOf_match_at_end_of_string_imm1_needle(String s) {
|
||||||
|
int index = s.indexOf("h");
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String s0_1 = text3.substring(0, len3-1);
|
||||||
|
static String s0_2 = text3.substring(0, len3-2);
|
||||||
|
static String s0_3 = text3.substring(0, len3-3);
|
||||||
|
static String s0_4 = text3.substring(0, len3-4);
|
||||||
|
static String s1_1 = text4.substring(0, len4-1);
|
||||||
|
static String s1_2 = text4.substring(0, len4-2);
|
||||||
|
static String s1_3 = text4.substring(0, len4-3);
|
||||||
|
static String s1_4 = text4.substring(0, len4-4);
|
||||||
|
static String s2_1 = text5.substring(0, len5-1);
|
||||||
|
static String s2_2 = text5.substring(0, len5-2);
|
||||||
|
static String s2_3 = text5.substring(0, len5-3);
|
||||||
|
static String s2_4 = text5.substring(0, len5-4);
|
||||||
|
static String s3_1 = text6.substring(0, len6-1);
|
||||||
|
static String s3_2 = text6.substring(0, len6-2);
|
||||||
|
static String s3_3 = text6.substring(0, len6-3);
|
||||||
|
static String s3_4 = text6.substring(0, len6-4);
|
||||||
|
|
||||||
|
static String s0_1x = text7 .substring(0, text7 .length()-1);
|
||||||
|
static String s1_1x = text8 .substring(0, text8 .length()-1);
|
||||||
|
static String s2_1x = text9 .substring(0, text9 .length()-1);
|
||||||
|
static String s3_1x = text10.substring(0, text10.length()-1);
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_indexOf_match_spans_end_of_string() {
|
||||||
|
String res = null;
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s0_1, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s0_2, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s0_3, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s0_4, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s1_1, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s1_2, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s1_3, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s1_4, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s2_1, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s2_2, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s2_3, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s2_4, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s3_1, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s3_2, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s3_3, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_unknown_needle(s3_4, "<hit>");
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_4 " + res);
|
||||||
|
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s0_1);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s0_2);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s0_3);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s0_4);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s1_1);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s1_2);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s1_3);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s1_4);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s2_1);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s2_2);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s2_3);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s2_4);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_4 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s3_1);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_1 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s3_2);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_2 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s3_3);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_3 " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm_needle(s3_4);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_4 " + res);
|
||||||
|
|
||||||
|
res = indexOf_match_spans_end_of_string_imm2_needle(s0_1x);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s0_1x " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm2_needle(s1_1x);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s1_1x " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm2_needle(s2_1x);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s2_1x " + res);
|
||||||
|
res = indexOf_match_spans_end_of_string_imm2_needle(s3_1x);
|
||||||
|
assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s3_1x " + res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit", "<hit>" })
|
||||||
|
static String indexOf_match_spans_end_of_string_unknown_needle(String s, String needle) {
|
||||||
|
int index = s.indexOf(needle);
|
||||||
|
if (index > -1) {
|
||||||
|
return "Found needle \"" + needle + "\" that is spanning the end of the string: " + s + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit" })
|
||||||
|
static String indexOf_match_spans_end_of_string_imm_needle(String s) {
|
||||||
|
int index = s.indexOf("<hit>");
|
||||||
|
if (index > -1) {
|
||||||
|
return "Found needle \"<hit>\" that is spanning the end of the string: " + s + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t><t><t<t><" })
|
||||||
|
static String indexOf_match_spans_end_of_string_imm2_needle(String s) {
|
||||||
|
int index = s.indexOf("<h");
|
||||||
|
if (index > -1) {
|
||||||
|
return "Found needle \"<h\" that is spanning the end of the string: " + s + ".";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String text16 = "ooooooo";
|
||||||
|
static String text11 = "1ooooooo";
|
||||||
|
static String text12 = "ooooooo1";
|
||||||
|
static String text13 = "oooooooo1";
|
||||||
|
static String text14 = "ooooooooo1";
|
||||||
|
static String text15 = "oooooooooo1";
|
||||||
|
static int len12 = text12.length();
|
||||||
|
static int len13 = text13.length();
|
||||||
|
static int len14 = text14.length();
|
||||||
|
static int len15 = text15.length();
|
||||||
|
|
||||||
|
static String text12_1 = text12.substring(0, len12-1);
|
||||||
|
static String text13_1 = text13.substring(0, len13-1);
|
||||||
|
static String text14_1 = text14.substring(0, len14-1);
|
||||||
|
static String text15_1 = text15.substring(0, len15-1);
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_indexOf_imm1_needle() {
|
||||||
|
assertEquals( -1, indexOf_imm1_needle(text16), "test_indexOf_imm1_needle no_match");
|
||||||
|
|
||||||
|
assertEquals( 0, indexOf_imm1_needle(text11), "test_indexOf_imm1_needle first_matches");
|
||||||
|
|
||||||
|
assertEquals(len12-1, indexOf_imm1_needle(text12), "test_indexOf_imm1_needle last_matches");
|
||||||
|
assertEquals(len13-1, indexOf_imm1_needle(text13), "test_indexOf_imm1_needle last_matches");
|
||||||
|
assertEquals(len14-1, indexOf_imm1_needle(text14), "test_indexOf_imm1_needle last_matches");
|
||||||
|
assertEquals(len15-1, indexOf_imm1_needle(text15), "test_indexOf_imm1_needle last_matches");
|
||||||
|
|
||||||
|
assertEquals( -1, indexOf_imm1_needle(text12_1), "test_indexOf_imm1_needle walked_past");
|
||||||
|
assertEquals( -1, indexOf_imm1_needle(text13_1), "test_indexOf_imm1_needle walked_past");
|
||||||
|
assertEquals( -1, indexOf_imm1_needle(text14_1), "test_indexOf_imm1_needle walked_past");
|
||||||
|
assertEquals( -1, indexOf_imm1_needle(text15_1), "test_indexOf_imm1_needle walked_past");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "ooooooo1" })
|
||||||
|
static int indexOf_imm1_needle(String s) {
|
||||||
|
return s.indexOf("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "abc", "abcd" })
|
||||||
|
public static int asmStringCompareTo(String a, String b) {
|
||||||
|
return a.compareTo(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_asmStringCompareTo() {
|
||||||
|
// null
|
||||||
|
try {
|
||||||
|
asmStringCompareTo("not null", null);
|
||||||
|
assertTrue(false,
|
||||||
|
"TestOther.asmStringCompareTo(\"not null\", null) doesn't throw exception");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
assertEquals("java.lang.String.compareTo",
|
||||||
|
e.getStackTrace()[0].getClassName() + "." +
|
||||||
|
e.getStackTrace()[0].getMethodName(),
|
||||||
|
"TestOther.asmStringCompareTo(\"not null\", null) throws exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==0
|
||||||
|
{
|
||||||
|
// check length 0 optimization
|
||||||
|
assertEquals(0, asmStringCompareTo("", ""),
|
||||||
|
"TestOther.asmStringCompareTo(\"\", \"\")");
|
||||||
|
|
||||||
|
// check first character optimization
|
||||||
|
assertEquals(0, asmStringCompareTo("A", "A"),
|
||||||
|
"TestOther.asmStringCompareTo(\"A\", \"A\")");
|
||||||
|
|
||||||
|
// check real comparisons
|
||||||
|
assertEquals(0, asmStringCompareTo(new String("eq") + new String("ual"), "equal"),
|
||||||
|
"TestOther.asmStringCompareTo(\"equal\", \"equal\")");
|
||||||
|
assertEquals(0, asmStringCompareTo("textABC", "textABC"),
|
||||||
|
"TestOther.asmStringCompareTo(\"textABC\", \"textABC\")");
|
||||||
|
assertEquals(0,
|
||||||
|
asmStringCompareTo(new String("abcdefgh01234") +
|
||||||
|
new String("56abcdefgh0123456abcdefgh0123456"),
|
||||||
|
"abcdefgh0123456abcdefgh0123456abcdefgh0123456"),
|
||||||
|
"TestOther.asmStringCompareTo(\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\", " +
|
||||||
|
"\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// <0
|
||||||
|
{
|
||||||
|
// check first character optimization
|
||||||
|
assertEquals(-1, asmStringCompareTo("4", "5"),
|
||||||
|
"TestOther.asmStringCompareTo(\"4\", \"5\")");
|
||||||
|
|
||||||
|
// check real comparisons
|
||||||
|
assertEquals(-1, asmStringCompareTo("diff4", "diff5"),
|
||||||
|
"TestOther.asmStringCompareTo(\"diff4\", \"diff5\")");
|
||||||
|
assertEquals(-10, asmStringCompareTo("", "123456789A"),
|
||||||
|
"TestOther.asmStringCompareTo(\"\", \"123456789A\")");
|
||||||
|
assertEquals(-10, asmStringCompareTo("ZYX", "ZYX123456789A"),
|
||||||
|
"TestOther.asmStringCompareTo(\"ZYX\", \"ZYX123456789A\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// >0
|
||||||
|
{
|
||||||
|
// check first character optimization
|
||||||
|
assertEquals(1, asmStringCompareTo("5", "4"),
|
||||||
|
"TestOther.asmStringCompareTo(\"5\", \"4\")");
|
||||||
|
|
||||||
|
// check real comparisons
|
||||||
|
assertEquals(1, asmStringCompareTo("diff5", "diff4"),
|
||||||
|
"TestOther.asmStringCompareTo(\"diff5\", \"diff4\")");
|
||||||
|
assertEquals(10, asmStringCompareTo("123456789A", ""),
|
||||||
|
"TestOther.asmStringCompareTo(\"123456789A\", \"\")");
|
||||||
|
assertEquals(10, asmStringCompareTo("ZYX123456789A", "ZYX"),
|
||||||
|
"TestOther.asmStringCompareTo(\"ZYX123456789A\", \"ZYX\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// very long strings (100k)
|
||||||
|
{
|
||||||
|
char[] ac = new char[(100 * 1024)];
|
||||||
|
for (int i = 0; i < (100 * 1024); i += 315)
|
||||||
|
ac[i] = (char) ((i % 12) + 'a');
|
||||||
|
char[] bc = new char[(100 * 1024)];
|
||||||
|
for (int i = 0; i < (100 * 1024); i += 315)
|
||||||
|
bc[i] = (char) ((i % 12) + 'a');
|
||||||
|
|
||||||
|
ac[(100 * 1024) - 1] = '2';
|
||||||
|
bc[(100 * 1024) - 1] = '2';
|
||||||
|
String a1 = new String(ac);
|
||||||
|
String b1 = new String(bc);
|
||||||
|
assertEquals(0, asmStringCompareTo(a1, b1),
|
||||||
|
"TestOther.asmStringCompareTo(very_long_strings_1)");
|
||||||
|
|
||||||
|
ac[(100 * 1024) - 1] = 'X';
|
||||||
|
bc[(100 * 1024) - 1] = 'Z';
|
||||||
|
String a2 = new String(ac);
|
||||||
|
String b2 = new String(bc);
|
||||||
|
assertEquals(-2, asmStringCompareTo(a2, b2),
|
||||||
|
"TestOther.asmStringCompareTo(very_long_strings_2)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// very very long strings (2M)
|
||||||
|
{
|
||||||
|
char[] ac = new char[(2 * 1024 * 1024)];
|
||||||
|
for (int i = 0; i < (2 * 1024 * 1024); i += 315)
|
||||||
|
ac[i] = (char) ((i % 12) + 'a');
|
||||||
|
char[] bc = new char[(2 * 1024 * 1024)];
|
||||||
|
for (int i = 0; i < (2 * 1024 * 1024); i += 315)
|
||||||
|
bc[i] = (char) ((i % 12) + 'a');
|
||||||
|
|
||||||
|
ac[(2 * 1024 * 1024) - 1] = '3';
|
||||||
|
bc[(2 * 1024 * 1024) - 1] = '3';
|
||||||
|
String a1 = new String(ac);
|
||||||
|
String b1 = new String(bc);
|
||||||
|
assertEquals(0, asmStringCompareTo(a1, b1),
|
||||||
|
"TestOther.asmStringCompareTo(very_very_long_strings_1)");
|
||||||
|
|
||||||
|
ac[(2 * 1024 * 1024) - 1] = 'W';
|
||||||
|
bc[(2 * 1024 * 1024) - 1] = 'Z';
|
||||||
|
String a2 = new String(ac);
|
||||||
|
String b2 = new String(bc);
|
||||||
|
assertEquals(-3, asmStringCompareTo(a2, b2),
|
||||||
|
"TestOther.asmStringCompareTo(very_very_long_strings_2)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "abc", "abcd" })
|
||||||
|
public static boolean asmStringEquals(String a, String b) {
|
||||||
|
return a.equals(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String a1 = "abcd";
|
||||||
|
static String b1 = "abcd";
|
||||||
|
static final String a2 = "1234";
|
||||||
|
static final String b2 = "1234";
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1)
|
||||||
|
public static boolean asmStringEqualsConst() {
|
||||||
|
boolean ret = a1.equals(b1);
|
||||||
|
ret &= a2.equals(b2);
|
||||||
|
ret &= !a2.equals(b1);
|
||||||
|
ret &= "ABCD".equals("ABCD");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(role = Role.TEST_ENTRY)
|
||||||
|
public static void test_asmStringEquals() {
|
||||||
|
// null
|
||||||
|
{
|
||||||
|
assertFalse(asmStringEquals("not null", null),
|
||||||
|
"TestOther.asmStringEquals(\"not null\", null)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// true
|
||||||
|
{
|
||||||
|
// check constant optimization
|
||||||
|
assertTrue(asmStringEqualsConst(),
|
||||||
|
"TestOther.asmStringEqualsConst(\"\", \"\")");
|
||||||
|
|
||||||
|
// check length 0 optimization
|
||||||
|
assertTrue(asmStringEquals("", ""),
|
||||||
|
"TestOther.asmStringEquals(\"\", \"\")");
|
||||||
|
|
||||||
|
// check first character optimization
|
||||||
|
assertTrue(asmStringEquals("A", "A"),
|
||||||
|
"TestOther.asmStringEquals(\"A\", \"A\")");
|
||||||
|
|
||||||
|
// check real comparisons
|
||||||
|
assertTrue(asmStringEquals(new String("eq") + new String("ual"), "equal"),
|
||||||
|
"TestOther.asmStringEquals(\"equal\", \"equal\")");
|
||||||
|
assertTrue(asmStringEquals("textABC", "textABC"),
|
||||||
|
"TestOther.asmStringEquals(\"textABC\", \"textABC\")");
|
||||||
|
assertTrue(asmStringEquals(new String("abcdefgh01234") +
|
||||||
|
new String("56abcdefgh0123456abcdefgh0123456"),
|
||||||
|
"abcdefgh0123456abcdefgh0123456abcdefgh0123456"),
|
||||||
|
"TestOther.asmStringEquals(\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\", " +
|
||||||
|
"\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue