[cleanup] Refactor CodeStubAssembler::NewConsString().
Remove the duplication of the allocation logic via the AllocateOneByteConsString and AllocateTwoByteConsString helpers, and instead just have a diamond to figure out the result map. This reduces code size of the StringAdd_CheckNone builtin and even seems to be beneficial performance wise. It seems to improve the performance on the `bench-dom-serialize.js` test by around 1% just doing this. Drive-by-fix: Remove the `flags` from CodeStubAssembler::StringAdd() and its helpers, since we no longer support pretenuring of string additions (for quite a while now). Bug: v8:8834, v8:8939 Change-Id: Ia23e02c974b5f572930fcd45be0643094ab2fa98 Doc: https://bit.ly/fast-string-concatenation-in-javascript Reviewed-on: https://chromium-review.googlesource.com/c/1498133 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/master@{#59993}
This commit is contained in:
parent
0edcb2239a
commit
8dd8bd56d1
@ -3307,52 +3307,9 @@ TNode<String> CodeStubAssembler::AllocateSlicedTwoByteString(
|
||||
offset);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateConsString(RootIndex map_root_index,
|
||||
TNode<Uint32T> length,
|
||||
TNode<String> first,
|
||||
TNode<String> second,
|
||||
AllocationFlags flags) {
|
||||
DCHECK(map_root_index == RootIndex::kConsOneByteStringMap ||
|
||||
map_root_index == RootIndex::kConsStringMap);
|
||||
Node* result = Allocate(ConsString::kSize, flags);
|
||||
DCHECK(RootsTable::IsImmortalImmovable(map_root_index));
|
||||
StoreMapNoWriteBarrier(result, map_root_index);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
bool const new_space = !(flags & kPretenured);
|
||||
if (new_space) {
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second,
|
||||
MachineRepresentation::kTagged);
|
||||
} else {
|
||||
StoreObjectField(result, ConsString::kFirstOffset, first);
|
||||
StoreObjectField(result, ConsString::kSecondOffset, second);
|
||||
}
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateOneByteConsString(
|
||||
TNode<Uint32T> length, TNode<String> first, TNode<String> second,
|
||||
AllocationFlags flags) {
|
||||
return AllocateConsString(RootIndex::kConsOneByteStringMap, length, first,
|
||||
second, flags);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateTwoByteConsString(
|
||||
TNode<Uint32T> length, TNode<String> first, TNode<String> second,
|
||||
AllocationFlags flags) {
|
||||
return AllocateConsString(RootIndex::kConsStringMap, length, first, second,
|
||||
flags);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::NewConsString(TNode<Uint32T> length,
|
||||
TNode<String> left,
|
||||
TNode<String> right,
|
||||
AllocationFlags flags) {
|
||||
TNode<String> CodeStubAssembler::AllocateConsString(TNode<Uint32T> length,
|
||||
TNode<String> left,
|
||||
TNode<String> right) {
|
||||
// Added string can be a cons string.
|
||||
Comment("Allocating ConsString");
|
||||
Node* left_instance_type = LoadInstanceType(left);
|
||||
@ -3377,8 +3334,8 @@ TNode<String> CodeStubAssembler::NewConsString(TNode<Uint32T> length,
|
||||
STATIC_ASSERT(kOneByteDataHintTag != 0);
|
||||
Label one_byte_map(this);
|
||||
Label two_byte_map(this);
|
||||
TVARIABLE(String, result);
|
||||
Label done(this, &result);
|
||||
TVARIABLE(Map, result_map);
|
||||
Label done(this, &result_map);
|
||||
GotoIf(IsSetWord32(anded_instance_types,
|
||||
kStringEncodingMask | kOneByteDataHintTag),
|
||||
&one_byte_map);
|
||||
@ -3389,18 +3346,30 @@ TNode<String> CodeStubAssembler::NewConsString(TNode<Uint32T> length,
|
||||
&two_byte_map, &one_byte_map);
|
||||
|
||||
BIND(&one_byte_map);
|
||||
Comment("One-byte ConsString");
|
||||
result = AllocateOneByteConsString(length, left, right, flags);
|
||||
Goto(&done);
|
||||
{
|
||||
Comment("One-byte ConsString");
|
||||
result_map = CAST(LoadRoot(RootIndex::kConsOneByteStringMap));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&two_byte_map);
|
||||
Comment("Two-byte ConsString");
|
||||
result = AllocateTwoByteConsString(length, left, right, flags);
|
||||
Goto(&done);
|
||||
{
|
||||
Comment("Two-byte ConsString");
|
||||
result_map = CAST(LoadRoot(RootIndex::kConsStringMap));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&done);
|
||||
|
||||
return result.value();
|
||||
Node* result = AllocateInNewSpace(ConsString::kSize);
|
||||
StoreMapNoWriteBarrier(result, result_map.value());
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, left);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, right);
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionary(
|
||||
@ -7197,8 +7166,7 @@ void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left,
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left,
|
||||
TNode<String> right,
|
||||
AllocationFlags flags) {
|
||||
TNode<String> right) {
|
||||
TVARIABLE(String, result);
|
||||
Label check_right(this), runtime(this, Label::kDeferred), cons(this),
|
||||
done(this, &result), done_native(this, &result);
|
||||
@ -7234,7 +7202,7 @@ TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left,
|
||||
&non_cons);
|
||||
|
||||
result =
|
||||
NewConsString(new_length, var_left.value(), var_right.value(), flags);
|
||||
AllocateConsString(new_length, var_left.value(), var_right.value());
|
||||
Goto(&done_native);
|
||||
|
||||
BIND(&non_cons);
|
||||
|
@ -1463,26 +1463,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<String> parent,
|
||||
TNode<Smi> offset);
|
||||
|
||||
// Allocate a one-byte ConsString with the given length, first and second
|
||||
// parts. |length| is expected to be tagged, and |first| and |second| are
|
||||
// expected to be one-byte strings.
|
||||
TNode<String> AllocateOneByteConsString(TNode<Uint32T> length,
|
||||
TNode<String> first,
|
||||
TNode<String> second,
|
||||
AllocationFlags flags = kNone);
|
||||
// Allocate a two-byte ConsString with the given length, first and second
|
||||
// parts. |length| is expected to be tagged, and |first| and |second| are
|
||||
// expected to be two-byte strings.
|
||||
TNode<String> AllocateTwoByteConsString(TNode<Uint32T> length,
|
||||
TNode<String> first,
|
||||
TNode<String> second,
|
||||
AllocationFlags flags = kNone);
|
||||
|
||||
// Allocate an appropriate one- or two-byte ConsString with the first and
|
||||
// second parts specified by |left| and |right|.
|
||||
TNode<String> NewConsString(TNode<Uint32T> length, TNode<String> left,
|
||||
TNode<String> right,
|
||||
AllocationFlags flags = kNone);
|
||||
TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left,
|
||||
TNode<String> right);
|
||||
|
||||
TNode<NameDictionary> AllocateNameDictionary(int at_least_space_for);
|
||||
TNode<NameDictionary> AllocateNameDictionary(
|
||||
@ -2285,7 +2269,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
// Return a new string object produced by concatenating |first| with |second|.
|
||||
TNode<String> StringAdd(Node* context, TNode<String> first,
|
||||
TNode<String> second, AllocationFlags flags = kNone);
|
||||
TNode<String> second);
|
||||
|
||||
// Check if |string| is an indirect (thin or flat cons) string type that can
|
||||
// be dereferenced by DerefIndirectString.
|
||||
@ -3426,10 +3410,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Uint32T> length,
|
||||
TNode<String> parent, TNode<Smi> offset);
|
||||
|
||||
TNode<String> AllocateConsString(RootIndex map_root_index,
|
||||
TNode<Uint32T> length, TNode<String> first,
|
||||
TNode<String> second, AllocationFlags flags);
|
||||
|
||||
// Allocate a MutableHeapNumber without initializing its value.
|
||||
TNode<MutableHeapNumber> AllocateMutableHeapNumber();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user