| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index be7286e7c7365e8c064a80b6f5d98ddd3ed7ba00..170ad235e316f3f21141e296282c5252e47e402a 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -2073,47 +2073,66 @@ void CodeStubAssembler::CopyFixedArrayElements(
|
| Comment("] CopyFixedArrayElements");
|
| }
|
|
|
| -void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string,
|
| - compiler::Node* to_string,
|
| - compiler::Node* from_index,
|
| - compiler::Node* to_index,
|
| - compiler::Node* character_count,
|
| - String::Encoding encoding,
|
| - ParameterMode mode) {
|
| - bool one_byte = encoding == String::ONE_BYTE_ENCODING;
|
| - Comment(one_byte ? "CopyStringCharacters ONE_BYTE_ENCODING"
|
| - : "CopyStringCharacters TWO_BYTE_ENCODING");
|
| -
|
| - ElementsKind kind = one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS;
|
| - int header_size = (one_byte ? SeqOneByteString::kHeaderSize
|
| - : SeqTwoByteString::kHeaderSize) -
|
| - kHeapObjectTag;
|
| - Node* from_offset = ElementOffsetFromIndex(from_index, kind, mode);
|
| - Node* to_offset = ElementOffsetFromIndex(to_index, kind, mode);
|
| - Node* byte_count = ElementOffsetFromIndex(character_count, kind, mode);
|
| +void CodeStubAssembler::CopyStringCharacters(
|
| + compiler::Node* from_string, compiler::Node* to_string,
|
| + compiler::Node* from_index, compiler::Node* to_index,
|
| + compiler::Node* character_count, String::Encoding from_encoding,
|
| + String::Encoding to_encoding, ParameterMode mode) {
|
| + bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING;
|
| + bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING;
|
| + DCHECK_IMPLIES(to_one_byte, from_one_byte);
|
| + Comment("CopyStringCharacters %s -> %s",
|
| + from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING",
|
| + to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING");
|
| +
|
| + ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS;
|
| + ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS;
|
| + STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
|
| + int header_size = SeqOneByteString::kHeaderSize - kHeapObjectTag;
|
| + Node* from_offset =
|
| + ElementOffsetFromIndex(from_index, from_kind, mode, header_size);
|
| + Node* to_offset =
|
| + ElementOffsetFromIndex(to_index, to_kind, mode, header_size);
|
| + Node* byte_count = ElementOffsetFromIndex(character_count, from_kind, mode);
|
| Node* limit_offset = IntPtrAddFoldConstants(from_offset, byte_count);
|
|
|
| // Prepare the fast loop
|
| - MachineType type = one_byte ? MachineType::Uint8() : MachineType::Uint16();
|
| - MachineRepresentation rep =
|
| - one_byte ? MachineRepresentation::kWord8 : MachineRepresentation::kWord16;
|
| - int increment = -(1 << ElementsKindToShiftSize(kind));
|
| -
|
| - Node* to_string_adjusted = IntPtrAddFoldConstants(
|
| - to_string, IntPtrSubFoldConstants(to_offset, from_offset));
|
| - limit_offset =
|
| - IntPtrAddFoldConstants(limit_offset, IntPtrConstant(header_size));
|
| - from_offset =
|
| - IntPtrAddFoldConstants(from_offset, IntPtrConstant(header_size));
|
| -
|
| - BuildFastLoop(MachineType::PointerRepresentation(), limit_offset, from_offset,
|
| - [from_string, to_string_adjusted, type, rep](
|
| - CodeStubAssembler* assembler, Node* offset) {
|
| + MachineType type =
|
| + from_one_byte ? MachineType::Uint8() : MachineType::Uint16();
|
| + MachineRepresentation rep = to_one_byte ? MachineRepresentation::kWord8
|
| + : MachineRepresentation::kWord16;
|
| + int from_increment = 1 << ElementsKindToShiftSize(from_kind);
|
| + int to_increment = 1 << ElementsKindToShiftSize(to_kind);
|
| +
|
| + Variable current_to_offset(this, MachineType::PointerRepresentation());
|
| + VariableList vars({¤t_to_offset}, zone());
|
| + current_to_offset.Bind(to_offset);
|
| + int to_index_constant = 0, from_index_constant = 0;
|
| + Smi* to_index_smi = nullptr;
|
| + Smi* from_index_smi = nullptr;
|
| + bool index_same = (from_encoding == to_encoding) &&
|
| + (from_index == to_index ||
|
| + (ToInt32Constant(from_index, from_index_constant) &&
|
| + ToInt32Constant(to_index, to_index_constant) &&
|
| + from_index_constant == to_index_constant) ||
|
| + (ToSmiConstant(from_index, from_index_smi) &&
|
| + ToSmiConstant(to_index, to_index_smi) &&
|
| + to_index_smi == from_index_smi));
|
| + BuildFastLoop(vars, MachineType::PointerRepresentation(), from_offset,
|
| + limit_offset,
|
| + [from_string, to_string, ¤t_to_offset, to_increment, type,
|
| + rep, index_same](CodeStubAssembler* assembler, Node* offset) {
|
| Node* value = assembler->Load(type, from_string, offset);
|
| - assembler->StoreNoWriteBarrier(rep, to_string_adjusted,
|
| - offset, value);
|
| + assembler->StoreNoWriteBarrier(
|
| + rep, to_string,
|
| + index_same ? offset : current_to_offset.value(), value);
|
| + if (!index_same) {
|
| + current_to_offset.Bind(assembler->IntPtrAdd(
|
| + current_to_offset.value(),
|
| + assembler->IntPtrConstant(to_increment)));
|
| + }
|
| },
|
| - increment);
|
| + from_increment, IndexAdvanceMode::kPost);
|
| }
|
|
|
| Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array,
|
| @@ -2983,6 +3002,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
|
| a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
|
| a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
|
| String::ONE_BYTE_ENCODING,
|
| + String::ONE_BYTE_ENCODING,
|
| CodeStubAssembler::SMI_PARAMETERS);
|
| var_result.Bind(result);
|
|
|
| @@ -2996,6 +3016,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
|
| a->AllocateSeqTwoByteString(context, a->SmiToWord(character_count));
|
| a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
|
| String::TWO_BYTE_ENCODING,
|
| + String::TWO_BYTE_ENCODING,
|
| CodeStubAssembler::SMI_PARAMETERS);
|
| var_result.Bind(result);
|
|
|
| @@ -3297,9 +3318,11 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
|
| AllocateSeqOneByteString(context, new_length, SMI_PARAMETERS);
|
| CopyStringCharacters(left, new_string, SmiConstant(Smi::kZero),
|
| SmiConstant(Smi::kZero), left_length,
|
| - String::ONE_BYTE_ENCODING, SMI_PARAMETERS);
|
| + String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING,
|
| + SMI_PARAMETERS);
|
| CopyStringCharacters(right, new_string, SmiConstant(Smi::kZero), left_length,
|
| - right_length, String::ONE_BYTE_ENCODING, SMI_PARAMETERS);
|
| + right_length, String::ONE_BYTE_ENCODING,
|
| + String::ONE_BYTE_ENCODING, SMI_PARAMETERS);
|
| result.Bind(new_string);
|
| Goto(&done_native);
|
|
|
| @@ -3309,10 +3332,11 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
|
| new_string = AllocateSeqTwoByteString(context, new_length, SMI_PARAMETERS);
|
| CopyStringCharacters(left, new_string, SmiConstant(Smi::kZero),
|
| SmiConstant(Smi::kZero), left_length,
|
| - String::TWO_BYTE_ENCODING, SMI_PARAMETERS);
|
| + String::TWO_BYTE_ENCODING, String::TWO_BYTE_ENCODING,
|
| + SMI_PARAMETERS);
|
| CopyStringCharacters(right, new_string, SmiConstant(Smi::kZero),
|
| left_length, right_length, String::TWO_BYTE_ENCODING,
|
| - SMI_PARAMETERS);
|
| + String::TWO_BYTE_ENCODING, SMI_PARAMETERS);
|
| result.Bind(new_string);
|
| Goto(&done_native);
|
| }
|
| @@ -6964,12 +6988,15 @@ Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector,
|
| }
|
|
|
| void CodeStubAssembler::BuildFastLoop(
|
| + const CodeStubAssembler::VariableList& vars,
|
| MachineRepresentation index_rep, Node* start_index, Node* end_index,
|
| std::function<void(CodeStubAssembler* assembler, Node* index)> body,
|
| int increment, IndexAdvanceMode mode) {
|
| Variable var(this, index_rep);
|
| + VariableList vars_copy(vars, zone());
|
| + vars_copy.Add(&var, zone());
|
| var.Bind(start_index);
|
| - Label loop(this, &var);
|
| + Label loop(this, vars_copy);
|
| Label after_loop(this);
|
| // Introduce an explicit second check of the termination condition before the
|
| // loop that helps turbofan generate better code. If there's only a single
|
|
|