Commit 3168a963 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Revert "[csa] Refactor large-object handling in string allocation"

This reverts commit f6d73509.

Reason for revert: Perf regressions https://crbug.com/758126

Original change's description:
> [csa] Refactor large-object handling in string allocation
> 
> CSA::AllocateSeq{One,Two}ByteString used its own home-grown handling to
> allocate very large strings. This CL refactors both methods to use
> AllocationFlags::kAllowLargeObjectAllocation instead. Callers now need
> to specify explicitly if large-object allocation is possible or not.
> 
> Bug: chromium:636391
> Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
> Change-Id: I0b7ffb0b083f4e977cea42c500f8f2ee1c60519f
> Reviewed-on: https://chromium-review.googlesource.com/625738
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#47504}

TBR=cbruni@chromium.org,jgruber@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: chromium:636391
Change-Id: Iab88ce400f489a677df821d4053bd3678289ae2e
Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/637392Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47639}
parent 837b8016
......@@ -43,8 +43,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
// For short strings, do the conversion in CSA through the lookup table.
Node* const dst = AllocateSeqOneByteString(context, length, INTPTR_PARAMETERS,
kAllowLargeObjectAllocation);
Node* const dst = AllocateSeqOneByteString(context, length);
const int kMaxShortStringLength = 24; // Determined empirically.
GotoIf(IntPtrGreaterThan(length, IntPtrConstant(kMaxShortStringLength)),
......
......@@ -2924,8 +2924,7 @@ Node* RegExpBuiltinsAssembler::ReplaceSimpleStringFastPath(
Node* const second_part =
SubString(context, string, match_end, subject_end);
Node* const result = StringAdd(context, first_part, second_part,
kAllowLargeObjectAllocation);
Node* const result = StringAdd(context, first_part, second_part);
var_result.Bind(result);
Goto(&out);
}
......@@ -2938,10 +2937,8 @@ Node* RegExpBuiltinsAssembler::ReplaceSimpleStringFastPath(
Node* const third_part =
SubString(context, string, match_end, subject_end);
Node* result = StringAdd(context, first_part, second_part,
kAllowLargeObjectAllocation);
result =
StringAdd(context, result, third_part, kAllowLargeObjectAllocation);
Node* result = StringAdd(context, first_part, second_part);
result = StringAdd(context, result, third_part);
var_result.Bind(result);
Goto(&out);
......
......@@ -557,8 +557,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
{
Label two_byte(this);
// Assume that the resulting string contains only one-byte characters.
Node* one_byte_result = AllocateSeqOneByteString(
context, argc, INTPTR_PARAMETERS, kAllowLargeObjectAllocation);
Node* one_byte_result = AllocateSeqOneByteString(context, argc);
VARIABLE(max_index, MachineType::PointerRepresentation());
max_index.Bind(IntPtrConstant(0));
......@@ -592,8 +591,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
// At least one of the characters in the string requires a 16-bit
// representation. Allocate a SeqTwoByteString to hold the resulting
// string.
Node* two_byte_result = AllocateSeqTwoByteString(
context, argc, INTPTR_PARAMETERS, kAllowLargeObjectAllocation);
Node* two_byte_result = AllocateSeqTwoByteString(context, argc);
// Copy the characters that have already been put in the 8-bit string into
// their corresponding positions in the new 16-bit string.
......
......@@ -959,8 +959,6 @@ Node* CodeStubAssembler::AllocateInNewSpace(int size_in_bytes,
}
Node* CodeStubAssembler::Allocate(int size_in_bytes, AllocationFlags flags) {
DCHECK_IMPLIES(size_in_bytes > kMaxRegularHeapObjectSize,
(flags & kAllowLargeObjectAllocation) != 0);
return CodeStubAssembler::Allocate(IntPtrConstant(size_in_bytes), flags);
}
......@@ -1980,18 +1978,22 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
CSA_SLOW_ASSERT(this, MatchesParameterMode(length, mode));
VARIABLE(var_result, MachineRepresentation::kTagged);
Label if_lengthiszero(this), out(this);
// Compute the SeqOneByteString size and check if it fits into new space.
Label if_lengthiszero(this), if_sizeissmall(this),
if_notsizeissmall(this, Label::kDeferred), if_join(this);
GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
{
// Compute the SeqOneByteString size.
Node* raw_size = GetArrayAllocationSize(
length, UINT8_ELEMENTS, mode,
SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
Node* raw_size = GetArrayAllocationSize(
length, UINT8_ELEMENTS, mode,
SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
&if_sizeissmall, &if_notsizeissmall);
// Just allocate the SeqOneByteString.
Node* result = Allocate(size, flags);
BIND(&if_sizeissmall);
{
// Just allocate the SeqOneByteString in new space.
Node* result = AllocateInNewSpace(size, flags);
DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
......@@ -2001,16 +2003,25 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
IntPtrConstant(String::kEmptyHashField),
MachineType::PointerRepresentation());
var_result.Bind(result);
Goto(&out);
Goto(&if_join);
}
BIND(&if_notsizeissmall);
{
// We might need to allocate in large object space, go to the runtime.
Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
ParameterToTagged(length, mode));
var_result.Bind(result);
Goto(&if_join);
}
BIND(&if_lengthiszero);
{
var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
Goto(&out);
Goto(&if_join);
}
BIND(&out);
BIND(&if_join);
return var_result.value();
}
......@@ -2040,18 +2051,22 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
Comment("AllocateSeqTwoByteString");
VARIABLE(var_result, MachineRepresentation::kTagged);
Label if_lengthiszero(this), out(this);
// Compute the SeqTwoByteString size and check if it fits into new space.
Label if_lengthiszero(this), if_sizeissmall(this),
if_notsizeissmall(this, Label::kDeferred), if_join(this);
GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
{
// Compute the SeqTwoByteString size.
Node* raw_size = GetArrayAllocationSize(
length, UINT16_ELEMENTS, mode,
SeqTwoByteString::kHeaderSize + kObjectAlignmentMask);
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
Node* raw_size = GetArrayAllocationSize(
length, UINT16_ELEMENTS, mode,
SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
&if_sizeissmall, &if_notsizeissmall);
BIND(&if_sizeissmall);
{
// Just allocate the SeqTwoByteString in new space.
Node* result = Allocate(size, flags);
Node* result = AllocateInNewSpace(size, flags);
DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
StoreObjectFieldNoWriteBarrier(
......@@ -2062,16 +2077,26 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
IntPtrConstant(String::kEmptyHashField),
MachineType::PointerRepresentation());
var_result.Bind(result);
Goto(&out);
Goto(&if_join);
}
BIND(&if_notsizeissmall);
{
// We might need to allocate in large object space, go to the runtime.
Node* result =
CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
mode == SMI_PARAMETERS ? length : SmiFromWord(length));
var_result.Bind(result);
Goto(&if_join);
}
BIND(&if_lengthiszero);
{
var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
Goto(&out);
Goto(&if_join);
}
BIND(&out);
BIND(&if_join);
return var_result.value();
}
......@@ -3944,8 +3969,8 @@ Node* CodeStubAssembler::AllocAndCopyStringCharacters(Node* context, Node* from,
// The subject string is a sequential one-byte string.
BIND(&one_byte_sequential);
{
Node* result = AllocateSeqOneByteString(
context, character_count, SMI_PARAMETERS, kAllowLargeObjectAllocation);
Node* result =
AllocateSeqOneByteString(context, SmiToWord(character_count));
CopyStringCharacters(from, result, from_index, smi_zero, character_count,
String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING,
CodeStubAssembler::SMI_PARAMETERS);
......@@ -3957,8 +3982,8 @@ Node* CodeStubAssembler::AllocAndCopyStringCharacters(Node* context, Node* from,
// The subject string is a sequential two-byte string.
BIND(&two_byte_sequential);
{
Node* result = AllocateSeqTwoByteString(
context, character_count, SMI_PARAMETERS, kAllowLargeObjectAllocation);
Node* result =
AllocateSeqTwoByteString(context, SmiToWord(character_count));
CopyStringCharacters(from, result, from_index, smi_zero, character_count,
String::TWO_BYTE_ENCODING, String::TWO_BYTE_ENCODING,
CodeStubAssembler::SMI_PARAMETERS);
......@@ -4408,7 +4433,7 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
&two_byte);
// One-byte sequential string case
Node* new_string =
AllocateSeqOneByteString(context, new_length, SMI_PARAMETERS, flags);
AllocateSeqOneByteString(context, new_length, SMI_PARAMETERS);
CopyStringCharacters(var_left.value(), new_string, SmiConstant(0),
SmiConstant(0), left_length, String::ONE_BYTE_ENCODING,
String::ONE_BYTE_ENCODING, SMI_PARAMETERS);
......@@ -4422,7 +4447,7 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
{
// Two-byte sequential string case
new_string =
AllocateSeqTwoByteString(context, new_length, SMI_PARAMETERS, flags);
AllocateSeqTwoByteString(context, new_length, SMI_PARAMETERS);
CopyStringCharacters(var_left.value(), new_string, SmiConstant(0),
SmiConstant(0), left_length,
String::TWO_BYTE_ENCODING, String::TWO_BYTE_ENCODING,
......
......@@ -306,10 +306,9 @@ TF_STUB(StringAddStub, CodeStubAssembler) {
}
if ((flags & STRING_ADD_CHECK_BOTH) == 0) {
CodeStubAssembler::AllocationFlags allocation_flags =
CodeStubAssembler::AllocationFlag allocation_flags =
(pretenure_flag == TENURED) ? CodeStubAssembler::kPretenured
: CodeStubAssembler::kNone;
allocation_flags |= CodeStubAssembler::kAllowLargeObjectAllocation;
Return(StringAdd(context, left, right, allocation_flags));
} else {
Callable callable = CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE,
......
......@@ -320,7 +320,8 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(GenerateRandomNumbers) \
V(GlobalPrint) \
V(AllocateInNewSpace) \
V(AllocateInTargetSpace) \
V(AllocateSeqOneByteString) \
V(AllocateSeqTwoByteString) \
V(ObjectCreate) \
V(ObjectHasOwnProperty) \
V(ArrayIndexOf) \
......
......@@ -335,6 +335,28 @@ RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
return *isolate->factory()->NewFillerObject(size, double_align, space);
}
RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_SMI_ARG_CHECKED(length, 0);
if (length == 0) return isolate->heap()->empty_string();
Handle<SeqOneByteString> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, isolate->factory()->NewRawOneByteString(length));
return *result;
}
RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_SMI_ARG_CHECKED(length, 0);
if (length == 0) return isolate->heap()->empty_string();
Handle<SeqTwoByteString> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, isolate->factory()->NewRawTwoByteString(length));
return *result;
}
RUNTIME_FUNCTION(Runtime_IS_VAR) {
UNREACHABLE(); // implemented as macro in the parser
}
......
......@@ -280,6 +280,8 @@ namespace internal {
#define FOR_EACH_INTRINSIC_INTERNAL(F) \
F(AllocateInNewSpace, 1, 1) \
F(AllocateInTargetSpace, 2, 1) \
F(AllocateSeqOneByteString, 1, 1) \
F(AllocateSeqTwoByteString, 1, 1) \
F(CheckIsBootstrapping, 0, 1) \
F(CreateAsyncFromSyncIterator, 1, 1) \
F(CreateListFromArrayLike, 1, 1) \
......
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