Commit 723b16b0 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Automatically grow ReplacementStringBuilder if needed

The ReplacementStringBuilder had a tricky API that required manually
growing the backing store if needed. This saves a few int additions
and comparisons, but is probably not worth the potential for errors.
This CL changes to automatic growth that is invisible to the user.

Bug: chromium:933521
Change-Id: I7d2404a48fe47ccce9af919910c06a9eca598120
Reviewed-on: https://chromium-review.googlesource.com/c/1477748Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59726}
parent 6956c02c
...@@ -652,16 +652,9 @@ V8_WARN_UNUSED_RESULT static Object StringReplaceGlobalRegExpWithString( ...@@ -652,16 +652,9 @@ V8_WARN_UNUSED_RESULT static Object StringReplaceGlobalRegExpWithString(
int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1; int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
ReplacementStringBuilder builder(isolate->heap(), subject, expected_parts); ReplacementStringBuilder builder(isolate->heap(), subject, expected_parts);
// Number of parts added by compiled replacement plus preceding
// string and possibly suffix after last match. It is possible for
// all components to use two elements when encoded as two smis.
const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
int prev = 0; int prev = 0;
do { do {
builder.EnsureCapacity(parts_added_per_loop);
int start = current_match[0]; int start = current_match[0];
int end = current_match[1]; int end = current_match[1];
...@@ -682,7 +675,6 @@ V8_WARN_UNUSED_RESULT static Object StringReplaceGlobalRegExpWithString( ...@@ -682,7 +675,6 @@ V8_WARN_UNUSED_RESULT static Object StringReplaceGlobalRegExpWithString(
if (global_cache.HasException()) return ReadOnlyRoots(isolate).exception(); if (global_cache.HasException()) return ReadOnlyRoots(isolate).exception();
if (prev < subject_length) { if (prev < subject_length) {
builder.EnsureCapacity(2);
builder.AddSubjectSlice(prev, subject_length); builder.AddSubjectSlice(prev, subject_length);
} }
......
...@@ -65,6 +65,7 @@ class ReplacementStringBuilder { ...@@ -65,6 +65,7 @@ class ReplacementStringBuilder {
ReplacementStringBuilder(Heap* heap, Handle<String> subject, ReplacementStringBuilder(Heap* heap, Handle<String> subject,
int estimated_part_count); int estimated_part_count);
// Caution: Callers must ensure the builder has enough capacity.
static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from, static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from,
int to) { int to) {
DCHECK_GE(from, 0); DCHECK_GE(from, 0);
...@@ -82,9 +83,8 @@ class ReplacementStringBuilder { ...@@ -82,9 +83,8 @@ class ReplacementStringBuilder {
} }
} }
void EnsureCapacity(int elements);
void AddSubjectSlice(int from, int to) { void AddSubjectSlice(int from, int to) {
EnsureCapacity(2); // Subject slices are encoded with up to two smis.
AddSubjectSlice(&array_builder_, from, to); AddSubjectSlice(&array_builder_, from, to);
IncrementCharacterCount(to - from); IncrementCharacterCount(to - from);
} }
...@@ -104,6 +104,7 @@ class ReplacementStringBuilder { ...@@ -104,6 +104,7 @@ class ReplacementStringBuilder {
private: private:
void AddElement(Object element); void AddElement(Object element);
void EnsureCapacity(int elements);
Heap* heap_; Heap* heap_;
FixedArrayBuilder array_builder_; FixedArrayBuilder array_builder_;
......
...@@ -226,6 +226,7 @@ MaybeHandle<String> ReplacementStringBuilder::ToString() { ...@@ -226,6 +226,7 @@ MaybeHandle<String> ReplacementStringBuilder::ToString() {
void ReplacementStringBuilder::AddElement(Object element) { void ReplacementStringBuilder::AddElement(Object element) {
DCHECK(element->IsSmi() || element->IsString()); DCHECK(element->IsSmi() || element->IsString());
DCHECK(array_builder_.capacity() > array_builder_.length()); DCHECK(array_builder_.capacity() > array_builder_.length());
EnsureCapacity(1);
array_builder_.Add(element); array_builder_.Add(element);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment