Commit d8ce7cd3 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[CSA][cleanup] TNodified some CSA methods relating to Strings

This is a CL in a string of CLs that aims to TNodify CSA. In particular,
there were some loads that were done in AnyTagged instead of
TaggedPointer. TNode-ifying them brings improvement in pointer
compression since we are able to decompress using the Pointer
decompression.

Bug: v8:6949, v8:9396
Change-Id: I368d4f85348f3560a7f71bf66ebc7c4dd978a8dd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1752854Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63274}
parent 017a68c0
......@@ -33,9 +33,7 @@ class IntlBuiltinsAssembler : public CodeStubAssembler {
};
TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
Node* const string = Parameter(Descriptor::kString);
CSA_ASSERT(this, IsString(string));
TNode<String> const string = CAST(Parameter(Descriptor::kString));
Label call_c(this), return_string(this), runtime(this, Label::kDeferred);
......@@ -49,7 +47,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
state(), string, ToDirectStringAssembler::kDontUnpackSlicedStrings);
to_direct.TryToDirect(&runtime);
Node* const instance_type = to_direct.instance_type();
TNode<Int32T> const instance_type = to_direct.instance_type();
CSA_ASSERT(this,
Word32BinaryNot(IsIndirectStringInstanceType(instance_type)));
GotoIfNot(IsOneByteStringInstanceType(instance_type), &runtime);
......@@ -67,7 +65,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
VARIABLE(var_cursor, MachineType::PointerRepresentation(),
IntPtrConstant(0));
Node* const start_address = to_direct.PointerToData(&call_c);
TNode<RawPtrT> const start_address = to_direct.PointerToData(&call_c);
TNode<IntPtrT> const end_address =
Signed(IntPtrAdd(start_address, ChangeUint32ToWord(length)));
......@@ -105,7 +103,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
// String ConvertOneByteToLower(String src, String dst);
BIND(&call_c);
{
Node* const src = to_direct.string();
TNode<String> const src = to_direct.string();
Node* const function_addr =
ExternalConstant(ExternalReference::intl_convert_one_byte_to_lower());
......
......@@ -128,9 +128,10 @@ Node* StringBuiltinsAssembler::PointerToStringDataAtIndex(
return IntPtrAdd(string_data, offset_in_bytes);
}
void StringBuiltinsAssembler::GenerateStringEqual(Node* left, Node* right) {
VARIABLE(var_left, MachineRepresentation::kTagged, left);
VARIABLE(var_right, MachineRepresentation::kTagged, right);
void StringBuiltinsAssembler::GenerateStringEqual(TNode<String> left,
TNode<String> right) {
TVARIABLE(String, var_left, left);
TVARIABLE(String, var_right, right);
Label if_equal(this), if_notequal(this), if_indirect(this, Label::kDeferred),
restart(this, {&var_left, &var_right});
......@@ -142,11 +143,11 @@ void StringBuiltinsAssembler::GenerateStringEqual(Node* left, Node* right) {
Goto(&restart);
BIND(&restart);
Node* lhs = var_left.value();
Node* rhs = var_right.value();
TNode<String> lhs = var_left.value();
TNode<String> rhs = var_right.value();
Node* lhs_instance_type = LoadInstanceType(lhs);
Node* rhs_instance_type = LoadInstanceType(rhs);
TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs);
TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs);
StringEqual_Core(lhs, lhs_instance_type, rhs, rhs_instance_type, lhs_length,
&if_equal, &if_notequal, &if_indirect);
......@@ -324,11 +325,10 @@ TF_BUILTIN(SubString, StringBuiltinsAssembler) {
Return(SubString(string, SmiUntag(from), SmiUntag(to)));
}
void StringBuiltinsAssembler::GenerateStringRelationalComparison(Node* left,
Node* right,
Operation op) {
VARIABLE(var_left, MachineRepresentation::kTagged, left);
VARIABLE(var_right, MachineRepresentation::kTagged, right);
void StringBuiltinsAssembler::GenerateStringRelationalComparison(
TNode<String> left, TNode<String> right, Operation op) {
TVARIABLE(String, var_left, left);
TVARIABLE(String, var_right, right);
Variable* input_vars[2] = {&var_left, &var_right};
Label if_less(this), if_equal(this), if_greater(this);
......@@ -336,18 +336,18 @@ void StringBuiltinsAssembler::GenerateStringRelationalComparison(Node* left,
Goto(&restart);
BIND(&restart);
Node* lhs = var_left.value();
Node* rhs = var_right.value();
TNode<String> lhs = var_left.value();
TNode<String> rhs = var_right.value();
// Fast check to see if {lhs} and {rhs} refer to the same String object.
GotoIf(WordEqual(lhs, rhs), &if_equal);
// Load instance types of {lhs} and {rhs}.
Node* lhs_instance_type = LoadInstanceType(lhs);
Node* rhs_instance_type = LoadInstanceType(rhs);
TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs);
TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs);
// Combine the instance types into a single 16-bit value, so we can check
// both of them at once.
Node* both_instance_types = Word32Or(
TNode<Word32T> both_instance_types = Word32Or(
lhs_instance_type, Word32Shl(rhs_instance_type, Int32Constant(8)));
// Check that both {lhs} and {rhs} are flat one-byte strings.
......@@ -496,32 +496,32 @@ void StringBuiltinsAssembler::GenerateStringRelationalComparison(Node* left,
}
TF_BUILTIN(StringEqual, StringBuiltinsAssembler) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
TNode<String> left = CAST(Parameter(Descriptor::kLeft));
TNode<String> right = CAST(Parameter(Descriptor::kRight));
GenerateStringEqual(left, right);
}
TF_BUILTIN(StringLessThan, StringBuiltinsAssembler) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
TNode<String> left = CAST(Parameter(Descriptor::kLeft));
TNode<String> right = CAST(Parameter(Descriptor::kRight));
GenerateStringRelationalComparison(left, right, Operation::kLessThan);
}
TF_BUILTIN(StringLessThanOrEqual, StringBuiltinsAssembler) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
TNode<String> left = CAST(Parameter(Descriptor::kLeft));
TNode<String> right = CAST(Parameter(Descriptor::kRight));
GenerateStringRelationalComparison(left, right, Operation::kLessThanOrEqual);
}
TF_BUILTIN(StringGreaterThan, StringBuiltinsAssembler) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
TNode<String> left = CAST(Parameter(Descriptor::kLeft));
TNode<String> right = CAST(Parameter(Descriptor::kRight));
GenerateStringRelationalComparison(left, right, Operation::kGreaterThan);
}
TF_BUILTIN(StringGreaterThanOrEqual, StringBuiltinsAssembler) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
TNode<String> left = CAST(Parameter(Descriptor::kLeft));
TNode<String> right = CAST(Parameter(Descriptor::kRight));
GenerateStringRelationalComparison(left, right,
Operation::kGreaterThanOrEqual);
}
......@@ -682,12 +682,9 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
}
void StringBuiltinsAssembler::StringIndexOf(
Node* const subject_string, Node* const search_string, Node* const position,
const std::function<void(Node*)>& f_return) {
CSA_ASSERT(this, IsString(subject_string));
CSA_ASSERT(this, IsString(search_string));
CSA_ASSERT(this, TaggedIsSmi(position));
TNode<String> const subject_string, TNode<String> const search_string,
TNode<Smi> const position,
const std::function<void(TNode<Smi>)>& f_return) {
TNode<IntPtrT> const int_zero = IntPtrConstant(0);
TNode<IntPtrT> const search_length = LoadStringLengthAsWord(search_string);
TNode<IntPtrT> const subject_length = LoadStringLengthAsWord(subject_string);
......@@ -719,13 +716,13 @@ void StringBuiltinsAssembler::StringIndexOf(
search_to_direct.TryToDirect(&call_runtime_unchecked);
// Load pointers to string data.
Node* const subject_ptr =
TNode<RawPtrT> const subject_ptr =
subject_to_direct.PointerToData(&call_runtime_unchecked);
Node* const search_ptr =
TNode<RawPtrT> const search_ptr =
search_to_direct.PointerToData(&call_runtime_unchecked);
Node* const subject_offset = subject_to_direct.offset();
Node* const search_offset = search_to_direct.offset();
TNode<IntPtrT> const subject_offset = subject_to_direct.offset();
TNode<IntPtrT> const search_offset = search_to_direct.offset();
// Like String::IndexOf, the actual matching is done by the optimized
// SearchString method in string-search.h. Dispatch based on string instance
......@@ -844,9 +841,9 @@ void StringBuiltinsAssembler::StringIndexOf(
// Simplified version of the runtime call where the types of the arguments
// are already known due to type checks in this stub.
Comment("Call Runtime Unchecked");
Node* result =
CallRuntime(Runtime::kStringIndexOfUnchecked, NoContextConstant(),
subject_string, search_string, position);
TNode<Smi> result =
CAST(CallRuntime(Runtime::kStringIndexOfUnchecked, NoContextConstant(),
subject_string, search_string, position));
f_return(result);
}
}
......@@ -855,11 +852,11 @@ void StringBuiltinsAssembler::StringIndexOf(
// #sec-string.prototype.indexof
// Unchecked helper for builtins lowering.
TF_BUILTIN(StringIndexOf, StringBuiltinsAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* search_string = Parameter(Descriptor::kSearchString);
Node* position = Parameter(Descriptor::kPosition);
TNode<String> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<String> search_string = CAST(Parameter(Descriptor::kSearchString));
TNode<Smi> position = CAST(Parameter(Descriptor::kPosition));
StringIndexOf(receiver, search_string, position,
[this](Node* result) { this->Return(result); });
[this](TNode<Smi> result) { this->Return(result); });
}
// ES6 String.prototype.includes(searchString [, position])
......@@ -926,13 +923,15 @@ void StringIncludesIndexOfAssembler::Generate(SearchVariant variant,
GotoIfNot(IsString(receiver), &call_runtime);
GotoIfNot(IsString(search), &call_runtime);
StringIndexOf(receiver, search, position, [&](Node* result) {
CSA_ASSERT(this, TaggedIsSmi(result));
arguments.PopAndReturn((variant == kIndexOf)
? result
: SelectBooleanConstant(SmiGreaterThanOrEqual(
CAST(result), SmiConstant(0))));
});
StringIndexOf(CAST(receiver), CAST(search), CAST(position),
[&](TNode<Smi> result) {
if (variant == kIndexOf) {
arguments.PopAndReturn(result);
} else {
arguments.PopAndReturn(SelectBooleanConstant(
SmiGreaterThanOrEqual(result, SmiConstant(0))));
}
});
}
BIND(&call_runtime);
{
......@@ -1517,8 +1516,8 @@ TNode<JSArray> StringBuiltinsAssembler::StringToArray(
TNode<FixedArray> elements = CAST(AllocateFixedArray(
PACKED_ELEMENTS, length, AllocationFlag::kAllowLargeObjectAllocation));
// Don't allocate anything while {string_data} is live!
TNode<RawPtrT> string_data = UncheckedCast<RawPtrT>(
to_direct.PointerToData(&fill_thehole_and_call_runtime));
TNode<RawPtrT> string_data =
to_direct.PointerToData(&fill_thehole_and_call_runtime);
TNode<IntPtrT> string_data_offset = to_direct.offset();
TNode<Object> cache = LoadRoot(RootIndex::kSingleCharacterStringCache);
......@@ -1818,10 +1817,11 @@ void StringTrimAssembler::Generate(String::TrimMode mode,
ToDirectStringAssembler to_direct(state(), string);
to_direct.TryToDirect(&if_runtime);
Node* const string_data = to_direct.PointerToData(&if_runtime);
Node* const instance_type = to_direct.instance_type();
Node* const is_stringonebyte = IsOneByteStringInstanceType(instance_type);
Node* const string_data_offset = to_direct.offset();
TNode<RawPtrT> const string_data = to_direct.PointerToData(&if_runtime);
TNode<Int32T> const instance_type = to_direct.instance_type();
TNode<BoolT> const is_stringonebyte =
IsOneByteStringInstanceType(instance_type);
TNode<IntPtrT> const string_data_offset = to_direct.offset();
TVARIABLE(IntPtrT, var_start, IntPtrConstant(0));
TVARIABLE(IntPtrT, var_end, IntPtrSub(string_length, IntPtrConstant(1)));
......
......@@ -58,16 +58,17 @@ class StringBuiltinsAssembler : public CodeStubAssembler {
void ConvertAndBoundsCheckStartArgument(Node* context, Variable* var_start,
Node* start, Node* string_length);
void GenerateStringEqual(Node* left, Node* right);
void GenerateStringRelationalComparison(Node* left, Node* right,
Operation op);
void GenerateStringEqual(TNode<String> left, TNode<String> right);
void GenerateStringRelationalComparison(TNode<String> left,
TNode<String> right, Operation op);
using StringAtAccessor = std::function<TNode<Object>(
TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)>;
void StringIndexOf(Node* const subject_string, Node* const search_string,
Node* const position,
const std::function<void(Node*)>& f_return);
void StringIndexOf(TNode<String> const subject_string,
TNode<String> const search_string,
TNode<Smi> const position,
const std::function<void(TNode<Smi>)>& f_return);
TNode<Smi> IndexOfDollarChar(Node* const context, Node* const string);
......
......@@ -6886,10 +6886,9 @@ TNode<Int32T> CodeStubAssembler::StringCharCodeAt(SloppyTNode<String> string,
ToDirectStringAssembler to_direct(state(), string);
to_direct.TryToDirect(&if_runtime);
Node* const offset = IntPtrAdd(index, to_direct.offset());
Node* const instance_type = to_direct.instance_type();
Node* const string_data = to_direct.PointerToData(&if_runtime);
TNode<IntPtrT> const offset = IntPtrAdd(index, to_direct.offset());
TNode<Int32T> const instance_type = to_direct.instance_type();
TNode<RawPtrT> const string_data = to_direct.PointerToData(&if_runtime);
// Check if the {string} is a TwoByteSeqString or a OneByteSeqString.
Branch(IsOneByteStringInstanceType(instance_type), &if_stringisonebyte,
......@@ -7050,7 +7049,7 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
TNode<String> direct_string = to_direct.TryToDirect(&runtime);
TNode<IntPtrT> offset = IntPtrAdd(from, to_direct.offset());
Node* const instance_type = to_direct.instance_type();
TNode<Int32T> const instance_type = to_direct.instance_type();
// The subject string can only be external or sequential string of either
// encoding at this point.
......@@ -7108,7 +7107,8 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
// Handle external string.
BIND(&external_string);
{
Node* const fake_sequential_string = to_direct.PointerToString(&runtime);
TNode<RawPtrT> const fake_sequential_string =
to_direct.PointerToString(&runtime);
var_result = AllocAndCopyStringCharacters(
fake_sequential_string, instance_type, offset, substr_length);
......@@ -7163,21 +7163,13 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
}
ToDirectStringAssembler::ToDirectStringAssembler(
compiler::CodeAssemblerState* state, Node* string, Flags flags)
compiler::CodeAssemblerState* state, TNode<String> string, Flags flags)
: CodeStubAssembler(state),
var_string_(this, MachineRepresentation::kTagged, string),
var_instance_type_(this, MachineRepresentation::kWord32),
var_offset_(this, MachineType::PointerRepresentation()),
var_is_external_(this, MachineRepresentation::kWord32),
flags_(flags) {
CSA_ASSERT(this, TaggedIsNotSmi(string));
CSA_ASSERT(this, IsString(string));
var_string_.Bind(string);
var_offset_.Bind(IntPtrConstant(0));
var_instance_type_.Bind(LoadInstanceType(string));
var_is_external_.Bind(Int32Constant(0));
}
var_string_(string, this),
var_instance_type_(LoadInstanceType(string), this),
var_offset_(IntPtrConstant(0), this),
var_is_external_(Int32Constant(0), this),
flags_(flags) {}
TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
VariableList vars({&var_string_, &var_offset_, &var_instance_type_}, zone());
......@@ -7203,7 +7195,7 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
};
STATIC_ASSERT(arraysize(values) == arraysize(labels));
Node* const representation = Word32And(
TNode<Word32T> const representation = Word32And(
var_instance_type_.value(), Int32Constant(kStringRepresentationMask));
Switch(representation, if_bailout, values, labels, arraysize(values));
}
......@@ -7212,13 +7204,15 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
// Flat cons strings have an empty second part.
BIND(&if_iscons);
{
Node* const string = var_string_.value();
GotoIfNot(IsEmptyString(LoadObjectField(string, ConsString::kSecondOffset)),
TNode<String> const string = var_string_.value();
GotoIfNot(IsEmptyString(
LoadObjectField<String>(string, ConsString::kSecondOffset)),
if_bailout);
Node* const lhs = LoadObjectField(string, ConsString::kFirstOffset);
var_string_.Bind(lhs);
var_instance_type_.Bind(LoadInstanceType(lhs));
TNode<String> const lhs =
LoadObjectField<String>(string, ConsString::kFirstOffset);
var_string_ = lhs;
var_instance_type_ = LoadInstanceType(lhs);
Goto(&dispatch);
}
......@@ -7229,14 +7223,15 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
if (!FLAG_string_slices || (flags_ & kDontUnpackSlicedStrings)) {
Goto(if_bailout);
} else {
Node* const string = var_string_.value();
Node* const sliced_offset =
TNode<String> const string = var_string_.value();
TNode<IntPtrT> const sliced_offset =
LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
var_offset_.Bind(IntPtrAdd(var_offset_.value(), sliced_offset));
var_offset_ = IntPtrAdd(var_offset_.value(), sliced_offset);
Node* const parent = LoadObjectField(string, SlicedString::kParentOffset);
var_string_.Bind(parent);
var_instance_type_.Bind(LoadInstanceType(parent));
TNode<String> const parent =
LoadObjectField<String>(string, SlicedString::kParentOffset);
var_string_ = parent;
var_instance_type_ = LoadInstanceType(parent);
Goto(&dispatch);
}
......@@ -7245,24 +7240,24 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
// Thin string. Fetch the actual string.
BIND(&if_isthin);
{
Node* const string = var_string_.value();
Node* const actual_string =
LoadObjectField(string, ThinString::kActualOffset);
Node* const actual_instance_type = LoadInstanceType(actual_string);
TNode<String> const string = var_string_.value();
TNode<String> const actual_string =
LoadObjectField<String>(string, ThinString::kActualOffset);
TNode<Uint16T> const actual_instance_type = LoadInstanceType(actual_string);
var_string_.Bind(actual_string);
var_instance_type_.Bind(actual_instance_type);
var_string_ = actual_string;
var_instance_type_ = actual_instance_type;
Goto(&dispatch);
}
// External string.
BIND(&if_isexternal);
var_is_external_.Bind(Int32Constant(1));
var_is_external_ = Int32Constant(1);
Goto(&out);
BIND(&out);
return CAST(var_string_.value());
return var_string_.value();
}
TNode<RawPtrT> ToDirectStringAssembler::TryToSequential(
......@@ -7291,7 +7286,7 @@ TNode<RawPtrT> ToDirectStringAssembler::TryToSequential(
GotoIf(IsUncachedExternalStringInstanceType(var_instance_type_.value()),
if_bailout);
TNode<String> string = CAST(var_string_.value());
TNode<String> string = var_string_.value();
TNode<IntPtrT> result =
LoadObjectField<IntPtrT>(string, ExternalString::kResourceDataOffset);
if (ptr_kind == PTR_TO_STRING) {
......@@ -7306,35 +7301,33 @@ TNode<RawPtrT> ToDirectStringAssembler::TryToSequential(
return var_result.value();
}
void CodeStubAssembler::BranchIfCanDerefIndirectString(Node* string,
Node* instance_type,
Label* can_deref,
Label* cannot_deref) {
CSA_ASSERT(this, IsString(string));
void CodeStubAssembler::BranchIfCanDerefIndirectString(
TNode<String> string, TNode<Int32T> instance_type, Label* can_deref,
Label* cannot_deref) {
Node* representation =
Word32And(instance_type, Int32Constant(kStringRepresentationMask));
GotoIf(Word32Equal(representation, Int32Constant(kThinStringTag)), can_deref);
GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)),
cannot_deref);
// Cons string.
Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
TNode<String> rhs =
LoadObjectField<String>(string, ConsString::kSecondOffset);
GotoIf(IsEmptyString(rhs), can_deref);
Goto(cannot_deref);
}
Node* CodeStubAssembler::DerefIndirectString(TNode<String> string,
TNode<Int32T> instance_type,
Label* cannot_deref) {
TNode<String> CodeStubAssembler::DerefIndirectString(
TNode<String> string, TNode<Int32T> instance_type, Label* cannot_deref) {
Label deref(this);
BranchIfCanDerefIndirectString(string, instance_type, &deref, cannot_deref);
BIND(&deref);
STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) ==
static_cast<int>(ConsString::kFirstOffset));
return LoadObjectField(string, ThinString::kActualOffset);
return LoadObjectField<String>(string, ThinString::kActualOffset);
}
void CodeStubAssembler::DerefIndirectString(Variable* var_string,
Node* instance_type) {
void CodeStubAssembler::DerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type) {
#ifdef DEBUG
Label can_deref(this), cannot_deref(this);
BranchIfCanDerefIndirectString(var_string->value(), instance_type, &can_deref,
......@@ -7347,12 +7340,12 @@ void CodeStubAssembler::DerefIndirectString(Variable* var_string,
STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) ==
static_cast<int>(ConsString::kFirstOffset));
var_string->Bind(
LoadObjectField(var_string->value(), ThinString::kActualOffset));
*var_string =
LoadObjectField<String>(var_string->value(), ThinString::kActualOffset);
}
void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string,
Node* instance_type,
void CodeStubAssembler::MaybeDerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type,
Label* did_deref,
Label* cannot_deref) {
Label deref(this);
......@@ -7366,11 +7359,10 @@ void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string,
}
}
void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left,
Node* left_instance_type,
Variable* var_right,
Node* right_instance_type,
Label* did_something) {
void CodeStubAssembler::MaybeDerefIndirectStrings(
TVariable<String>* var_left, TNode<Int32T> left_instance_type,
TVariable<String>* var_right, TNode<Int32T> right_instance_type,
Label* did_something) {
Label did_nothing_left(this), did_something_left(this),
didnt_do_anything(this);
MaybeDerefIndirectString(var_left, left_instance_type, &did_something_left,
......@@ -7435,13 +7427,13 @@ TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left,
BIND(&non_cons);
Comment("Full string concatenate");
Node* left_instance_type = LoadInstanceType(var_left.value());
Node* right_instance_type = LoadInstanceType(var_right.value());
TNode<Int32T> left_instance_type = LoadInstanceType(var_left.value());
TNode<Int32T> right_instance_type = LoadInstanceType(var_right.value());
// Compute intersection and difference of instance types.
Node* ored_instance_types =
TNode<Word32T> ored_instance_types =
Word32Or(left_instance_type, right_instance_type);
Node* xored_instance_types =
TNode<Word32T> xored_instance_types =
Word32Xor(left_instance_type, right_instance_type);
// Check if both strings have the same encoding and both are sequential.
......@@ -8343,7 +8335,8 @@ void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
Goto(if_keyisunique);
BIND(&if_thinstring);
var_unique->Bind(LoadObjectField(key, ThinString::kActualOffset));
var_unique->Bind(
LoadObjectField<String>(CAST(key), ThinString::kActualOffset));
Goto(if_keyisunique);
BIND(&if_hascachedindex);
......@@ -14003,7 +13996,7 @@ void CodeStubAssembler::SetPropertyLength(TNode<Context> context,
TNode<String> CodeStubAssembler::TaggedToDirectString(TNode<Object> value,
Label* fail) {
ToDirectStringAssembler to_direct(state(), value);
ToDirectStringAssembler to_direct(state(), CAST(value));
to_direct.TryToDirect(fail);
to_direct.PointerToData(fail);
return CAST(value);
......
......@@ -2422,21 +2422,27 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Check if |string| is an indirect (thin or flat cons) string type that can
// be dereferenced by DerefIndirectString.
void BranchIfCanDerefIndirectString(Node* string, Node* instance_type,
void BranchIfCanDerefIndirectString(TNode<String> string,
TNode<Int32T> instance_type,
Label* can_deref, Label* cannot_deref);
// Unpack an indirect (thin or flat cons) string type.
void DerefIndirectString(Variable* var_string, Node* instance_type);
void DerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type);
// Check if |var_string| has an indirect (thin or flat cons) string type,
// and unpack it if so.
void MaybeDerefIndirectString(Variable* var_string, Node* instance_type,
Label* did_deref, Label* cannot_deref);
void MaybeDerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type, Label* did_deref,
Label* cannot_deref);
// Check if |var_left| or |var_right| has an indirect (thin or flat cons)
// string type, and unpack it/them if so. Fall through if nothing was done.
void MaybeDerefIndirectStrings(Variable* var_left, Node* left_instance_type,
Variable* var_right, Node* right_instance_type,
void MaybeDerefIndirectStrings(TVariable<String>* var_left,
TNode<Int32T> left_instance_type,
TVariable<String>* var_right,
TNode<Int32T> right_instance_type,
Label* did_something);
Node* DerefIndirectString(TNode<String> string, TNode<Int32T> instance_type,
Label* cannot_deref);
TNode<String> DerefIndirectString(TNode<String> string,
TNode<Int32T> instance_type,
Label* cannot_deref);
TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint);
......@@ -3705,8 +3711,8 @@ class ToDirectStringAssembler : public CodeStubAssembler {
};
using Flags = base::Flags<Flag>;
ToDirectStringAssembler(compiler::CodeAssemblerState* state, Node* string,
Flags flags = Flags());
ToDirectStringAssembler(compiler::CodeAssemblerState* state,
TNode<String> string, Flags flags = Flags());
// Converts flat cons, thin, and sliced strings and returns the direct
// string. The result can be either a sequential or external string.
......@@ -3726,20 +3732,18 @@ class ToDirectStringAssembler : public CodeStubAssembler {
return TryToSequential(PTR_TO_STRING, if_bailout);
}
Node* string() { return var_string_.value(); }
Node* instance_type() { return var_instance_type_.value(); }
TNode<IntPtrT> offset() {
return UncheckedCast<IntPtrT>(var_offset_.value());
}
Node* is_external() { return var_is_external_.value(); }
TNode<String> string() { return var_string_.value(); }
TNode<Int32T> instance_type() { return var_instance_type_.value(); }
TNode<IntPtrT> offset() { return var_offset_.value(); }
TNode<Word32T> is_external() { return var_is_external_.value(); }
private:
TNode<RawPtrT> TryToSequential(StringPointerKind ptr_kind, Label* if_bailout);
Variable var_string_;
Variable var_instance_type_;
Variable var_offset_;
Variable var_is_external_;
TVariable<String> var_string_;
TVariable<Int32T> var_instance_type_;
TVariable<IntPtrT> var_offset_;
TVariable<Word32T> var_is_external_;
const Flags flags_;
};
......
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