--- old/src/share/vm/opto/graphKit.cpp 2015-10-30 19:14:53.276475697 +0100 +++ new/src/share/vm/opto/graphKit.cpp 2015-10-30 19:14:53.208475694 +0100 @@ -4266,35 +4266,11 @@ #undef __ - -Node* GraphKit::load_String_offset(Node* ctrl, Node* str) { - if (java_lang_String::has_offset_field()) { - int offset_offset = java_lang_String::offset_offset_in_bytes(); - const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), - false, NULL, 0); - const TypePtr* offset_field_type = string_type->add_offset(offset_offset); - int offset_field_idx = C->get_alias_index(offset_field_type); - return make_load(ctrl, - basic_plus_adr(str, str, offset_offset), - TypeInt::INT, T_INT, offset_field_idx, MemNode::unordered); - } else { - return intcon(0); - } -} - Node* GraphKit::load_String_length(Node* ctrl, Node* str) { - if (java_lang_String::has_count_field()) { - int count_offset = java_lang_String::count_offset_in_bytes(); - const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), - false, NULL, 0); - const TypePtr* count_field_type = string_type->add_offset(count_offset); - int count_field_idx = C->get_alias_index(count_field_type); - return make_load(ctrl, - basic_plus_adr(str, str, count_offset), - TypeInt::INT, T_INT, count_field_idx, MemNode::unordered); - } else { - return load_array_length(load_String_value(ctrl, str)); - } + Node* len = load_array_length(load_String_value(ctrl, str)); + Node* coder = load_String_coder(ctrl, str); + // Divide length by 2 if coder is UTF16 + return _gvn.transform(new RShiftINode(len, coder)); } Node* GraphKit::load_String_value(Node* ctrl, Node* str) { @@ -4302,9 +4278,9 @@ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, - TypeAry::make(TypeInt::CHAR,TypeInt::POS), - ciTypeArrayKlass::make(T_CHAR), true, 0); + const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, + TypeAry::make(TypeInt::BYTE, TypeInt::POS), + ciTypeArrayKlass::make(T_BYTE), true, 0); int value_field_idx = C->get_alias_index(value_field_type); Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset), value_type, T_OBJECT, value_field_idx, MemNode::unordered); @@ -4315,14 +4291,21 @@ return load; } -void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) { - int offset_offset = java_lang_String::offset_offset_in_bytes(); - const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), - false, NULL, 0); - const TypePtr* offset_field_type = string_type->add_offset(offset_offset); - int offset_field_idx = C->get_alias_index(offset_field_type); - store_to_memory(ctrl, basic_plus_adr(str, offset_offset), - value, T_INT, offset_field_idx, MemNode::unordered); +Node* GraphKit::load_String_coder(Node* ctrl, Node* str) { + if (java_lang_String::has_coder_field()) { + if (!CompactStrings) { + return intcon(java_lang_String::CODER_UTF16); + } + int coder_offset = java_lang_String::coder_offset_in_bytes(); + const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), + false, NULL, 0); + const TypePtr* coder_field_type = string_type->add_offset(coder_offset); + int coder_field_idx = C->get_alias_index(coder_field_type); + return make_load(ctrl, basic_plus_adr(str, str, coder_offset), + TypeInt::BYTE, T_BYTE, coder_field_idx, MemNode::unordered); + } else { + return intcon(0); // false + } } void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) { @@ -4330,19 +4313,76 @@ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - store_oop_to_object(ctrl, str, basic_plus_adr(str, value_offset), value_field_type, - value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered); + value, TypeAryPtr::BYTES, T_OBJECT, MemNode::unordered); } -void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) { - int count_offset = java_lang_String::count_offset_in_bytes(); +void GraphKit::store_String_coder(Node* ctrl, Node* str, Node* value) { + int coder_offset = java_lang_String::coder_offset_in_bytes(); const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); - const TypePtr* count_field_type = string_type->add_offset(count_offset); - int count_field_idx = C->get_alias_index(count_field_type); - store_to_memory(ctrl, basic_plus_adr(str, count_offset), - value, T_INT, count_field_idx, MemNode::unordered); + const TypePtr* coder_field_type = string_type->add_offset(coder_offset); + int coder_field_idx = C->get_alias_index(coder_field_type); + store_to_memory(ctrl, basic_plus_adr(str, coder_offset), + value, T_BYTE, coder_field_idx, MemNode::unordered); +} + +Node* GraphKit::compress_string(Node* src, Node* dst, Node* count) { + assert(Matcher::match_rule_supported(Op_StrCompressedCopy), "Intrinsic not supported"); + uint idx = C->get_alias_index(TypeAryPtr::BYTES); + StrCompressedCopyNode* str = new StrCompressedCopyNode(control(), memory(idx), src, dst, count); + Node* res_mem = _gvn.transform(new SCMemProjNode(str)); + set_memory(res_mem, idx); + return str; +} + +void GraphKit::inflate_string(Node* src, Node* dst, Node* count) { + assert(Matcher::match_rule_supported(Op_StrInflatedCopy), "Intrinsic not supported"); + uint idx = C->get_alias_index(TypeAryPtr::BYTES); + StrInflatedCopyNode* str = new StrInflatedCopyNode(control(), memory(idx), src, dst, count); + set_memory(_gvn.transform(str), idx); +} + +void GraphKit::inflate_string_slow(Node* src, Node* dst, Node* start, Node* count) { + /** + * int i_char = start; + * for (int i_byte = 0; i_byte < count; i_byte++) { + * dst[i_char++] = (char)(src[i_byte] & 0xff); + * } + */ + add_predicate(); + RegionNode* head = new RegionNode(3); + head->init_req(1, control()); + gvn().set_type(head, Type::CONTROL); + record_for_igvn(head); + + Node* i_byte = new PhiNode(head, TypeInt::INT); + i_byte->init_req(1, intcon(0)); + gvn().set_type(i_byte, TypeInt::INT); + record_for_igvn(i_byte); + + Node* i_char = new PhiNode(head, TypeInt::INT); + i_char->init_req(1, start); + gvn().set_type(i_char, TypeInt::INT); + record_for_igvn(i_char); + + Node* mem = PhiNode::make(head, memory(TypeAryPtr::BYTES), Type::MEMORY, TypeAryPtr::BYTES); + gvn().set_type(mem, Type::MEMORY); + record_for_igvn(mem); + set_control(head); + set_memory(mem, TypeAryPtr::BYTES); + Node* ch = load_array_element(control(), src, i_byte, TypeAryPtr::BYTES); + Node* st = store_to_memory(control(), array_element_address(dst, i_char, T_BYTE), + AndI(ch, intcon(0xff)), T_CHAR, TypeAryPtr::BYTES, MemNode::unordered); + + IfNode* iff = create_and_map_if(head, Bool(CmpI(i_byte, count), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); + head->init_req(2, IfTrue(iff)); + mem->init_req(2, st); + i_byte->init_req(2, AddI(i_byte, intcon(1))); + i_char->init_req(2, AddI(i_char, intcon(2))); + + set_control(IfFalse(iff)); + set_memory(st, TypeAryPtr::BYTES); } Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {