Revert "Reland "[objects] Change String::length field to uint32_t.""
This reverts commita03cec2c33
. Reason for revert: https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux64%20GC%20Stress%20-%20custom%20snapshot/21320 Original change's description: > Reland "[objects] Change String::length field to uint32_t." > > This is a reland of1f1eb625a8
, the > breakage on the GCStress bot seems to be unrelated (maybe flushed > out by this change). We decided to reland to figure out whether it's > a random flake or really triggered by this particular change. > > Original change's description: > > [objects] Change String::length field to uint32_t. > > > > This changes the Name::hash_field and Symbol::flags to uint32_t as > > well, so that both Symbols and Strings consume one fewer word on 64-bit > > architectures now. More importantly the access to String::length is > > always a 32-bit field load now, even with 31-bit Smis (i.e. on ARM or > > on 64-bit with pointer compression), so the access should be faster. > > > > Bug: v8:7065, v8:8171 > > Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng;luci.v8.try:v8_linux_noi18n_rel_ng > > Change-Id: I5523deb1f84ece91fa2fea775d50318bd1300493 > > Reviewed-on: https://chromium-review.googlesource.com/1221288 > > Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> > > Reviewed-by: Yang Guo <yangguo@chromium.org> > > Reviewed-by: Tobias Tebbi <tebbi@chromium.org> > > Reviewed-by: Igor Sheludko <ishell@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#55825} > > Bug: v8:7065, v8:8171 > Tbr: tebbi@chromium.org, yangguo@chromium.org, ishell@chromium.org, ulan@chromium.org > Change-Id: I2be24ac018591c04c826e7e8db82e007b738d156 > Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng;luci.v8.try:v8_linux_noi18n_rel_ng > Reviewed-on: https://chromium-review.googlesource.com/1222308 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> > Cr-Commit-Position: refs/heads/master@{#55838} TBR=yangguo@chromium.org,tebbi@chromium.org,ishell@chromium.org,bmeurer@chromium.org Change-Id: Ic741c3d407d4257a8c86b3082b9a19e33dc89215 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: v8:7065, v8:8171 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng;luci.v8.try:v8_linux_noi18n_rel_ng Reviewed-on: https://chromium-review.googlesource.com/1222368 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#55839}
This commit is contained in:
parent
a03cec2c33
commit
350dfb622b
@ -129,8 +129,7 @@ class Internals {
|
||||
// the implementation of v8.
|
||||
static const int kHeapObjectMapOffset = 0;
|
||||
static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize;
|
||||
static const int kStringResourceOffset =
|
||||
1 * kApiPointerSize + 2 * kApiIntSize;
|
||||
static const int kStringResourceOffset = 3 * kApiPointerSize;
|
||||
|
||||
static const int kOddballKindOffset = 4 * kApiPointerSize + kApiDoubleSize;
|
||||
static const int kForeignAddressOffset = kApiPointerSize;
|
||||
|
@ -71,7 +71,7 @@ bool Accessors::IsJSObjectFieldAccessor(Isolate* isolate, Handle<Map> map,
|
||||
default:
|
||||
if (map->instance_type() < FIRST_NONSTRING_TYPE) {
|
||||
return CheckForName(isolate, name, isolate->factory()->length_string(),
|
||||
String::kLengthOffset, FieldIndex::kWord32, index);
|
||||
String::kLengthOffset, FieldIndex::kTagged, index);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -41,8 +41,8 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
|
||||
Label call_c(this), return_string(this), runtime(this, Label::kDeferred);
|
||||
|
||||
// Early exit on empty strings.
|
||||
TNode<Uint32T> const length = LoadStringLengthAsWord32(string);
|
||||
GotoIf(Word32Equal(length, Uint32Constant(0)), &return_string);
|
||||
TNode<Smi> const length = LoadStringLengthAsSmi(string);
|
||||
GotoIf(SmiEqual(length, SmiConstant(0)), &return_string);
|
||||
|
||||
// Unpack strings if possible, and bail to runtime unless we get a one-byte
|
||||
// flat string.
|
||||
@ -60,8 +60,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
|
||||
Node* const dst = AllocateSeqOneByteString(context, length);
|
||||
|
||||
const int kMaxShortStringLength = 24; // Determined empirically.
|
||||
GotoIf(Uint32GreaterThan(length, Uint32Constant(kMaxShortStringLength)),
|
||||
&call_c);
|
||||
GotoIf(SmiGreaterThan(length, SmiConstant(kMaxShortStringLength)), &call_c);
|
||||
|
||||
{
|
||||
Node* const dst_ptr = PointerToSeqStringData(dst);
|
||||
@ -70,7 +69,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
|
||||
|
||||
Node* const start_address = to_direct.PointerToData(&call_c);
|
||||
TNode<IntPtrT> const end_address =
|
||||
Signed(IntPtrAdd(start_address, ChangeUint32ToWord(length)));
|
||||
Signed(IntPtrAdd(start_address, SmiUntag(length)));
|
||||
|
||||
Node* const to_lower_table_addr =
|
||||
ExternalConstant(ExternalReference::intl_to_latin1_lower_table());
|
||||
|
@ -536,9 +536,8 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context,
|
||||
GotoIf(IsJSReceiverInstanceType(from_instance_type), &cont);
|
||||
GotoIfNot(IsStringInstanceType(from_instance_type), &done);
|
||||
{
|
||||
Branch(
|
||||
Word32Equal(LoadStringLengthAsWord32(CAST(from)), Int32Constant(0)),
|
||||
&done, slow);
|
||||
Branch(SmiEqual(LoadStringLengthAsSmi(CAST(from)), SmiConstant(0)), &done,
|
||||
slow);
|
||||
}
|
||||
BIND(&cont);
|
||||
}
|
||||
|
@ -1103,7 +1103,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
|
||||
Isolate* isolate = this->isolate();
|
||||
|
||||
TNode<IntPtrT> const int_one = IntPtrConstant(1);
|
||||
TVARIABLE(Uint32T, var_length, Uint32Constant(0));
|
||||
TVARIABLE(Smi, var_length, SmiZero());
|
||||
TVARIABLE(IntPtrT, var_flags);
|
||||
|
||||
// First, count the number of characters we will need and check which flags
|
||||
@ -1115,13 +1115,13 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
|
||||
Node* const flags_smi = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
|
||||
var_flags = SmiUntag(flags_smi);
|
||||
|
||||
#define CASE_FOR_FLAG(FLAG) \
|
||||
do { \
|
||||
Label next(this); \
|
||||
GotoIfNot(IsSetWord(var_flags.value(), FLAG), &next); \
|
||||
var_length = Uint32Add(var_length.value(), Uint32Constant(1)); \
|
||||
Goto(&next); \
|
||||
BIND(&next); \
|
||||
#define CASE_FOR_FLAG(FLAG) \
|
||||
do { \
|
||||
Label next(this); \
|
||||
GotoIfNot(IsSetWord(var_flags.value(), FLAG), &next); \
|
||||
var_length = SmiAdd(var_length.value(), SmiConstant(1)); \
|
||||
Goto(&next); \
|
||||
BIND(&next); \
|
||||
} while (false)
|
||||
|
||||
CASE_FOR_FLAG(JSRegExp::kGlobal);
|
||||
@ -1145,7 +1145,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
|
||||
Label if_isflagset(this); \
|
||||
BranchIfToBooleanIsTrue(flag, &if_isflagset, &next); \
|
||||
BIND(&if_isflagset); \
|
||||
var_length = Uint32Add(var_length.value(), Uint32Constant(1)); \
|
||||
var_length = SmiAdd(var_length.value(), SmiConstant(1)); \
|
||||
var_flags = Signed(WordOr(var_flags.value(), IntPtrConstant(FLAG))); \
|
||||
Goto(&next); \
|
||||
BIND(&next); \
|
||||
|
@ -585,9 +585,8 @@ TF_BUILTIN(StringGreaterThanOrEqual, StringBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(StringCharAt, StringBuiltinsAssembler) {
|
||||
TNode<String> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
TNode<IntPtrT> position =
|
||||
UncheckedCast<IntPtrT>(Parameter(Descriptor::kPosition));
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* position = Parameter(Descriptor::kPosition);
|
||||
|
||||
// Load the character code at the {position} from the {receiver}.
|
||||
TNode<Int32T> code = StringCharCodeAt(receiver, position);
|
||||
@ -638,6 +637,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc));
|
||||
TNode<Smi> smi_argc = SmiTag(arguments.GetLength(INTPTR_PARAMETERS));
|
||||
// Check if we have exactly one argument (plus the implicit receiver), i.e.
|
||||
// if the parent frame is not an arguments adaptor frame.
|
||||
Label if_oneargument(this), if_notoneargument(this);
|
||||
@ -662,7 +662,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, Unsigned(argc));
|
||||
Node* one_byte_result = AllocateSeqOneByteString(context, smi_argc);
|
||||
|
||||
TVARIABLE(IntPtrT, var_max_index);
|
||||
var_max_index = IntPtrConstant(0);
|
||||
@ -696,7 +696,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, Unsigned(argc));
|
||||
Node* two_byte_result = AllocateSeqTwoByteString(context, smi_argc);
|
||||
|
||||
// Copy the characters that have already been put in the 8-bit string into
|
||||
// their corresponding positions in the new 16-bit string.
|
||||
@ -1227,6 +1227,8 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
|
||||
TNode<Object> count = CAST(Parameter(Descriptor::kCount));
|
||||
Node* const string =
|
||||
ToThisString(context, receiver, "String.prototype.repeat");
|
||||
Node* const is_stringempty =
|
||||
SmiEqual(LoadStringLengthAsSmi(string), SmiConstant(0));
|
||||
|
||||
VARIABLE(
|
||||
var_count, MachineRepresentation::kTagged,
|
||||
@ -1244,8 +1246,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
|
||||
TNode<Smi> smi_count = CAST(var_count.value());
|
||||
GotoIf(SmiLessThan(smi_count, SmiConstant(0)), &invalid_count);
|
||||
GotoIf(SmiEqual(smi_count, SmiConstant(0)), &return_emptystring);
|
||||
GotoIf(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)),
|
||||
&return_emptystring);
|
||||
GotoIf(is_stringempty, &return_emptystring);
|
||||
GotoIf(SmiGreaterThan(smi_count, SmiConstant(String::kMaxLength)),
|
||||
&invalid_string_length);
|
||||
Return(CallBuiltin(Builtins::kStringRepeat, context, string, smi_count));
|
||||
@ -1263,8 +1264,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
|
||||
&invalid_count);
|
||||
GotoIf(Float64LessThan(number_value, Float64Constant(0.0)),
|
||||
&invalid_count);
|
||||
Branch(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)),
|
||||
&return_emptystring, &invalid_string_length);
|
||||
Branch(is_stringempty, &return_emptystring, &invalid_string_length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1367,16 +1367,16 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
|
||||
TNode<String> const subject_string = ToString_Inline(context, receiver);
|
||||
TNode<String> const search_string = ToString_Inline(context, search);
|
||||
|
||||
TNode<IntPtrT> const subject_length = LoadStringLengthAsWord(subject_string);
|
||||
TNode<IntPtrT> const search_length = LoadStringLengthAsWord(search_string);
|
||||
TNode<Smi> const subject_length = LoadStringLengthAsSmi(subject_string);
|
||||
TNode<Smi> const search_length = LoadStringLengthAsSmi(search_string);
|
||||
|
||||
// Fast-path single-char {search}, long cons {receiver}, and simple string
|
||||
// {replace}.
|
||||
{
|
||||
Label next(this);
|
||||
|
||||
GotoIfNot(WordEqual(search_length, IntPtrConstant(1)), &next);
|
||||
GotoIfNot(IntPtrGreaterThan(subject_length, IntPtrConstant(0xFF)), &next);
|
||||
GotoIfNot(SmiEqual(search_length, SmiConstant(1)), &next);
|
||||
GotoIfNot(SmiGreaterThan(subject_length, SmiConstant(0xFF)), &next);
|
||||
GotoIf(TaggedIsSmi(replace), &next);
|
||||
GotoIfNot(IsString(replace), &next);
|
||||
|
||||
@ -1428,8 +1428,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
|
||||
BIND(&next);
|
||||
}
|
||||
|
||||
TNode<Smi> const match_end_index =
|
||||
SmiAdd(match_start_index, SmiFromIntPtr(search_length));
|
||||
TNode<Smi> const match_end_index = SmiAdd(match_start_index, search_length);
|
||||
|
||||
Callable stringadd_callable =
|
||||
CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
|
||||
@ -1484,7 +1483,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
|
||||
{
|
||||
Node* const suffix =
|
||||
CallBuiltin(Builtins::kStringSubstring, context, subject_string,
|
||||
SmiUntag(match_end_index), subject_length);
|
||||
SmiUntag(match_end_index), SmiUntag(subject_length));
|
||||
Node* const result =
|
||||
CallStub(stringadd_callable, context, var_result.value(), suffix);
|
||||
Return(result);
|
||||
|
@ -1829,20 +1829,16 @@ TNode<Uint32T> CodeStubAssembler::LoadNameHash(SloppyTNode<Name> name,
|
||||
return Unsigned(Word32Shr(hash_field, Int32Constant(Name::kHashShift)));
|
||||
}
|
||||
|
||||
TNode<Smi> CodeStubAssembler::LoadStringLengthAsSmi(
|
||||
SloppyTNode<String> string) {
|
||||
return SmiFromIntPtr(LoadStringLengthAsWord(string));
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeStubAssembler::LoadStringLengthAsWord(
|
||||
SloppyTNode<String> string) {
|
||||
return Signed(ChangeUint32ToWord(LoadStringLengthAsWord32(string)));
|
||||
SloppyTNode<String> object) {
|
||||
return SmiUntag(LoadStringLengthAsSmi(object));
|
||||
}
|
||||
|
||||
TNode<Uint32T> CodeStubAssembler::LoadStringLengthAsWord32(
|
||||
SloppyTNode<String> string) {
|
||||
CSA_ASSERT(this, IsString(string));
|
||||
return LoadObjectField<Uint32T>(string, String::kLengthOffset);
|
||||
TNode<Smi> CodeStubAssembler::LoadStringLengthAsSmi(
|
||||
SloppyTNode<String> object) {
|
||||
CSA_ASSERT(this, IsString(object));
|
||||
return CAST(LoadObjectField(object, String::kLengthOffset,
|
||||
MachineType::TaggedPointer()));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::PointerToSeqStringData(Node* seq_string) {
|
||||
@ -3162,7 +3158,7 @@ TNode<UintPtrT> CodeStubAssembler::LoadBigIntDigit(TNode<BigInt> bigint,
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
uint32_t length, AllocationFlags flags) {
|
||||
int length, AllocationFlags flags) {
|
||||
Comment("AllocateSeqOneByteString");
|
||||
if (length == 0) {
|
||||
return CAST(LoadRoot(Heap::kempty_stringRootIndex));
|
||||
@ -3171,11 +3167,11 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
|
||||
StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
|
||||
Uint32Constant(length),
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
SmiConstant(length),
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
@ -3186,7 +3182,7 @@ TNode<BoolT> CodeStubAssembler::IsZeroOrContext(SloppyTNode<Object> object) {
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
Node* context, TNode<Uint32T> length, AllocationFlags flags) {
|
||||
Node* context, TNode<Smi> length, AllocationFlags flags) {
|
||||
Comment("AllocateSeqOneByteString");
|
||||
CSA_SLOW_ASSERT(this, IsZeroOrContext(context));
|
||||
VARIABLE(var_result, MachineRepresentation::kTagged);
|
||||
@ -3194,10 +3190,10 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
// 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(Word32Equal(length, Uint32Constant(0)), &if_lengthiszero);
|
||||
GotoIf(SmiEqual(length, SmiConstant(0)), &if_lengthiszero);
|
||||
|
||||
Node* raw_size = GetArrayAllocationSize(
|
||||
Signed(ChangeUint32ToWord(length)), UINT8_ELEMENTS, INTPTR_PARAMETERS,
|
||||
SmiUntag(length), UINT8_ELEMENTS, INTPTR_PARAMETERS,
|
||||
SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
|
||||
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
|
||||
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
|
||||
@ -3210,10 +3206,10 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
|
||||
StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
|
||||
length, MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
length, MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
var_result.Bind(result);
|
||||
Goto(&if_join);
|
||||
}
|
||||
@ -3221,8 +3217,8 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
BIND(&if_notsizeissmall);
|
||||
{
|
||||
// We might need to allocate in large object space, go to the runtime.
|
||||
Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
|
||||
ChangeUint32ToTagged(length));
|
||||
Node* result =
|
||||
CallRuntime(Runtime::kAllocateSeqOneByteString, context, length);
|
||||
var_result.Bind(result);
|
||||
Goto(&if_join);
|
||||
}
|
||||
@ -3238,7 +3234,7 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
uint32_t length, AllocationFlags flags) {
|
||||
int length, AllocationFlags flags) {
|
||||
Comment("AllocateSeqTwoByteString");
|
||||
if (length == 0) {
|
||||
return CAST(LoadRoot(Heap::kempty_stringRootIndex));
|
||||
@ -3247,16 +3243,16 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
|
||||
StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
|
||||
Uint32Constant(length),
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
SmiConstant(Smi::FromInt(length)),
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
Node* context, TNode<Uint32T> length, AllocationFlags flags) {
|
||||
Node* context, TNode<Smi> length, AllocationFlags flags) {
|
||||
CSA_SLOW_ASSERT(this, IsZeroOrContext(context));
|
||||
Comment("AllocateSeqTwoByteString");
|
||||
VARIABLE(var_result, MachineRepresentation::kTagged);
|
||||
@ -3264,10 +3260,10 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
// 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(Word32Equal(length, Uint32Constant(0)), &if_lengthiszero);
|
||||
GotoIf(SmiEqual(length, SmiConstant(0)), &if_lengthiszero);
|
||||
|
||||
Node* raw_size = GetArrayAllocationSize(
|
||||
Signed(ChangeUint32ToWord(length)), UINT16_ELEMENTS, INTPTR_PARAMETERS,
|
||||
SmiUntag(length), UINT16_ELEMENTS, INTPTR_PARAMETERS,
|
||||
SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
|
||||
Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
|
||||
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
|
||||
@ -3280,10 +3276,10 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
|
||||
StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
|
||||
length, MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
length, MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
var_result.Bind(result);
|
||||
Goto(&if_join);
|
||||
}
|
||||
@ -3291,8 +3287,8 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
BIND(&if_notsizeissmall);
|
||||
{
|
||||
// We might need to allocate in large object space, go to the runtime.
|
||||
Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
|
||||
ChangeUint32ToTagged(length));
|
||||
Node* result =
|
||||
CallRuntime(Runtime::kAllocateSeqTwoByteString, context, length);
|
||||
var_result.Bind(result);
|
||||
Goto(&if_join);
|
||||
}
|
||||
@ -3308,18 +3304,18 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSlicedString(
|
||||
Heap::RootListIndex map_root_index, TNode<Uint32T> length,
|
||||
TNode<String> parent, TNode<Smi> offset) {
|
||||
Heap::RootListIndex map_root_index, TNode<Smi> length, TNode<String> parent,
|
||||
TNode<Smi> offset) {
|
||||
DCHECK(map_root_index == Heap::kSlicedOneByteStringMapRootIndex ||
|
||||
map_root_index == Heap::kSlicedStringMapRootIndex);
|
||||
Node* result = Allocate(SlicedString::kSize);
|
||||
DCHECK(Heap::RootIsImmortalImmovable(map_root_index));
|
||||
StoreMapNoWriteBarrier(result, map_root_index);
|
||||
StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length,
|
||||
MachineRepresentation::kWord32);
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent,
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset,
|
||||
@ -3328,30 +3324,30 @@ TNode<String> CodeStubAssembler::AllocateSlicedString(
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSlicedOneByteString(
|
||||
TNode<Uint32T> length, TNode<String> parent, TNode<Smi> offset) {
|
||||
TNode<Smi> length, TNode<String> parent, TNode<Smi> offset) {
|
||||
return AllocateSlicedString(Heap::kSlicedOneByteStringMapRootIndex, length,
|
||||
parent, offset);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateSlicedTwoByteString(
|
||||
TNode<Uint32T> length, TNode<String> parent, TNode<Smi> offset) {
|
||||
TNode<Smi> length, TNode<String> parent, TNode<Smi> offset) {
|
||||
return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent,
|
||||
offset);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateConsString(
|
||||
Heap::RootListIndex map_root_index, TNode<Uint32T> length,
|
||||
TNode<String> first, TNode<String> second, AllocationFlags flags) {
|
||||
Heap::RootListIndex map_root_index, TNode<Smi> length, TNode<String> first,
|
||||
TNode<String> second, AllocationFlags flags) {
|
||||
DCHECK(map_root_index == Heap::kConsOneByteStringMapRootIndex ||
|
||||
map_root_index == Heap::kConsStringMapRootIndex);
|
||||
Node* result = Allocate(ConsString::kSize, flags);
|
||||
DCHECK(Heap::RootIsImmortalImmovable(map_root_index));
|
||||
StoreMapNoWriteBarrier(result, map_root_index);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
|
||||
MachineRepresentation::kWord32);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
|
||||
Int32Constant(String::kEmptyHashField),
|
||||
MachineRepresentation::kWord32);
|
||||
MachineRepresentation::kTagged);
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldSlot,
|
||||
IntPtrConstant(String::kEmptyHashField),
|
||||
MachineType::PointerRepresentation());
|
||||
bool const new_space = !(flags & kPretenured);
|
||||
if (new_space) {
|
||||
StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
|
||||
@ -3366,20 +3362,20 @@ TNode<String> CodeStubAssembler::AllocateConsString(
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateOneByteConsString(
|
||||
TNode<Uint32T> length, TNode<String> first, TNode<String> second,
|
||||
TNode<Smi> length, TNode<String> first, TNode<String> second,
|
||||
AllocationFlags flags) {
|
||||
return AllocateConsString(Heap::kConsOneByteStringMapRootIndex, length, first,
|
||||
second, flags);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::AllocateTwoByteConsString(
|
||||
TNode<Uint32T> length, TNode<String> first, TNode<String> second,
|
||||
TNode<Smi> length, TNode<String> first, TNode<String> second,
|
||||
AllocationFlags flags) {
|
||||
return AllocateConsString(Heap::kConsStringMapRootIndex, length, first,
|
||||
second, flags);
|
||||
}
|
||||
|
||||
TNode<String> CodeStubAssembler::NewConsString(TNode<Uint32T> length,
|
||||
TNode<String> CodeStubAssembler::NewConsString(TNode<Smi> length,
|
||||
TNode<String> left,
|
||||
TNode<String> right,
|
||||
AllocationFlags flags) {
|
||||
@ -5831,14 +5827,15 @@ TNode<BoolT> CodeStubAssembler::IsPrimitiveInstanceType(
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsPrivateSymbol(
|
||||
SloppyTNode<HeapObject> object) {
|
||||
return Select<BoolT>(IsSymbol(object),
|
||||
[=] {
|
||||
TNode<Symbol> symbol = CAST(object);
|
||||
TNode<Uint32T> flags = LoadObjectField<Uint32T>(
|
||||
symbol, Symbol::kFlagsOffset);
|
||||
return IsSetWord32<Symbol::IsPrivateBit>(flags);
|
||||
},
|
||||
[=] { return Int32FalseConstant(); });
|
||||
return Select<BoolT>(
|
||||
IsSymbol(object),
|
||||
[=] {
|
||||
TNode<Symbol> symbol = CAST(object);
|
||||
TNode<Int32T> flags =
|
||||
SmiToInt32(LoadObjectField<Smi>(symbol, Symbol::kFlagsOffset));
|
||||
return IsSetWord32(flags, 1 << Symbol::kPrivateBit);
|
||||
},
|
||||
[=] { return Int32FalseConstant(); });
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsNativeContext(
|
||||
@ -6183,7 +6180,7 @@ TNode<String> CodeStubAssembler::StringFromSingleCharCode(TNode<Int32T> code) {
|
||||
// 0 <= |from_index| <= |from_index| + |character_count| < from_string.length.
|
||||
TNode<String> CodeStubAssembler::AllocAndCopyStringCharacters(
|
||||
Node* from, Node* from_instance_type, TNode<IntPtrT> from_index,
|
||||
TNode<IntPtrT> character_count) {
|
||||
TNode<Smi> character_count) {
|
||||
Label end(this), one_byte_sequential(this), two_byte_sequential(this);
|
||||
TVARIABLE(String, var_result);
|
||||
|
||||
@ -6193,10 +6190,10 @@ TNode<String> CodeStubAssembler::AllocAndCopyStringCharacters(
|
||||
// The subject string is a sequential one-byte string.
|
||||
BIND(&one_byte_sequential);
|
||||
{
|
||||
TNode<String> result = AllocateSeqOneByteString(
|
||||
NoContextConstant(), Unsigned(TruncateIntPtrToInt32(character_count)));
|
||||
TNode<String> result =
|
||||
AllocateSeqOneByteString(NoContextConstant(), character_count);
|
||||
CopyStringCharacters(from, result, from_index, IntPtrConstant(0),
|
||||
character_count, String::ONE_BYTE_ENCODING,
|
||||
SmiUntag(character_count), String::ONE_BYTE_ENCODING,
|
||||
String::ONE_BYTE_ENCODING);
|
||||
var_result = result;
|
||||
Goto(&end);
|
||||
@ -6205,10 +6202,10 @@ TNode<String> CodeStubAssembler::AllocAndCopyStringCharacters(
|
||||
// The subject string is a sequential two-byte string.
|
||||
BIND(&two_byte_sequential);
|
||||
{
|
||||
TNode<String> result = AllocateSeqTwoByteString(
|
||||
NoContextConstant(), Unsigned(TruncateIntPtrToInt32(character_count)));
|
||||
TNode<String> result =
|
||||
AllocateSeqTwoByteString(NoContextConstant(), character_count);
|
||||
CopyStringCharacters(from, result, from_index, IntPtrConstant(0),
|
||||
character_count, String::TWO_BYTE_ENCODING,
|
||||
SmiUntag(character_count), String::TWO_BYTE_ENCODING,
|
||||
String::TWO_BYTE_ENCODING);
|
||||
var_result = result;
|
||||
Goto(&end);
|
||||
@ -6271,17 +6268,15 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
|
||||
|
||||
BIND(&one_byte_slice);
|
||||
{
|
||||
var_result = AllocateSlicedOneByteString(
|
||||
Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string,
|
||||
SmiTag(offset));
|
||||
var_result = AllocateSlicedOneByteString(SmiTag(substr_length),
|
||||
direct_string, SmiTag(offset));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
BIND(&two_byte_slice);
|
||||
{
|
||||
var_result = AllocateSlicedTwoByteString(
|
||||
Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string,
|
||||
SmiTag(offset));
|
||||
var_result = AllocateSlicedTwoByteString(SmiTag(substr_length),
|
||||
direct_string, SmiTag(offset));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
@ -6293,7 +6288,7 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
|
||||
GotoIf(to_direct.is_external(), &external_string);
|
||||
|
||||
var_result = AllocAndCopyStringCharacters(direct_string, instance_type,
|
||||
offset, substr_length);
|
||||
offset, SmiTag(substr_length));
|
||||
|
||||
Counters* counters = isolate()->counters();
|
||||
IncrementCounter(counters->sub_string_native(), 1);
|
||||
@ -6307,7 +6302,7 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
|
||||
Node* const fake_sequential_string = to_direct.PointerToString(&runtime);
|
||||
|
||||
var_result = AllocAndCopyStringCharacters(
|
||||
fake_sequential_string, instance_type, offset, substr_length);
|
||||
fake_sequential_string, instance_type, offset, SmiTag(substr_length));
|
||||
|
||||
Counters* counters = isolate()->counters();
|
||||
IncrementCounter(counters->sub_string_native(), 1);
|
||||
@ -6588,33 +6583,32 @@ TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left,
|
||||
done(this, &result), done_native(this, &result);
|
||||
Counters* counters = isolate()->counters();
|
||||
|
||||
TNode<Uint32T> left_length = LoadStringLengthAsWord32(left);
|
||||
GotoIfNot(Word32Equal(left_length, Uint32Constant(0)), &check_right);
|
||||
TNode<Smi> left_length = LoadStringLengthAsSmi(left);
|
||||
GotoIf(SmiNotEqual(SmiConstant(0), left_length), &check_right);
|
||||
result = right;
|
||||
Goto(&done_native);
|
||||
|
||||
BIND(&check_right);
|
||||
TNode<Uint32T> right_length = LoadStringLengthAsWord32(right);
|
||||
GotoIfNot(Word32Equal(right_length, Uint32Constant(0)), &cons);
|
||||
TNode<Smi> right_length = LoadStringLengthAsSmi(right);
|
||||
GotoIf(SmiNotEqual(SmiConstant(0), right_length), &cons);
|
||||
result = left;
|
||||
Goto(&done_native);
|
||||
|
||||
BIND(&cons);
|
||||
{
|
||||
TNode<Uint32T> new_length = Uint32Add(left_length, right_length);
|
||||
TNode<Smi> new_length = SmiAdd(left_length, right_length);
|
||||
|
||||
// If new length is greater than String::kMaxLength, goto runtime to
|
||||
// throw. Note: we also need to invalidate the string length protector, so
|
||||
// can't just throw here directly.
|
||||
GotoIf(Uint32GreaterThan(new_length, Uint32Constant(String::kMaxLength)),
|
||||
&runtime);
|
||||
GotoIf(SmiAbove(new_length, SmiConstant(String::kMaxLength)), &runtime);
|
||||
|
||||
TVARIABLE(String, var_left, left);
|
||||
TVARIABLE(String, var_right, right);
|
||||
Variable* input_vars[2] = {&var_left, &var_right};
|
||||
Label non_cons(this, 2, input_vars);
|
||||
Label slow(this, Label::kDeferred);
|
||||
GotoIf(Uint32LessThan(new_length, Uint32Constant(ConsString::kMinLength)),
|
||||
GotoIf(SmiLessThan(new_length, SmiConstant(ConsString::kMinLength)),
|
||||
&non_cons);
|
||||
|
||||
result =
|
||||
@ -6637,8 +6631,8 @@ TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left,
|
||||
GotoIf(IsSetWord32(xored_instance_types, kStringEncodingMask), &runtime);
|
||||
GotoIf(IsSetWord32(ored_instance_types, kStringRepresentationMask), &slow);
|
||||
|
||||
TNode<IntPtrT> word_left_length = Signed(ChangeUint32ToWord(left_length));
|
||||
TNode<IntPtrT> word_right_length = Signed(ChangeUint32ToWord(right_length));
|
||||
TNode<IntPtrT> word_left_length = SmiUntag(left_length);
|
||||
TNode<IntPtrT> word_right_length = SmiUntag(right_length);
|
||||
|
||||
Label two_byte(this);
|
||||
GotoIf(Word32Equal(Word32And(ored_instance_types,
|
||||
|
@ -958,12 +958,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
|
||||
Label* if_hash_not_computed = nullptr);
|
||||
|
||||
// Load length field of a String object as Smi value.
|
||||
TNode<Smi> LoadStringLengthAsSmi(SloppyTNode<String> string);
|
||||
// Load length field of a String object as intptr_t value.
|
||||
TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> string);
|
||||
// Load length field of a String object as uint32_t value.
|
||||
TNode<Uint32T> LoadStringLengthAsWord32(SloppyTNode<String> string);
|
||||
TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> object);
|
||||
// Load length field of a String object as Smi value.
|
||||
TNode<Smi> LoadStringLengthAsSmi(SloppyTNode<String> object);
|
||||
// Loads a pointer to the sequential String char array.
|
||||
Node* PointerToSeqStringData(Node* seq_string);
|
||||
// Load value field of a JSValue object.
|
||||
@ -1331,46 +1329,46 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
|
||||
|
||||
// Allocate a SeqOneByteString with the given length.
|
||||
TNode<String> AllocateSeqOneByteString(uint32_t length,
|
||||
TNode<String> AllocateSeqOneByteString(int length,
|
||||
AllocationFlags flags = kNone);
|
||||
TNode<String> AllocateSeqOneByteString(Node* context, TNode<Uint32T> length,
|
||||
TNode<String> AllocateSeqOneByteString(Node* context, TNode<Smi> length,
|
||||
AllocationFlags flags = kNone);
|
||||
// Allocate a SeqTwoByteString with the given length.
|
||||
TNode<String> AllocateSeqTwoByteString(uint32_t length,
|
||||
TNode<String> AllocateSeqTwoByteString(int length,
|
||||
AllocationFlags flags = kNone);
|
||||
TNode<String> AllocateSeqTwoByteString(Node* context, TNode<Uint32T> length,
|
||||
TNode<String> AllocateSeqTwoByteString(Node* context, TNode<Smi> length,
|
||||
AllocationFlags flags = kNone);
|
||||
|
||||
// Allocate a SlicedOneByteString with the given length, parent and offset.
|
||||
// |length| and |offset| are expected to be tagged.
|
||||
|
||||
TNode<String> AllocateSlicedOneByteString(TNode<Uint32T> length,
|
||||
TNode<String> AllocateSlicedOneByteString(TNode<Smi> length,
|
||||
TNode<String> parent,
|
||||
TNode<Smi> offset);
|
||||
// Allocate a SlicedTwoByteString with the given length, parent and offset.
|
||||
// |length| and |offset| are expected to be tagged.
|
||||
TNode<String> AllocateSlicedTwoByteString(TNode<Uint32T> length,
|
||||
TNode<String> AllocateSlicedTwoByteString(TNode<Smi> length,
|
||||
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> AllocateOneByteConsString(TNode<Smi> 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> AllocateTwoByteConsString(TNode<Smi> 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> NewConsString(TNode<Smi> length, TNode<String> left,
|
||||
TNode<String> right,
|
||||
AllocationFlags flags = kNone);
|
||||
|
||||
@ -2992,11 +2990,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Label* bailout);
|
||||
|
||||
TNode<String> AllocateSlicedString(Heap::RootListIndex map_root_index,
|
||||
TNode<Uint32T> length,
|
||||
TNode<String> parent, TNode<Smi> offset);
|
||||
TNode<Smi> length, TNode<String> parent,
|
||||
TNode<Smi> offset);
|
||||
|
||||
TNode<String> AllocateConsString(Heap::RootListIndex map_root_index,
|
||||
TNode<Uint32T> length, TNode<String> first,
|
||||
TNode<Smi> length, TNode<String> first,
|
||||
TNode<String> second, AllocationFlags flags);
|
||||
|
||||
// Allocate a MutableHeapNumber without initializing its value.
|
||||
@ -3020,7 +3018,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
TNode<String> AllocAndCopyStringCharacters(Node* from,
|
||||
Node* from_instance_type,
|
||||
TNode<IntPtrT> from_index,
|
||||
TNode<IntPtrT> character_count);
|
||||
TNode<Smi> character_count);
|
||||
|
||||
static const int kElementLoopUnrollThreshold = 8;
|
||||
|
||||
|
@ -611,7 +611,7 @@ FieldAccess AccessBuilder::ForStringLength() {
|
||||
Handle<Name>(),
|
||||
MaybeHandle<Map>(),
|
||||
TypeCache::Get().kStringLengthType,
|
||||
MachineType::Uint32(),
|
||||
MachineType::TaggedSigned(),
|
||||
kNoWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
@ -910,11 +910,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Uint32T> Uint32Add(TNode<Uint32T> left, TNode<Uint32T> right) {
|
||||
return Unsigned(
|
||||
Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
|
@ -2790,7 +2790,7 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
|
||||
Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(ConsString::kSize));
|
||||
__ StoreField(AccessBuilder::ForMap(), result, result_map);
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), result,
|
||||
__ Int32Constant(Name::kEmptyHashField));
|
||||
jsgraph()->Int32Constant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), result, length);
|
||||
__ StoreField(AccessBuilder::ForConsStringFirst(), result, first);
|
||||
__ StoreField(AccessBuilder::ForConsStringSecond(), result, second);
|
||||
@ -3063,9 +3063,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
|
||||
__ StoreField(AccessBuilder::ForMap(), vtrue2,
|
||||
__ HeapConstant(factory()->one_byte_string_map()));
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
|
||||
__ Int32Constant(Name::kEmptyHashField));
|
||||
__ IntPtrConstant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
|
||||
__ Int32Constant(1));
|
||||
__ SmiConstant(1));
|
||||
__ Store(
|
||||
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
|
||||
vtrue2,
|
||||
@ -3087,9 +3087,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
|
||||
__ StoreField(AccessBuilder::ForMap(), vfalse1,
|
||||
__ HeapConstant(factory()->string_map()));
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
|
||||
__ Int32Constant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vfalse1,
|
||||
__ Int32Constant(1));
|
||||
__ IntPtrConstant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vfalse1, __ SmiConstant(1));
|
||||
__ Store(
|
||||
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
|
||||
vfalse1,
|
||||
@ -3187,9 +3186,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
|
||||
__ StoreField(AccessBuilder::ForMap(), vtrue2,
|
||||
__ HeapConstant(factory()->one_byte_string_map()));
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
|
||||
__ Int32Constant(Name::kEmptyHashField));
|
||||
__ IntPtrConstant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
|
||||
__ Int32Constant(1));
|
||||
__ SmiConstant(1));
|
||||
__ Store(
|
||||
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
|
||||
vtrue2,
|
||||
@ -3213,7 +3212,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
|
||||
__ IntPtrConstant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vfalse1,
|
||||
__ Int32Constant(1));
|
||||
__ SmiConstant(1));
|
||||
__ Store(
|
||||
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
|
||||
vfalse1,
|
||||
@ -3258,9 +3257,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
|
||||
__ StoreField(AccessBuilder::ForMap(), vfalse0,
|
||||
__ HeapConstant(factory()->string_map()));
|
||||
__ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
|
||||
__ Int32Constant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vfalse0,
|
||||
__ Int32Constant(2));
|
||||
__ IntPtrConstant(Name::kEmptyHashField));
|
||||
__ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2));
|
||||
__ Store(
|
||||
StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
|
||||
vfalse0,
|
||||
|
@ -121,7 +121,13 @@ class VirtualObject : public Dependable {
|
||||
typedef ZoneVector<Variable>::const_iterator const_iterator;
|
||||
VirtualObject(VariableTracker* var_states, Id id, int size);
|
||||
Maybe<Variable> FieldAt(int offset) const {
|
||||
CHECK_EQ(0, offset % kPointerSize);
|
||||
if (offset % kPointerSize != 0) {
|
||||
// We do not support fields that are not word-aligned. Bail out by
|
||||
// treating the object as escaping. This can only happen for
|
||||
// {Name::kHashFieldOffset} on 64bit big endian architectures.
|
||||
DCHECK_EQ(Name::kHashFieldOffset, offset);
|
||||
return Nothing<Variable>();
|
||||
}
|
||||
CHECK(!HasEscaped());
|
||||
if (offset >= size()) {
|
||||
// TODO(tebbi): Reading out-of-bounds can only happen in unreachable
|
||||
|
@ -2338,9 +2338,9 @@ class RepresentationSelector {
|
||||
MachineRepresentation::kTaggedPointer);
|
||||
}
|
||||
case IrOpcode::kNewConsString: {
|
||||
ProcessInput(node, 0, UseInfo::TruncatingWord32()); // length
|
||||
ProcessInput(node, 1, UseInfo::AnyTagged()); // first
|
||||
ProcessInput(node, 2, UseInfo::AnyTagged()); // second
|
||||
ProcessInput(node, 0, UseInfo::TaggedSigned()); // length
|
||||
ProcessInput(node, 1, UseInfo::AnyTagged()); // first
|
||||
ProcessInput(node, 2, UseInfo::AnyTagged()); // second
|
||||
SetOutput(node, MachineRepresentation::kTaggedPointer);
|
||||
return;
|
||||
}
|
||||
@ -2393,7 +2393,8 @@ class RepresentationSelector {
|
||||
// TODO(bmeurer): The input representation should be TaggedPointer.
|
||||
// Fix this once we have a dedicated StringConcat/JSStringAdd
|
||||
// operator, which marks it's output as TaggedPointer properly.
|
||||
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kWord32);
|
||||
VisitUnop(node, UseInfo::AnyTagged(),
|
||||
MachineRepresentation::kTaggedSigned);
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kStringSubstring: {
|
||||
|
@ -2093,7 +2093,7 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map,
|
||||
Comment("check if string");
|
||||
GotoIfNot(IsStringInstanceType(instance_type), slow);
|
||||
Comment("load string character");
|
||||
TNode<IntPtrT> length = LoadStringLengthAsWord(receiver);
|
||||
Node* length = LoadAndUntagObjectField(receiver, String::kLengthOffset);
|
||||
GotoIfNot(UintPtrLessThan(index, length), slow);
|
||||
IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1);
|
||||
TailCallBuiltin(Builtins::kStringCharAt, NoContextConstant(), receiver,
|
||||
|
@ -19,25 +19,24 @@ CAST_ACCESSOR(Name)
|
||||
CAST_ACCESSOR(Symbol)
|
||||
|
||||
ACCESSORS(Symbol, name, Object, kNameOffset)
|
||||
INT_ACCESSORS(Symbol, flags, kFlagsOffset)
|
||||
BIT_FIELD_ACCESSORS(Symbol, flags, is_private, Symbol::IsPrivateBit)
|
||||
BIT_FIELD_ACCESSORS(Symbol, flags, is_well_known_symbol,
|
||||
Symbol::IsWellKnownSymbolBit)
|
||||
BIT_FIELD_ACCESSORS(Symbol, flags, is_public, Symbol::IsPublicBit)
|
||||
BIT_FIELD_ACCESSORS(Symbol, flags, is_interesting_symbol,
|
||||
Symbol::IsInterestingSymbolBit)
|
||||
SMI_ACCESSORS(Symbol, flags, kFlagsOffset)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_well_known_symbol, kWellKnownSymbolBit)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_public, kPublicBit)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_interesting_symbol, kInterestingSymbolBit)
|
||||
|
||||
bool Symbol::is_private_field() const {
|
||||
bool value = Symbol::IsPrivateFieldBit::decode(flags());
|
||||
bool value = BooleanBit::get(flags(), kPrivateFieldBit);
|
||||
DCHECK_IMPLIES(value, is_private());
|
||||
return value;
|
||||
}
|
||||
|
||||
void Symbol::set_is_private_field() {
|
||||
int old_value = flags();
|
||||
// TODO(gsathya): Re-order the bits to have these next to each other
|
||||
// and just do the bit shifts once.
|
||||
set_flags(Symbol::IsPrivateBit::update(flags(), true));
|
||||
set_flags(Symbol::IsPrivateFieldBit::update(flags(), true));
|
||||
set_flags(BooleanBit::set(old_value, kPrivateBit, true) |
|
||||
BooleanBit::set(old_value, kPrivateFieldBit, true));
|
||||
}
|
||||
|
||||
bool Name::IsUniqueName() const {
|
||||
@ -52,6 +51,13 @@ uint32_t Name::hash_field() {
|
||||
|
||||
void Name::set_hash_field(uint32_t value) {
|
||||
WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
|
||||
#if V8_HOST_ARCH_64_BIT
|
||||
#if V8_TARGET_LITTLE_ENDIAN
|
||||
WRITE_UINT32_FIELD(this, kHashFieldSlot + kInt32Size, 0);
|
||||
#else
|
||||
WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Name::Equals(Name* other) {
|
||||
|
@ -67,8 +67,13 @@ class Name : public HeapObject {
|
||||
int NameShortPrint(Vector<char> str);
|
||||
|
||||
// Layout description.
|
||||
static const int kHashFieldOffset = HeapObject::kHeaderSize;
|
||||
static const int kHeaderSize = kHashFieldOffset + kInt32Size;
|
||||
static const int kHashFieldSlot = HeapObject::kHeaderSize;
|
||||
#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
|
||||
static const int kHashFieldOffset = kHashFieldSlot;
|
||||
#else
|
||||
static const int kHashFieldOffset = kHashFieldSlot + kInt32Size;
|
||||
#endif
|
||||
static const int kSize = kHashFieldSlot + kPointerSize;
|
||||
|
||||
// Mask constant for checking if a name has a computed hash code
|
||||
// and if it is a string that is an array index. The least significant bit
|
||||
@ -176,22 +181,18 @@ class Symbol : public Name {
|
||||
DECL_VERIFIER(Symbol)
|
||||
|
||||
// Layout description.
|
||||
static const int kFlagsOffset = Name::kHeaderSize;
|
||||
static const int kNameOffset = kFlagsOffset + kInt32Size;
|
||||
static const int kSize = kNameOffset + kPointerSize;
|
||||
static const int kNameOffset = Name::kSize;
|
||||
static const int kFlagsOffset = kNameOffset + kPointerSize;
|
||||
static const int kSize = kFlagsOffset + kPointerSize;
|
||||
|
||||
// Flags layout.
|
||||
#define FLAGS_BIT_FIELDS(V, _) \
|
||||
V(IsPrivateBit, bool, 1, _) \
|
||||
V(IsWellKnownSymbolBit, bool, 1, _) \
|
||||
V(IsPublicBit, bool, 1, _) \
|
||||
V(IsInterestingSymbolBit, bool, 1, _) \
|
||||
V(IsPrivateFieldBit, bool, 1, _)
|
||||
// Flags layout.
|
||||
static const int kPrivateBit = 0;
|
||||
static const int kWellKnownSymbolBit = 1;
|
||||
static const int kPublicBit = 2;
|
||||
static const int kInterestingSymbolBit = 3;
|
||||
static const int kPrivateFieldBit = 4;
|
||||
|
||||
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
|
||||
#undef FLAGS_BIT_FIELDS
|
||||
|
||||
typedef FixedBodyDescriptor<kNameOffset, kSize, kSize> BodyDescriptor;
|
||||
typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
|
||||
// No weak fields.
|
||||
typedef BodyDescriptor BodyDescriptorWeak;
|
||||
|
||||
|
@ -19,17 +19,8 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
INT32_ACCESSORS(String, length, kLengthOffset)
|
||||
|
||||
int String::synchronized_length() const {
|
||||
return base::AsAtomic32::Acquire_Load(
|
||||
reinterpret_cast<const int32_t*>(FIELD_ADDR(this, kLengthOffset)));
|
||||
}
|
||||
|
||||
void String::synchronized_set_length(int value) {
|
||||
base::AsAtomic32::Release_Store(
|
||||
reinterpret_cast<int32_t*>(FIELD_ADDR(this, kLengthOffset)), value);
|
||||
}
|
||||
SMI_ACCESSORS(String, length, kLengthOffset)
|
||||
SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
|
||||
|
||||
CAST_ACCESSOR(ConsString)
|
||||
CAST_ACCESSOR(ExternalOneByteString)
|
||||
|
@ -341,8 +341,8 @@ class String : public Name {
|
||||
inline bool IsFlat();
|
||||
|
||||
// Layout description.
|
||||
static const int kLengthOffset = Name::kHeaderSize;
|
||||
static const int kHeaderSize = kLengthOffset + kInt32Size;
|
||||
static const int kLengthOffset = Name::kSize;
|
||||
static const int kSize = kLengthOffset + kPointerSize;
|
||||
|
||||
// Max char codes.
|
||||
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
|
||||
@ -360,7 +360,7 @@ class String : public Name {
|
||||
|
||||
// See include/v8.h for the definition.
|
||||
static const int kMaxLength = v8::String::kMaxLength;
|
||||
static_assert(kMaxLength <= (Smi::kMaxValue / 2 - kHeaderSize),
|
||||
static_assert(kMaxLength <= (Smi::kMaxValue / 2 - kSize),
|
||||
"Unexpected max String length");
|
||||
|
||||
// Max length for computing hash. For strings longer than this limit the
|
||||
@ -474,6 +474,9 @@ class SeqString : public String {
|
||||
public:
|
||||
DECL_CAST(SeqString)
|
||||
|
||||
// Layout description.
|
||||
static const int kHeaderSize = String::kSize;
|
||||
|
||||
// Truncate the string in-place if possible and return the result.
|
||||
// In case of new_length == 0, the empty string is returned without
|
||||
// truncating the original string.
|
||||
@ -617,7 +620,7 @@ class ConsString : public String {
|
||||
DECL_CAST(ConsString)
|
||||
|
||||
// Layout description.
|
||||
static const int kFirstOffset = String::kHeaderSize;
|
||||
static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
|
||||
static const int kSecondOffset = kFirstOffset + kPointerSize;
|
||||
static const int kSize = kSecondOffset + kPointerSize;
|
||||
|
||||
@ -656,7 +659,7 @@ class ThinString : public String {
|
||||
DECL_VERIFIER(ThinString)
|
||||
|
||||
// Layout description.
|
||||
static const int kActualOffset = String::kHeaderSize;
|
||||
static const int kActualOffset = String::kSize;
|
||||
static const int kSize = kActualOffset + kPointerSize;
|
||||
|
||||
typedef FixedBodyDescriptor<kActualOffset, kSize, kSize> BodyDescriptor;
|
||||
@ -693,7 +696,7 @@ class SlicedString : public String {
|
||||
DECL_CAST(SlicedString)
|
||||
|
||||
// Layout description.
|
||||
static const int kParentOffset = String::kHeaderSize;
|
||||
static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
|
||||
static const int kOffsetOffset = kParentOffset + kPointerSize;
|
||||
static const int kSize = kOffsetOffset + kPointerSize;
|
||||
|
||||
@ -726,7 +729,7 @@ class ExternalString : public String {
|
||||
DECL_CAST(ExternalString)
|
||||
|
||||
// Layout description.
|
||||
static const int kResourceOffset = String::kHeaderSize;
|
||||
static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
|
||||
static const int kUncachedSize = kResourceOffset + kPointerSize;
|
||||
static const int kResourceDataOffset = kResourceOffset + kPointerSize;
|
||||
static const int kSize = kResourceDataOffset + kPointerSize;
|
||||
|
@ -187,135 +187,135 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x023f1): (152, "OnePointerFillerMap"),
|
||||
("RO_SPACE", 0x02441): (152, "TwoPointerFillerMap"),
|
||||
("RO_SPACE", 0x024c1): (131, "UninitializedMap"),
|
||||
("RO_SPACE", 0x02531): (8, "OneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x025d1): (131, "UndefinedMap"),
|
||||
("RO_SPACE", 0x02631): (129, "HeapNumberMap"),
|
||||
("RO_SPACE", 0x026b1): (131, "TheHoleMap"),
|
||||
("RO_SPACE", 0x02759): (131, "BooleanMap"),
|
||||
("RO_SPACE", 0x02831): (136, "ByteArrayMap"),
|
||||
("RO_SPACE", 0x02881): (183, "FixedArrayMap"),
|
||||
("RO_SPACE", 0x028d1): (183, "FixedCOWArrayMap"),
|
||||
("RO_SPACE", 0x02921): (185, "HashTableMap"),
|
||||
("RO_SPACE", 0x02971): (128, "SymbolMap"),
|
||||
("RO_SPACE", 0x029c1): (72, "OneByteStringMap"),
|
||||
("RO_SPACE", 0x02a11): (194, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x02a61): (217, "SharedFunctionInfoMap"),
|
||||
("RO_SPACE", 0x02ab1): (133, "CodeMap"),
|
||||
("RO_SPACE", 0x02b01): (200, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x02b51): (209, "CellMap"),
|
||||
("RO_SPACE", 0x02ba1): (216, "GlobalPropertyCellMap"),
|
||||
("RO_SPACE", 0x02bf1): (135, "ForeignMap"),
|
||||
("RO_SPACE", 0x02c41): (207, "TransitionArrayMap"),
|
||||
("RO_SPACE", 0x02c91): (212, "FeedbackVectorMap"),
|
||||
("RO_SPACE", 0x02d31): (131, "ArgumentsMarkerMap"),
|
||||
("RO_SPACE", 0x02dd1): (131, "ExceptionMap"),
|
||||
("RO_SPACE", 0x02e71): (131, "TerminationExceptionMap"),
|
||||
("RO_SPACE", 0x02f19): (131, "OptimizedOutMap"),
|
||||
("RO_SPACE", 0x02fb9): (131, "StaleRegisterMap"),
|
||||
("RO_SPACE", 0x03029): (202, "NativeContextMap"),
|
||||
("RO_SPACE", 0x03079): (201, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x030c9): (199, "EvalContextMap"),
|
||||
("RO_SPACE", 0x03119): (203, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x03169): (196, "BlockContextMap"),
|
||||
("RO_SPACE", 0x031b9): (197, "CatchContextMap"),
|
||||
("RO_SPACE", 0x03209): (204, "WithContextMap"),
|
||||
("RO_SPACE", 0x03259): (198, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x032a9): (195, "ScriptContextTableMap"),
|
||||
("RO_SPACE", 0x032f9): (151, "FeedbackMetadataArrayMap"),
|
||||
("RO_SPACE", 0x03349): (183, "ArrayListMap"),
|
||||
("RO_SPACE", 0x03399): (130, "BigIntMap"),
|
||||
("RO_SPACE", 0x033e9): (184, "ObjectBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x03439): (137, "BytecodeArrayMap"),
|
||||
("RO_SPACE", 0x03489): (210, "CodeDataContainerMap"),
|
||||
("RO_SPACE", 0x034d9): (150, "FixedDoubleArrayMap"),
|
||||
("RO_SPACE", 0x03529): (189, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x03579): (211, "ManyClosuresCellMap"),
|
||||
("RO_SPACE", 0x035c9): (183, "ModuleInfoMap"),
|
||||
("RO_SPACE", 0x03619): (134, "MutableHeapNumberMap"),
|
||||
("RO_SPACE", 0x03669): (188, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x036b9): (211, "NoClosuresCellMap"),
|
||||
("RO_SPACE", 0x03709): (190, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03759): (211, "OneClosureCellMap"),
|
||||
("RO_SPACE", 0x037a9): (186, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x037f9): (187, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x03849): (214, "PreParsedScopeDataMap"),
|
||||
("RO_SPACE", 0x03899): (215, "PropertyArrayMap"),
|
||||
("RO_SPACE", 0x038e9): (208, "SideEffectCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03939): (208, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03989): (208, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x039d9): (191, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03a29): (183, "SloppyArgumentsElementsMap"),
|
||||
("RO_SPACE", 0x03a79): (218, "SmallOrderedHashMapMap"),
|
||||
("RO_SPACE", 0x03ac9): (219, "SmallOrderedHashSetMap"),
|
||||
("RO_SPACE", 0x03b19): (192, "StringTableMap"),
|
||||
("RO_SPACE", 0x03b69): (221, "UncompiledDataWithoutPreParsedScopeMap"),
|
||||
("RO_SPACE", 0x03bb9): (222, "UncompiledDataWithPreParsedScopeMap"),
|
||||
("RO_SPACE", 0x03c09): (223, "WeakArrayListMap"),
|
||||
("RO_SPACE", 0x03c59): (193, "EphemeronHashTableMap"),
|
||||
("RO_SPACE", 0x03ca9): (106, "NativeSourceStringMap"),
|
||||
("RO_SPACE", 0x03cf9): (64, "StringMap"),
|
||||
("RO_SPACE", 0x03d49): (73, "ConsOneByteStringMap"),
|
||||
("RO_SPACE", 0x03d99): (65, "ConsStringMap"),
|
||||
("RO_SPACE", 0x03de9): (77, "ThinOneByteStringMap"),
|
||||
("RO_SPACE", 0x03e39): (69, "ThinStringMap"),
|
||||
("RO_SPACE", 0x03e89): (67, "SlicedStringMap"),
|
||||
("RO_SPACE", 0x03ed9): (75, "SlicedOneByteStringMap"),
|
||||
("RO_SPACE", 0x03f29): (66, "ExternalStringMap"),
|
||||
("RO_SPACE", 0x03f79): (82, "ExternalStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x03fc9): (74, "ExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x04019): (98, "UncachedExternalStringMap"),
|
||||
("RO_SPACE", 0x04069): (114, "UncachedExternalStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x040b9): (0, "InternalizedStringMap"),
|
||||
("RO_SPACE", 0x04109): (2, "ExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x04159): (18, "ExternalInternalizedStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x041a9): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x041f9): (34, "UncachedExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x04249): (50, "UncachedExternalInternalizedStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x04299): (42, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x042e9): (106, "UncachedExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x04339): (140, "FixedUint8ArrayMap"),
|
||||
("RO_SPACE", 0x04389): (139, "FixedInt8ArrayMap"),
|
||||
("RO_SPACE", 0x043d9): (142, "FixedUint16ArrayMap"),
|
||||
("RO_SPACE", 0x04429): (141, "FixedInt16ArrayMap"),
|
||||
("RO_SPACE", 0x04479): (144, "FixedUint32ArrayMap"),
|
||||
("RO_SPACE", 0x044c9): (143, "FixedInt32ArrayMap"),
|
||||
("RO_SPACE", 0x04519): (145, "FixedFloat32ArrayMap"),
|
||||
("RO_SPACE", 0x04569): (146, "FixedFloat64ArrayMap"),
|
||||
("RO_SPACE", 0x045b9): (147, "FixedUint8ClampedArrayMap"),
|
||||
("RO_SPACE", 0x04609): (149, "FixedBigUint64ArrayMap"),
|
||||
("RO_SPACE", 0x04659): (148, "FixedBigInt64ArrayMap"),
|
||||
("RO_SPACE", 0x046a9): (131, "SelfReferenceMarkerMap"),
|
||||
("RO_SPACE", 0x04711): (171, "Tuple2Map"),
|
||||
("RO_SPACE", 0x047b1): (173, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x04aa1): (161, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x04b91): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x08cf1): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x08d41): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x08d91): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x08de1): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x08e31): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x08e81): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x08ed1): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x08f21): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x08f71): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x08fc1): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x09011): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x09061): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x090b1): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x09101): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x09151): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x091a1): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x091f1): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x09241): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x09291): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x092e1): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x09331): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x09381): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x093d1): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x09421): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x09471): (181, "MicrotaskQueueMap"),
|
||||
("RO_SPACE", 0x094c1): (182, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x09511): (182, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x02539): (8, "OneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x025e1): (131, "UndefinedMap"),
|
||||
("RO_SPACE", 0x02641): (129, "HeapNumberMap"),
|
||||
("RO_SPACE", 0x026c1): (131, "TheHoleMap"),
|
||||
("RO_SPACE", 0x02771): (131, "BooleanMap"),
|
||||
("RO_SPACE", 0x02869): (136, "ByteArrayMap"),
|
||||
("RO_SPACE", 0x028b9): (183, "FixedArrayMap"),
|
||||
("RO_SPACE", 0x02909): (183, "FixedCOWArrayMap"),
|
||||
("RO_SPACE", 0x02959): (185, "HashTableMap"),
|
||||
("RO_SPACE", 0x029a9): (128, "SymbolMap"),
|
||||
("RO_SPACE", 0x029f9): (72, "OneByteStringMap"),
|
||||
("RO_SPACE", 0x02a49): (194, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x02a99): (217, "SharedFunctionInfoMap"),
|
||||
("RO_SPACE", 0x02ae9): (133, "CodeMap"),
|
||||
("RO_SPACE", 0x02b39): (200, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x02b89): (209, "CellMap"),
|
||||
("RO_SPACE", 0x02bd9): (216, "GlobalPropertyCellMap"),
|
||||
("RO_SPACE", 0x02c29): (135, "ForeignMap"),
|
||||
("RO_SPACE", 0x02c79): (207, "TransitionArrayMap"),
|
||||
("RO_SPACE", 0x02cc9): (212, "FeedbackVectorMap"),
|
||||
("RO_SPACE", 0x02d69): (131, "ArgumentsMarkerMap"),
|
||||
("RO_SPACE", 0x02e11): (131, "ExceptionMap"),
|
||||
("RO_SPACE", 0x02eb9): (131, "TerminationExceptionMap"),
|
||||
("RO_SPACE", 0x02f69): (131, "OptimizedOutMap"),
|
||||
("RO_SPACE", 0x03011): (131, "StaleRegisterMap"),
|
||||
("RO_SPACE", 0x03089): (202, "NativeContextMap"),
|
||||
("RO_SPACE", 0x030d9): (201, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x03129): (199, "EvalContextMap"),
|
||||
("RO_SPACE", 0x03179): (203, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x031c9): (196, "BlockContextMap"),
|
||||
("RO_SPACE", 0x03219): (197, "CatchContextMap"),
|
||||
("RO_SPACE", 0x03269): (204, "WithContextMap"),
|
||||
("RO_SPACE", 0x032b9): (198, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x03309): (195, "ScriptContextTableMap"),
|
||||
("RO_SPACE", 0x03359): (151, "FeedbackMetadataArrayMap"),
|
||||
("RO_SPACE", 0x033a9): (183, "ArrayListMap"),
|
||||
("RO_SPACE", 0x033f9): (130, "BigIntMap"),
|
||||
("RO_SPACE", 0x03449): (184, "ObjectBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x03499): (137, "BytecodeArrayMap"),
|
||||
("RO_SPACE", 0x034e9): (210, "CodeDataContainerMap"),
|
||||
("RO_SPACE", 0x03539): (150, "FixedDoubleArrayMap"),
|
||||
("RO_SPACE", 0x03589): (189, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x035d9): (211, "ManyClosuresCellMap"),
|
||||
("RO_SPACE", 0x03629): (183, "ModuleInfoMap"),
|
||||
("RO_SPACE", 0x03679): (134, "MutableHeapNumberMap"),
|
||||
("RO_SPACE", 0x036c9): (188, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x03719): (211, "NoClosuresCellMap"),
|
||||
("RO_SPACE", 0x03769): (190, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x037b9): (211, "OneClosureCellMap"),
|
||||
("RO_SPACE", 0x03809): (186, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x03859): (187, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x038a9): (214, "PreParsedScopeDataMap"),
|
||||
("RO_SPACE", 0x038f9): (215, "PropertyArrayMap"),
|
||||
("RO_SPACE", 0x03949): (208, "SideEffectCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03999): (208, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x039e9): (208, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03a39): (191, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03a89): (183, "SloppyArgumentsElementsMap"),
|
||||
("RO_SPACE", 0x03ad9): (218, "SmallOrderedHashMapMap"),
|
||||
("RO_SPACE", 0x03b29): (219, "SmallOrderedHashSetMap"),
|
||||
("RO_SPACE", 0x03b79): (192, "StringTableMap"),
|
||||
("RO_SPACE", 0x03bc9): (221, "UncompiledDataWithoutPreParsedScopeMap"),
|
||||
("RO_SPACE", 0x03c19): (222, "UncompiledDataWithPreParsedScopeMap"),
|
||||
("RO_SPACE", 0x03c69): (223, "WeakArrayListMap"),
|
||||
("RO_SPACE", 0x03cb9): (193, "EphemeronHashTableMap"),
|
||||
("RO_SPACE", 0x03d09): (106, "NativeSourceStringMap"),
|
||||
("RO_SPACE", 0x03d59): (64, "StringMap"),
|
||||
("RO_SPACE", 0x03da9): (73, "ConsOneByteStringMap"),
|
||||
("RO_SPACE", 0x03df9): (65, "ConsStringMap"),
|
||||
("RO_SPACE", 0x03e49): (77, "ThinOneByteStringMap"),
|
||||
("RO_SPACE", 0x03e99): (69, "ThinStringMap"),
|
||||
("RO_SPACE", 0x03ee9): (67, "SlicedStringMap"),
|
||||
("RO_SPACE", 0x03f39): (75, "SlicedOneByteStringMap"),
|
||||
("RO_SPACE", 0x03f89): (66, "ExternalStringMap"),
|
||||
("RO_SPACE", 0x03fd9): (82, "ExternalStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x04029): (74, "ExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x04079): (98, "UncachedExternalStringMap"),
|
||||
("RO_SPACE", 0x040c9): (114, "UncachedExternalStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x04119): (0, "InternalizedStringMap"),
|
||||
("RO_SPACE", 0x04169): (2, "ExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x041b9): (18, "ExternalInternalizedStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x04209): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x04259): (34, "UncachedExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x042a9): (50, "UncachedExternalInternalizedStringWithOneByteDataMap"),
|
||||
("RO_SPACE", 0x042f9): (42, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x04349): (106, "UncachedExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x04399): (140, "FixedUint8ArrayMap"),
|
||||
("RO_SPACE", 0x043e9): (139, "FixedInt8ArrayMap"),
|
||||
("RO_SPACE", 0x04439): (142, "FixedUint16ArrayMap"),
|
||||
("RO_SPACE", 0x04489): (141, "FixedInt16ArrayMap"),
|
||||
("RO_SPACE", 0x044d9): (144, "FixedUint32ArrayMap"),
|
||||
("RO_SPACE", 0x04529): (143, "FixedInt32ArrayMap"),
|
||||
("RO_SPACE", 0x04579): (145, "FixedFloat32ArrayMap"),
|
||||
("RO_SPACE", 0x045c9): (146, "FixedFloat64ArrayMap"),
|
||||
("RO_SPACE", 0x04619): (147, "FixedUint8ClampedArrayMap"),
|
||||
("RO_SPACE", 0x04669): (149, "FixedBigUint64ArrayMap"),
|
||||
("RO_SPACE", 0x046b9): (148, "FixedBigInt64ArrayMap"),
|
||||
("RO_SPACE", 0x04709): (131, "SelfReferenceMarkerMap"),
|
||||
("RO_SPACE", 0x04771): (171, "Tuple2Map"),
|
||||
("RO_SPACE", 0x04811): (173, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x04b01): (161, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x04bf9): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x09d11): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x09d61): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x09db1): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x09e01): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x09e51): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x09ea1): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x09ef1): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x09f41): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09f91): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x09fe1): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x0a031): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x0a081): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x0a0d1): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x0a121): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x0a171): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x0a1c1): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x0a211): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x0a261): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x0a2b1): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x0a301): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x0a351): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x0a3a1): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a3f1): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a441): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x0a491): (181, "MicrotaskQueueMap"),
|
||||
("RO_SPACE", 0x0a4e1): (182, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x0a531): (182, "AllocationSiteMap"),
|
||||
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
|
||||
}
|
||||
@ -325,39 +325,39 @@ KNOWN_OBJECTS = {
|
||||
("RO_SPACE", 0x022a1): "NullValue",
|
||||
("RO_SPACE", 0x02321): "EmptyDescriptorArray",
|
||||
("RO_SPACE", 0x02491): "UninitializedValue",
|
||||
("RO_SPACE", 0x025a1): "UndefinedValue",
|
||||
("RO_SPACE", 0x02621): "NanValue",
|
||||
("RO_SPACE", 0x02681): "TheHoleValue",
|
||||
("RO_SPACE", 0x02719): "HoleNanValue",
|
||||
("RO_SPACE", 0x02729): "TrueValue",
|
||||
("RO_SPACE", 0x027d9): "FalseValue",
|
||||
("RO_SPACE", 0x02821): "empty_string",
|
||||
("RO_SPACE", 0x02ce1): "EmptyScopeInfo",
|
||||
("RO_SPACE", 0x02cf1): "EmptyFixedArray",
|
||||
("RO_SPACE", 0x02d01): "ArgumentsMarker",
|
||||
("RO_SPACE", 0x02da1): "Exception",
|
||||
("RO_SPACE", 0x02e41): "TerminationException",
|
||||
("RO_SPACE", 0x02ee9): "OptimizedOut",
|
||||
("RO_SPACE", 0x02f89): "StaleRegister",
|
||||
("RO_SPACE", 0x04771): "EmptyByteArray",
|
||||
("RO_SPACE", 0x04801): "EmptyFixedUint8Array",
|
||||
("RO_SPACE", 0x04821): "EmptyFixedInt8Array",
|
||||
("RO_SPACE", 0x04841): "EmptyFixedUint16Array",
|
||||
("RO_SPACE", 0x04861): "EmptyFixedInt16Array",
|
||||
("RO_SPACE", 0x04881): "EmptyFixedUint32Array",
|
||||
("RO_SPACE", 0x048a1): "EmptyFixedInt32Array",
|
||||
("RO_SPACE", 0x048c1): "EmptyFixedFloat32Array",
|
||||
("RO_SPACE", 0x048e1): "EmptyFixedFloat64Array",
|
||||
("RO_SPACE", 0x04901): "EmptyFixedUint8ClampedArray",
|
||||
("RO_SPACE", 0x04961): "EmptySloppyArgumentsElements",
|
||||
("RO_SPACE", 0x04981): "EmptySlowElementDictionary",
|
||||
("RO_SPACE", 0x049c9): "EmptyOrderedHashMap",
|
||||
("RO_SPACE", 0x049f1): "EmptyOrderedHashSet",
|
||||
("RO_SPACE", 0x04a29): "EmptyPropertyCell",
|
||||
("RO_SPACE", 0x04b09): "InfinityValue",
|
||||
("RO_SPACE", 0x04b19): "MinusZeroValue",
|
||||
("RO_SPACE", 0x04b29): "MinusInfinityValue",
|
||||
("RO_SPACE", 0x04b39): "SelfReferenceMarker",
|
||||
("RO_SPACE", 0x025b1): "UndefinedValue",
|
||||
("RO_SPACE", 0x02631): "NanValue",
|
||||
("RO_SPACE", 0x02691): "TheHoleValue",
|
||||
("RO_SPACE", 0x02731): "HoleNanValue",
|
||||
("RO_SPACE", 0x02741): "TrueValue",
|
||||
("RO_SPACE", 0x02801): "FalseValue",
|
||||
("RO_SPACE", 0x02851): "empty_string",
|
||||
("RO_SPACE", 0x02d19): "EmptyScopeInfo",
|
||||
("RO_SPACE", 0x02d29): "EmptyFixedArray",
|
||||
("RO_SPACE", 0x02d39): "ArgumentsMarker",
|
||||
("RO_SPACE", 0x02de1): "Exception",
|
||||
("RO_SPACE", 0x02e89): "TerminationException",
|
||||
("RO_SPACE", 0x02f39): "OptimizedOut",
|
||||
("RO_SPACE", 0x02fe1): "StaleRegister",
|
||||
("RO_SPACE", 0x047d1): "EmptyByteArray",
|
||||
("RO_SPACE", 0x04861): "EmptyFixedUint8Array",
|
||||
("RO_SPACE", 0x04881): "EmptyFixedInt8Array",
|
||||
("RO_SPACE", 0x048a1): "EmptyFixedUint16Array",
|
||||
("RO_SPACE", 0x048c1): "EmptyFixedInt16Array",
|
||||
("RO_SPACE", 0x048e1): "EmptyFixedUint32Array",
|
||||
("RO_SPACE", 0x04901): "EmptyFixedInt32Array",
|
||||
("RO_SPACE", 0x04921): "EmptyFixedFloat32Array",
|
||||
("RO_SPACE", 0x04941): "EmptyFixedFloat64Array",
|
||||
("RO_SPACE", 0x04961): "EmptyFixedUint8ClampedArray",
|
||||
("RO_SPACE", 0x049c1): "EmptySloppyArgumentsElements",
|
||||
("RO_SPACE", 0x049e1): "EmptySlowElementDictionary",
|
||||
("RO_SPACE", 0x04a29): "EmptyOrderedHashMap",
|
||||
("RO_SPACE", 0x04a51): "EmptyOrderedHashSet",
|
||||
("RO_SPACE", 0x04a89): "EmptyPropertyCell",
|
||||
("RO_SPACE", 0x04b69): "InfinityValue",
|
||||
("RO_SPACE", 0x04b79): "MinusZeroValue",
|
||||
("RO_SPACE", 0x04b89): "MinusInfinityValue",
|
||||
("RO_SPACE", 0x04b99): "SelfReferenceMarker",
|
||||
("OLD_SPACE", 0x02211): "EmptyScript",
|
||||
("OLD_SPACE", 0x02291): "ManyClosuresCell",
|
||||
("OLD_SPACE", 0x022b1): "NoElementsProtector",
|
||||
|
Loading…
Reference in New Issue
Block a user