--- old/src/hotspot/share/opto/library_call.cpp 2018-11-16 05:31:16.164564082 -0600 +++ new/src/hotspot/share/opto/library_call.cpp 2018-11-16 05:31:15.574583670 -0600 @@ -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_c: + case vmIntrinsics::_isLowerCase_c: + case vmIntrinsics::_isUpperCase_c: + case vmIntrinsics::_isWhitespace_c: + 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,72 @@ return true; } +bool LibraryCallKit::inline_character_compare(vmIntrinsics::ID id) { + Node* codePoint = argument(0); + Node* n = NULL; + switch (id) { + case vmIntrinsics::_isDigit_c : + if (!Matcher::match_rule_supported(Op_DigitC)) { + return false; + } + n = new DigitCNode(control(), codePoint); + break; + case vmIntrinsics::_isLowerCase_c : + if (!Matcher::match_rule_supported(Op_LowerCaseC)) { + return false; + } + n = new LowerCaseCNode(control(), codePoint); + break; + case vmIntrinsics::_isUpperCase_c : + if (!Matcher::match_rule_supported(Op_UpperCaseC)) { + return false; + } + n = new UpperCaseCNode(control(), codePoint); + break; + case vmIntrinsics::_isWhitespace_c : + if (!Matcher::match_rule_supported(Op_WhitespaceC)) { + return false; + } + n = new WhitespaceCNode(control(), codePoint); + break; + default: + fatal_unexpected_iid(id); + break; + } + + enum { _slow_path = 1, _fast_path, PATH_LIMIT }; + RegionNode* result_rgn = new RegionNode(PATH_LIMIT); + PhiNode* result_val = new PhiNode(result_rgn, TypeInt::CHAR); + + RegionNode* slow_region = new RegionNode(1); + record_for_igvn(slow_region); + + Node *ch = _gvn.transform(new URShiftINode(codePoint, intcon(8))); + Node* cmp_bit = _gvn.transform(new CmpINode(ch, intcon(0))); + Node* test = _gvn.transform(new BoolNode(cmp_bit, BoolTest::ne)); + + generate_slow_guard(test, slow_region); + + result_val->init_req(_fast_path, _gvn.transform(n)); + result_rgn->init_req(_fast_path, control()); + + set_control(_gvn.transform(slow_region)); + + if (!stopped()) { + PreserveJVMState pjvms(this); + CallJavaNode* slow_call = generate_method_call_static(id); + Node* slow_val = set_results_for_java_call(slow_call); + result_val->init_req(_slow_path, slow_val); + result_rgn->init_req(_slow_path, control()); + } else { + result_val->init_req(_slow_path, top()); + result_rgn->init_req(_slow_path, top()); + } + set_result(result_rgn, result_val); + + return true; +} + bool LibraryCallKit::inline_profileBoolean() { Node* counts = argument(1); const TypeAryPtr* ary = NULL;