| Index: src/runtime/string-builder.h
|
| diff --git a/src/runtime/string-builder.h b/src/runtime/string-builder.h
|
| deleted file mode 100644
|
| index 890b7f6be1bb0198c3681890991c29e142d42bf4..0000000000000000000000000000000000000000
|
| --- a/src/runtime/string-builder.h
|
| +++ /dev/null
|
| @@ -1,296 +0,0 @@
|
| -// Copyright 2014 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#ifndef V8_RUNTIME_STRING_BUILDER_H_
|
| -#define V8_RUNTIME_STRING_BUILDER_H_
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -const int kStringBuilderConcatHelperLengthBits = 11;
|
| -const int kStringBuilderConcatHelperPositionBits = 19;
|
| -
|
| -typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
|
| - StringBuilderSubstringLength;
|
| -typedef BitField<int, kStringBuilderConcatHelperLengthBits,
|
| - kStringBuilderConcatHelperPositionBits>
|
| - StringBuilderSubstringPosition;
|
| -
|
| -
|
| -template <typename sinkchar>
|
| -static inline void StringBuilderConcatHelper(String* special, sinkchar* sink,
|
| - FixedArray* fixed_array,
|
| - int array_length) {
|
| - DisallowHeapAllocation no_gc;
|
| - int position = 0;
|
| - for (int i = 0; i < array_length; i++) {
|
| - Object* element = fixed_array->get(i);
|
| - if (element->IsSmi()) {
|
| - // Smi encoding of position and length.
|
| - int encoded_slice = Smi::cast(element)->value();
|
| - int pos;
|
| - int len;
|
| - if (encoded_slice > 0) {
|
| - // Position and length encoded in one smi.
|
| - pos = StringBuilderSubstringPosition::decode(encoded_slice);
|
| - len = StringBuilderSubstringLength::decode(encoded_slice);
|
| - } else {
|
| - // Position and length encoded in two smis.
|
| - Object* obj = fixed_array->get(++i);
|
| - DCHECK(obj->IsSmi());
|
| - pos = Smi::cast(obj)->value();
|
| - len = -encoded_slice;
|
| - }
|
| - String::WriteToFlat(special, sink + position, pos, pos + len);
|
| - position += len;
|
| - } else {
|
| - String* string = String::cast(element);
|
| - int element_length = string->length();
|
| - String::WriteToFlat(string, sink + position, 0, element_length);
|
| - position += element_length;
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -// Returns the result length of the concatenation.
|
| -// On illegal argument, -1 is returned.
|
| -static inline int StringBuilderConcatLength(int special_length,
|
| - FixedArray* fixed_array,
|
| - int array_length, bool* one_byte) {
|
| - DisallowHeapAllocation no_gc;
|
| - int position = 0;
|
| - for (int i = 0; i < array_length; i++) {
|
| - int increment = 0;
|
| - Object* elt = fixed_array->get(i);
|
| - if (elt->IsSmi()) {
|
| - // Smi encoding of position and length.
|
| - int smi_value = Smi::cast(elt)->value();
|
| - int pos;
|
| - int len;
|
| - if (smi_value > 0) {
|
| - // Position and length encoded in one smi.
|
| - pos = StringBuilderSubstringPosition::decode(smi_value);
|
| - len = StringBuilderSubstringLength::decode(smi_value);
|
| - } else {
|
| - // Position and length encoded in two smis.
|
| - len = -smi_value;
|
| - // Get the position and check that it is a positive smi.
|
| - i++;
|
| - if (i >= array_length) return -1;
|
| - Object* next_smi = fixed_array->get(i);
|
| - if (!next_smi->IsSmi()) return -1;
|
| - pos = Smi::cast(next_smi)->value();
|
| - if (pos < 0) return -1;
|
| - }
|
| - DCHECK(pos >= 0);
|
| - DCHECK(len >= 0);
|
| - if (pos > special_length || len > special_length - pos) return -1;
|
| - increment = len;
|
| - } else if (elt->IsString()) {
|
| - String* element = String::cast(elt);
|
| - int element_length = element->length();
|
| - increment = element_length;
|
| - if (*one_byte && !element->HasOnlyOneByteChars()) {
|
| - *one_byte = false;
|
| - }
|
| - } else {
|
| - return -1;
|
| - }
|
| - if (increment > String::kMaxLength - position) {
|
| - return kMaxInt; // Provoke throw on allocation.
|
| - }
|
| - position += increment;
|
| - }
|
| - return position;
|
| -}
|
| -
|
| -
|
| -class FixedArrayBuilder {
|
| - public:
|
| - explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
|
| - : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
|
| - length_(0),
|
| - has_non_smi_elements_(false) {
|
| - // Require a non-zero initial size. Ensures that doubling the size to
|
| - // extend the array will work.
|
| - DCHECK(initial_capacity > 0);
|
| - }
|
| -
|
| - explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
|
| - : array_(backing_store), length_(0), has_non_smi_elements_(false) {
|
| - // Require a non-zero initial size. Ensures that doubling the size to
|
| - // extend the array will work.
|
| - DCHECK(backing_store->length() > 0);
|
| - }
|
| -
|
| - bool HasCapacity(int elements) {
|
| - int length = array_->length();
|
| - int required_length = length_ + elements;
|
| - return (length >= required_length);
|
| - }
|
| -
|
| - void EnsureCapacity(int elements) {
|
| - int length = array_->length();
|
| - int required_length = length_ + elements;
|
| - if (length < required_length) {
|
| - int new_length = length;
|
| - do {
|
| - new_length *= 2;
|
| - } while (new_length < required_length);
|
| - Handle<FixedArray> extended_array =
|
| - array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
|
| - array_->CopyTo(0, *extended_array, 0, length_);
|
| - array_ = extended_array;
|
| - }
|
| - }
|
| -
|
| - void Add(Object* value) {
|
| - DCHECK(!value->IsSmi());
|
| - DCHECK(length_ < capacity());
|
| - array_->set(length_, value);
|
| - length_++;
|
| - has_non_smi_elements_ = true;
|
| - }
|
| -
|
| - void Add(Smi* value) {
|
| - DCHECK(value->IsSmi());
|
| - DCHECK(length_ < capacity());
|
| - array_->set(length_, value);
|
| - length_++;
|
| - }
|
| -
|
| - Handle<FixedArray> array() { return array_; }
|
| -
|
| - int length() { return length_; }
|
| -
|
| - int capacity() { return array_->length(); }
|
| -
|
| - Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
|
| - JSArray::SetContent(target_array, array_);
|
| - target_array->set_length(Smi::FromInt(length_));
|
| - return target_array;
|
| - }
|
| -
|
| -
|
| - private:
|
| - Handle<FixedArray> array_;
|
| - int length_;
|
| - bool has_non_smi_elements_;
|
| -};
|
| -
|
| -
|
| -class ReplacementStringBuilder {
|
| - public:
|
| - ReplacementStringBuilder(Heap* heap, Handle<String> subject,
|
| - int estimated_part_count)
|
| - : heap_(heap),
|
| - array_builder_(heap->isolate(), estimated_part_count),
|
| - subject_(subject),
|
| - character_count_(0),
|
| - is_one_byte_(subject->IsOneByteRepresentation()) {
|
| - // Require a non-zero initial size. Ensures that doubling the size to
|
| - // extend the array will work.
|
| - DCHECK(estimated_part_count > 0);
|
| - }
|
| -
|
| - static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from,
|
| - int to) {
|
| - DCHECK(from >= 0);
|
| - int length = to - from;
|
| - DCHECK(length > 0);
|
| - if (StringBuilderSubstringLength::is_valid(length) &&
|
| - StringBuilderSubstringPosition::is_valid(from)) {
|
| - int encoded_slice = StringBuilderSubstringLength::encode(length) |
|
| - StringBuilderSubstringPosition::encode(from);
|
| - builder->Add(Smi::FromInt(encoded_slice));
|
| - } else {
|
| - // Otherwise encode as two smis.
|
| - builder->Add(Smi::FromInt(-length));
|
| - builder->Add(Smi::FromInt(from));
|
| - }
|
| - }
|
| -
|
| -
|
| - void EnsureCapacity(int elements) { array_builder_.EnsureCapacity(elements); }
|
| -
|
| -
|
| - void AddSubjectSlice(int from, int to) {
|
| - AddSubjectSlice(&array_builder_, from, to);
|
| - IncrementCharacterCount(to - from);
|
| - }
|
| -
|
| -
|
| - void AddString(Handle<String> string) {
|
| - int length = string->length();
|
| - DCHECK(length > 0);
|
| - AddElement(*string);
|
| - if (!string->IsOneByteRepresentation()) {
|
| - is_one_byte_ = false;
|
| - }
|
| - IncrementCharacterCount(length);
|
| - }
|
| -
|
| -
|
| - MaybeHandle<String> ToString() {
|
| - Isolate* isolate = heap_->isolate();
|
| - if (array_builder_.length() == 0) {
|
| - return isolate->factory()->empty_string();
|
| - }
|
| -
|
| - Handle<String> joined_string;
|
| - if (is_one_byte_) {
|
| - Handle<SeqOneByteString> seq;
|
| - ASSIGN_RETURN_ON_EXCEPTION(
|
| - isolate, seq,
|
| - isolate->factory()->NewRawOneByteString(character_count_), String);
|
| -
|
| - DisallowHeapAllocation no_gc;
|
| - uint8_t* char_buffer = seq->GetChars();
|
| - StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(),
|
| - array_builder_.length());
|
| - joined_string = Handle<String>::cast(seq);
|
| - } else {
|
| - // Two-byte.
|
| - Handle<SeqTwoByteString> seq;
|
| - ASSIGN_RETURN_ON_EXCEPTION(
|
| - isolate, seq,
|
| - isolate->factory()->NewRawTwoByteString(character_count_), String);
|
| -
|
| - DisallowHeapAllocation no_gc;
|
| - uc16* char_buffer = seq->GetChars();
|
| - StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(),
|
| - array_builder_.length());
|
| - joined_string = Handle<String>::cast(seq);
|
| - }
|
| - return joined_string;
|
| - }
|
| -
|
| -
|
| - void IncrementCharacterCount(int by) {
|
| - if (character_count_ > String::kMaxLength - by) {
|
| - STATIC_ASSERT(String::kMaxLength < kMaxInt);
|
| - character_count_ = kMaxInt;
|
| - } else {
|
| - character_count_ += by;
|
| - }
|
| - }
|
| -
|
| - private:
|
| - void AddElement(Object* element) {
|
| - DCHECK(element->IsSmi() || element->IsString());
|
| - DCHECK(array_builder_.capacity() > array_builder_.length());
|
| - array_builder_.Add(element);
|
| - }
|
| -
|
| - Heap* heap_;
|
| - FixedArrayBuilder array_builder_;
|
| - Handle<String> subject_;
|
| - int character_count_;
|
| - bool is_one_byte_;
|
| -};
|
| -}
|
| -} // namespace v8::internal
|
| -
|
| -#endif // V8_RUNTIME_STRING_BUILDER_H_
|
|
|