Commit bd69d64d authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

Revert "Reland "[objects] Change String::length field to uint32_t.""

This reverts commit df6157ae.

Reason for revert: trybots didn't rerun :-/

Original change's description:
> Reland "[objects] Change String::length field to uint32_t."
> 
> This is a reland of 1f1eb625, 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}
> 
> Tbr: tebbi@chromium.org, yangguo@chromium.org, ishell@chromium.org
> Bug: v8:7065, v8:8171
> Change-Id: I3c7d0b00abb15fa98ab622f9ecd8602fc798cbc3
> 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/1221290
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#55836}

TBR=ulan@chromium.org,yangguo@chromium.org,tebbi@chromium.org,ishell@chromium.org,bmeurer@chromium.org

Change-Id: Ieaf3be31166abb02e37370ad846c38fa3d114693
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/1222306Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55837}
parent df6157ae
...@@ -129,8 +129,7 @@ class Internals { ...@@ -129,8 +129,7 @@ class Internals {
// the implementation of v8. // the implementation of v8.
static const int kHeapObjectMapOffset = 0; static const int kHeapObjectMapOffset = 0;
static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize; static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize;
static const int kStringResourceOffset = static const int kStringResourceOffset = 3 * kApiPointerSize;
1 * kApiPointerSize + 2 * kApiIntSize;
static const int kOddballKindOffset = 4 * kApiPointerSize + kApiDoubleSize; static const int kOddballKindOffset = 4 * kApiPointerSize + kApiDoubleSize;
static const int kForeignAddressOffset = kApiPointerSize; static const int kForeignAddressOffset = kApiPointerSize;
......
...@@ -71,7 +71,7 @@ bool Accessors::IsJSObjectFieldAccessor(Isolate* isolate, Handle<Map> map, ...@@ -71,7 +71,7 @@ bool Accessors::IsJSObjectFieldAccessor(Isolate* isolate, Handle<Map> map,
default: default:
if (map->instance_type() < FIRST_NONSTRING_TYPE) { if (map->instance_type() < FIRST_NONSTRING_TYPE) {
return CheckForName(isolate, name, isolate->factory()->length_string(), return CheckForName(isolate, name, isolate->factory()->length_string(),
String::kLengthOffset, FieldIndex::kWord32, index); String::kLengthOffset, FieldIndex::kTagged, index);
} }
return false; return false;
......
...@@ -41,8 +41,8 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { ...@@ -41,8 +41,8 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
Label call_c(this), return_string(this), runtime(this, Label::kDeferred); Label call_c(this), return_string(this), runtime(this, Label::kDeferred);
// Early exit on empty strings. // Early exit on empty strings.
TNode<Uint32T> const length = LoadStringLengthAsWord32(string); TNode<Smi> const length = LoadStringLengthAsSmi(string);
GotoIf(Word32Equal(length, Uint32Constant(0)), &return_string); GotoIf(SmiEqual(length, SmiConstant(0)), &return_string);
// Unpack strings if possible, and bail to runtime unless we get a one-byte // Unpack strings if possible, and bail to runtime unless we get a one-byte
// flat string. // flat string.
...@@ -60,8 +60,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { ...@@ -60,8 +60,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
Node* const dst = AllocateSeqOneByteString(context, length); Node* const dst = AllocateSeqOneByteString(context, length);
const int kMaxShortStringLength = 24; // Determined empirically. const int kMaxShortStringLength = 24; // Determined empirically.
GotoIf(Uint32GreaterThan(length, Uint32Constant(kMaxShortStringLength)), GotoIf(SmiGreaterThan(length, SmiConstant(kMaxShortStringLength)), &call_c);
&call_c);
{ {
Node* const dst_ptr = PointerToSeqStringData(dst); Node* const dst_ptr = PointerToSeqStringData(dst);
...@@ -70,7 +69,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { ...@@ -70,7 +69,7 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
Node* const start_address = to_direct.PointerToData(&call_c); Node* const start_address = to_direct.PointerToData(&call_c);
TNode<IntPtrT> const end_address = TNode<IntPtrT> const end_address =
Signed(IntPtrAdd(start_address, ChangeUint32ToWord(length))); Signed(IntPtrAdd(start_address, SmiUntag(length)));
Node* const to_lower_table_addr = Node* const to_lower_table_addr =
ExternalConstant(ExternalReference::intl_to_latin1_lower_table()); ExternalConstant(ExternalReference::intl_to_latin1_lower_table());
......
...@@ -536,9 +536,8 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context, ...@@ -536,9 +536,8 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context,
GotoIf(IsJSReceiverInstanceType(from_instance_type), &cont); GotoIf(IsJSReceiverInstanceType(from_instance_type), &cont);
GotoIfNot(IsStringInstanceType(from_instance_type), &done); GotoIfNot(IsStringInstanceType(from_instance_type), &done);
{ {
Branch( Branch(SmiEqual(LoadStringLengthAsSmi(CAST(from)), SmiConstant(0)), &done,
Word32Equal(LoadStringLengthAsWord32(CAST(from)), Int32Constant(0)), slow);
&done, slow);
} }
BIND(&cont); BIND(&cont);
} }
......
...@@ -1103,7 +1103,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, ...@@ -1103,7 +1103,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
Isolate* isolate = this->isolate(); Isolate* isolate = this->isolate();
TNode<IntPtrT> const int_one = IntPtrConstant(1); TNode<IntPtrT> const int_one = IntPtrConstant(1);
TVARIABLE(Uint32T, var_length, Uint32Constant(0)); TVARIABLE(Smi, var_length, SmiZero());
TVARIABLE(IntPtrT, var_flags); TVARIABLE(IntPtrT, var_flags);
// First, count the number of characters we will need and check which flags // First, count the number of characters we will need and check which flags
...@@ -1115,13 +1115,13 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, ...@@ -1115,13 +1115,13 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
Node* const flags_smi = LoadObjectField(regexp, JSRegExp::kFlagsOffset); Node* const flags_smi = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
var_flags = SmiUntag(flags_smi); var_flags = SmiUntag(flags_smi);
#define CASE_FOR_FLAG(FLAG) \ #define CASE_FOR_FLAG(FLAG) \
do { \ do { \
Label next(this); \ Label next(this); \
GotoIfNot(IsSetWord(var_flags.value(), FLAG), &next); \ GotoIfNot(IsSetWord(var_flags.value(), FLAG), &next); \
var_length = Uint32Add(var_length.value(), Uint32Constant(1)); \ var_length = SmiAdd(var_length.value(), SmiConstant(1)); \
Goto(&next); \ Goto(&next); \
BIND(&next); \ BIND(&next); \
} while (false) } while (false)
CASE_FOR_FLAG(JSRegExp::kGlobal); CASE_FOR_FLAG(JSRegExp::kGlobal);
...@@ -1145,7 +1145,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, ...@@ -1145,7 +1145,7 @@ Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
Label if_isflagset(this); \ Label if_isflagset(this); \
BranchIfToBooleanIsTrue(flag, &if_isflagset, &next); \ BranchIfToBooleanIsTrue(flag, &if_isflagset, &next); \
BIND(&if_isflagset); \ 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))); \ var_flags = Signed(WordOr(var_flags.value(), IntPtrConstant(FLAG))); \
Goto(&next); \ Goto(&next); \
BIND(&next); \ BIND(&next); \
......
...@@ -585,9 +585,8 @@ TF_BUILTIN(StringGreaterThanOrEqual, StringBuiltinsAssembler) { ...@@ -585,9 +585,8 @@ TF_BUILTIN(StringGreaterThanOrEqual, StringBuiltinsAssembler) {
} }
TF_BUILTIN(StringCharAt, StringBuiltinsAssembler) { TF_BUILTIN(StringCharAt, StringBuiltinsAssembler) {
TNode<String> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* receiver = Parameter(Descriptor::kReceiver);
TNode<IntPtrT> position = Node* position = Parameter(Descriptor::kPosition);
UncheckedCast<IntPtrT>(Parameter(Descriptor::kPosition));
// Load the character code at the {position} from the {receiver}. // Load the character code at the {position} from the {receiver}.
TNode<Int32T> code = StringCharCodeAt(receiver, position); TNode<Int32T> code = StringCharCodeAt(receiver, position);
...@@ -638,6 +637,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { ...@@ -638,6 +637,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext); Node* context = Parameter(Descriptor::kContext);
CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc)); 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. // Check if we have exactly one argument (plus the implicit receiver), i.e.
// if the parent frame is not an arguments adaptor frame. // if the parent frame is not an arguments adaptor frame.
Label if_oneargument(this), if_notoneargument(this); Label if_oneargument(this), if_notoneargument(this);
...@@ -662,7 +662,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { ...@@ -662,7 +662,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
{ {
Label two_byte(this); Label two_byte(this);
// Assume that the resulting string contains only one-byte characters. // 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); TVARIABLE(IntPtrT, var_max_index);
var_max_index = IntPtrConstant(0); var_max_index = IntPtrConstant(0);
...@@ -696,7 +696,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { ...@@ -696,7 +696,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
// At least one of the characters in the string requires a 16-bit // At least one of the characters in the string requires a 16-bit
// representation. Allocate a SeqTwoByteString to hold the resulting // representation. Allocate a SeqTwoByteString to hold the resulting
// string. // 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 // Copy the characters that have already been put in the 8-bit string into
// their corresponding positions in the new 16-bit string. // their corresponding positions in the new 16-bit string.
...@@ -1227,6 +1227,8 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) { ...@@ -1227,6 +1227,8 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
TNode<Object> count = CAST(Parameter(Descriptor::kCount)); TNode<Object> count = CAST(Parameter(Descriptor::kCount));
Node* const string = Node* const string =
ToThisString(context, receiver, "String.prototype.repeat"); ToThisString(context, receiver, "String.prototype.repeat");
Node* const is_stringempty =
SmiEqual(LoadStringLengthAsSmi(string), SmiConstant(0));
VARIABLE( VARIABLE(
var_count, MachineRepresentation::kTagged, var_count, MachineRepresentation::kTagged,
...@@ -1244,8 +1246,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) { ...@@ -1244,8 +1246,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
TNode<Smi> smi_count = CAST(var_count.value()); TNode<Smi> smi_count = CAST(var_count.value());
GotoIf(SmiLessThan(smi_count, SmiConstant(0)), &invalid_count); GotoIf(SmiLessThan(smi_count, SmiConstant(0)), &invalid_count);
GotoIf(SmiEqual(smi_count, SmiConstant(0)), &return_emptystring); GotoIf(SmiEqual(smi_count, SmiConstant(0)), &return_emptystring);
GotoIf(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)), GotoIf(is_stringempty, &return_emptystring);
&return_emptystring);
GotoIf(SmiGreaterThan(smi_count, SmiConstant(String::kMaxLength)), GotoIf(SmiGreaterThan(smi_count, SmiConstant(String::kMaxLength)),
&invalid_string_length); &invalid_string_length);
Return(CallBuiltin(Builtins::kStringRepeat, context, string, smi_count)); Return(CallBuiltin(Builtins::kStringRepeat, context, string, smi_count));
...@@ -1263,8 +1264,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) { ...@@ -1263,8 +1264,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
&invalid_count); &invalid_count);
GotoIf(Float64LessThan(number_value, Float64Constant(0.0)), GotoIf(Float64LessThan(number_value, Float64Constant(0.0)),
&invalid_count); &invalid_count);
Branch(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)), Branch(is_stringempty, &return_emptystring, &invalid_string_length);
&return_emptystring, &invalid_string_length);
} }
} }
...@@ -1367,16 +1367,16 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) { ...@@ -1367,16 +1367,16 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
TNode<String> const subject_string = ToString_Inline(context, receiver); TNode<String> const subject_string = ToString_Inline(context, receiver);
TNode<String> const search_string = ToString_Inline(context, search); TNode<String> const search_string = ToString_Inline(context, search);
TNode<IntPtrT> const subject_length = LoadStringLengthAsWord(subject_string); TNode<Smi> const subject_length = LoadStringLengthAsSmi(subject_string);
TNode<IntPtrT> const search_length = LoadStringLengthAsWord(search_string); TNode<Smi> const search_length = LoadStringLengthAsSmi(search_string);
// Fast-path single-char {search}, long cons {receiver}, and simple string // Fast-path single-char {search}, long cons {receiver}, and simple string
// {replace}. // {replace}.
{ {
Label next(this); Label next(this);
GotoIfNot(WordEqual(search_length, IntPtrConstant(1)), &next); GotoIfNot(SmiEqual(search_length, SmiConstant(1)), &next);
GotoIfNot(IntPtrGreaterThan(subject_length, IntPtrConstant(0xFF)), &next); GotoIfNot(SmiGreaterThan(subject_length, SmiConstant(0xFF)), &next);
GotoIf(TaggedIsSmi(replace), &next); GotoIf(TaggedIsSmi(replace), &next);
GotoIfNot(IsString(replace), &next); GotoIfNot(IsString(replace), &next);
...@@ -1428,8 +1428,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) { ...@@ -1428,8 +1428,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
BIND(&next); BIND(&next);
} }
TNode<Smi> const match_end_index = TNode<Smi> const match_end_index = SmiAdd(match_start_index, search_length);
SmiAdd(match_start_index, SmiFromIntPtr(search_length));
Callable stringadd_callable = Callable stringadd_callable =
CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
...@@ -1484,7 +1483,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) { ...@@ -1484,7 +1483,7 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
{ {
Node* const suffix = Node* const suffix =
CallBuiltin(Builtins::kStringSubstring, context, subject_string, CallBuiltin(Builtins::kStringSubstring, context, subject_string,
SmiUntag(match_end_index), subject_length); SmiUntag(match_end_index), SmiUntag(subject_length));
Node* const result = Node* const result =
CallStub(stringadd_callable, context, var_result.value(), suffix); CallStub(stringadd_callable, context, var_result.value(), suffix);
Return(result); Return(result);
......
This diff is collapsed.
...@@ -958,12 +958,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -958,12 +958,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name, TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
Label* if_hash_not_computed = nullptr); 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. // Load length field of a String object as intptr_t value.
TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> string); TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> object);
// Load length field of a String object as uint32_t value. // Load length field of a String object as Smi value.
TNode<Uint32T> LoadStringLengthAsWord32(SloppyTNode<String> string); TNode<Smi> LoadStringLengthAsSmi(SloppyTNode<String> object);
// Loads a pointer to the sequential String char array. // Loads a pointer to the sequential String char array.
Node* PointerToSeqStringData(Node* seq_string); Node* PointerToSeqStringData(Node* seq_string);
// Load value field of a JSValue object. // Load value field of a JSValue object.
...@@ -1331,46 +1329,46 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1331,46 +1329,46 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index); TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
// Allocate a SeqOneByteString with the given length. // Allocate a SeqOneByteString with the given length.
TNode<String> AllocateSeqOneByteString(uint32_t length, TNode<String> AllocateSeqOneByteString(int length,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
TNode<String> AllocateSeqOneByteString(Node* context, TNode<Uint32T> length, TNode<String> AllocateSeqOneByteString(Node* context, TNode<Smi> length,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
// Allocate a SeqTwoByteString with the given length. // Allocate a SeqTwoByteString with the given length.
TNode<String> AllocateSeqTwoByteString(uint32_t length, TNode<String> AllocateSeqTwoByteString(int length,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
TNode<String> AllocateSeqTwoByteString(Node* context, TNode<Uint32T> length, TNode<String> AllocateSeqTwoByteString(Node* context, TNode<Smi> length,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
// Allocate a SlicedOneByteString with the given length, parent and offset. // Allocate a SlicedOneByteString with the given length, parent and offset.
// |length| and |offset| are expected to be tagged. // |length| and |offset| are expected to be tagged.
TNode<String> AllocateSlicedOneByteString(TNode<Uint32T> length, TNode<String> AllocateSlicedOneByteString(TNode<Smi> length,
TNode<String> parent, TNode<String> parent,
TNode<Smi> offset); TNode<Smi> offset);
// Allocate a SlicedTwoByteString with the given length, parent and offset. // Allocate a SlicedTwoByteString with the given length, parent and offset.
// |length| and |offset| are expected to be tagged. // |length| and |offset| are expected to be tagged.
TNode<String> AllocateSlicedTwoByteString(TNode<Uint32T> length, TNode<String> AllocateSlicedTwoByteString(TNode<Smi> length,
TNode<String> parent, TNode<String> parent,
TNode<Smi> offset); TNode<Smi> offset);
// Allocate a one-byte ConsString with the given length, first and second // Allocate a one-byte ConsString with the given length, first and second
// parts. |length| is expected to be tagged, and |first| and |second| are // parts. |length| is expected to be tagged, and |first| and |second| are
// expected to be one-byte strings. // expected to be one-byte strings.
TNode<String> AllocateOneByteConsString(TNode<Uint32T> length, TNode<String> AllocateOneByteConsString(TNode<Smi> length,
TNode<String> first, TNode<String> first,
TNode<String> second, TNode<String> second,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
// Allocate a two-byte ConsString with the given length, first and second // Allocate a two-byte ConsString with the given length, first and second
// parts. |length| is expected to be tagged, and |first| and |second| are // parts. |length| is expected to be tagged, and |first| and |second| are
// expected to be two-byte strings. // expected to be two-byte strings.
TNode<String> AllocateTwoByteConsString(TNode<Uint32T> length, TNode<String> AllocateTwoByteConsString(TNode<Smi> length,
TNode<String> first, TNode<String> first,
TNode<String> second, TNode<String> second,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
// Allocate an appropriate one- or two-byte ConsString with the first and // Allocate an appropriate one- or two-byte ConsString with the first and
// second parts specified by |left| and |right|. // 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, TNode<String> right,
AllocationFlags flags = kNone); AllocationFlags flags = kNone);
...@@ -2992,11 +2990,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -2992,11 +2990,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Label* bailout); Label* bailout);
TNode<String> AllocateSlicedString(Heap::RootListIndex map_root_index, TNode<String> AllocateSlicedString(Heap::RootListIndex map_root_index,
TNode<Uint32T> length, TNode<Smi> length, TNode<String> parent,
TNode<String> parent, TNode<Smi> offset); TNode<Smi> offset);
TNode<String> AllocateConsString(Heap::RootListIndex map_root_index, 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); TNode<String> second, AllocationFlags flags);
// Allocate a MutableHeapNumber without initializing its value. // Allocate a MutableHeapNumber without initializing its value.
...@@ -3020,7 +3018,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -3020,7 +3018,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<String> AllocAndCopyStringCharacters(Node* from, TNode<String> AllocAndCopyStringCharacters(Node* from,
Node* from_instance_type, Node* from_instance_type,
TNode<IntPtrT> from_index, TNode<IntPtrT> from_index,
TNode<IntPtrT> character_count); TNode<Smi> character_count);
static const int kElementLoopUnrollThreshold = 8; static const int kElementLoopUnrollThreshold = 8;
......
...@@ -611,7 +611,7 @@ FieldAccess AccessBuilder::ForStringLength() { ...@@ -611,7 +611,7 @@ FieldAccess AccessBuilder::ForStringLength() {
Handle<Name>(), Handle<Name>(),
MaybeHandle<Map>(), MaybeHandle<Map>(),
TypeCache::Get().kStringLengthType, TypeCache::Get().kStringLengthType,
MachineType::Uint32(), MachineType::TaggedSigned(),
kNoWriteBarrier}; kNoWriteBarrier};
return access; return access;
} }
......
...@@ -252,10 +252,6 @@ TNode<Int32T> CodeAssembler::Int32Constant(int32_t value) { ...@@ -252,10 +252,6 @@ TNode<Int32T> CodeAssembler::Int32Constant(int32_t value) {
return UncheckedCast<Int32T>(raw_assembler()->Int32Constant(value)); return UncheckedCast<Int32T>(raw_assembler()->Int32Constant(value));
} }
TNode<Uint32T> CodeAssembler::Uint32Constant(uint32_t value) {
return Unsigned(Int32Constant(bit_cast<int32_t>(value)));
}
TNode<Int64T> CodeAssembler::Int64Constant(int64_t value) { TNode<Int64T> CodeAssembler::Int64Constant(int64_t value) {
return UncheckedCast<Int64T>(raw_assembler()->Int64Constant(value)); return UncheckedCast<Int64T>(raw_assembler()->Int64Constant(value));
} }
......
...@@ -696,7 +696,6 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -696,7 +696,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Constants. // Constants.
TNode<Int32T> Int32Constant(int32_t value); TNode<Int32T> Int32Constant(int32_t value);
TNode<Uint32T> Uint32Constant(uint32_t value);
TNode<Int64T> Int64Constant(int64_t value); TNode<Int64T> Int64Constant(int64_t value);
TNode<IntPtrT> IntPtrConstant(intptr_t value); TNode<IntPtrT> IntPtrConstant(intptr_t value);
TNode<Uint32T> Uint32Constant(uint32_t value) { TNode<Uint32T> Uint32Constant(uint32_t value) {
...@@ -911,11 +910,6 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -911,11 +910,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Int32Add(static_cast<Node*>(left), static_cast<Node*>(right))); 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> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right); TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right); TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
......
...@@ -2790,7 +2790,7 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) { ...@@ -2790,7 +2790,7 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(ConsString::kSize)); Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(ConsString::kSize));
__ StoreField(AccessBuilder::ForMap(), result, result_map); __ StoreField(AccessBuilder::ForMap(), result, result_map);
__ StoreField(AccessBuilder::ForNameHashField(), result, __ StoreField(AccessBuilder::ForNameHashField(), result,
__ Int32Constant(Name::kEmptyHashField)); jsgraph()->Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), result, length); __ StoreField(AccessBuilder::ForStringLength(), result, length);
__ StoreField(AccessBuilder::ForConsStringFirst(), result, first); __ StoreField(AccessBuilder::ForConsStringFirst(), result, first);
__ StoreField(AccessBuilder::ForConsStringSecond(), result, second); __ StoreField(AccessBuilder::ForConsStringSecond(), result, second);
...@@ -3063,9 +3063,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) { ...@@ -3063,9 +3063,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vtrue2, __ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map())); __ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2, __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
__ Int32Constant(Name::kEmptyHashField)); __ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2, __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
__ Int32Constant(1)); __ SmiConstant(1));
__ Store( __ Store(
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
vtrue2, vtrue2,
...@@ -3087,9 +3087,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) { ...@@ -3087,9 +3087,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vfalse1, __ StoreField(AccessBuilder::ForMap(), vfalse1,
__ HeapConstant(factory()->string_map())); __ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1, __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
__ Int32Constant(Name::kEmptyHashField)); __ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse1, __ StoreField(AccessBuilder::ForStringLength(), vfalse1, __ SmiConstant(1));
__ Int32Constant(1));
__ Store( __ Store(
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
vfalse1, vfalse1,
...@@ -3187,9 +3186,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) { ...@@ -3187,9 +3186,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vtrue2, __ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map())); __ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2, __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
__ Int32Constant(Name::kEmptyHashField)); __ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2, __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
__ Int32Constant(1)); __ SmiConstant(1));
__ Store( __ Store(
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
vtrue2, vtrue2,
...@@ -3213,7 +3212,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) { ...@@ -3213,7 +3212,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1, __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
__ IntPtrConstant(Name::kEmptyHashField)); __ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse1, __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
__ Int32Constant(1)); __ SmiConstant(1));
__ Store( __ Store(
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
vfalse1, vfalse1,
...@@ -3258,9 +3257,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) { ...@@ -3258,9 +3257,8 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vfalse0, __ StoreField(AccessBuilder::ForMap(), vfalse0,
__ HeapConstant(factory()->string_map())); __ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse0, __ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
__ Int32Constant(Name::kEmptyHashField)); __ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2));
__ Int32Constant(2));
__ Store( __ Store(
StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
vfalse0, vfalse0,
......
...@@ -121,7 +121,13 @@ class VirtualObject : public Dependable { ...@@ -121,7 +121,13 @@ class VirtualObject : public Dependable {
typedef ZoneVector<Variable>::const_iterator const_iterator; typedef ZoneVector<Variable>::const_iterator const_iterator;
VirtualObject(VariableTracker* var_states, Id id, int size); VirtualObject(VariableTracker* var_states, Id id, int size);
Maybe<Variable> FieldAt(int offset) const { 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()); CHECK(!HasEscaped());
if (offset >= size()) { if (offset >= size()) {
// TODO(tebbi): Reading out-of-bounds can only happen in unreachable // TODO(tebbi): Reading out-of-bounds can only happen in unreachable
......
...@@ -2338,9 +2338,9 @@ class RepresentationSelector { ...@@ -2338,9 +2338,9 @@ class RepresentationSelector {
MachineRepresentation::kTaggedPointer); MachineRepresentation::kTaggedPointer);
} }
case IrOpcode::kNewConsString: { case IrOpcode::kNewConsString: {
ProcessInput(node, 0, UseInfo::TruncatingWord32()); // length ProcessInput(node, 0, UseInfo::TaggedSigned()); // length
ProcessInput(node, 1, UseInfo::AnyTagged()); // first ProcessInput(node, 1, UseInfo::AnyTagged()); // first
ProcessInput(node, 2, UseInfo::AnyTagged()); // second ProcessInput(node, 2, UseInfo::AnyTagged()); // second
SetOutput(node, MachineRepresentation::kTaggedPointer); SetOutput(node, MachineRepresentation::kTaggedPointer);
return; return;
} }
...@@ -2393,7 +2393,8 @@ class RepresentationSelector { ...@@ -2393,7 +2393,8 @@ class RepresentationSelector {
// TODO(bmeurer): The input representation should be TaggedPointer. // TODO(bmeurer): The input representation should be TaggedPointer.
// Fix this once we have a dedicated StringConcat/JSStringAdd // Fix this once we have a dedicated StringConcat/JSStringAdd
// operator, which marks it's output as TaggedPointer properly. // operator, which marks it's output as TaggedPointer properly.
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kWord32); VisitUnop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTaggedSigned);
return; return;
} }
case IrOpcode::kStringSubstring: { case IrOpcode::kStringSubstring: {
......
...@@ -2093,7 +2093,7 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, ...@@ -2093,7 +2093,7 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map,
Comment("check if string"); Comment("check if string");
GotoIfNot(IsStringInstanceType(instance_type), slow); GotoIfNot(IsStringInstanceType(instance_type), slow);
Comment("load string character"); Comment("load string character");
TNode<IntPtrT> length = LoadStringLengthAsWord(receiver); Node* length = LoadAndUntagObjectField(receiver, String::kLengthOffset);
GotoIfNot(UintPtrLessThan(index, length), slow); GotoIfNot(UintPtrLessThan(index, length), slow);
IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1); IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1);
TailCallBuiltin(Builtins::kStringCharAt, NoContextConstant(), receiver, TailCallBuiltin(Builtins::kStringCharAt, NoContextConstant(), receiver,
......
...@@ -19,25 +19,24 @@ CAST_ACCESSOR(Name) ...@@ -19,25 +19,24 @@ CAST_ACCESSOR(Name)
CAST_ACCESSOR(Symbol) CAST_ACCESSOR(Symbol)
ACCESSORS(Symbol, name, Object, kNameOffset) ACCESSORS(Symbol, name, Object, kNameOffset)
INT_ACCESSORS(Symbol, flags, kFlagsOffset) SMI_ACCESSORS(Symbol, flags, kFlagsOffset)
BIT_FIELD_ACCESSORS(Symbol, flags, is_private, Symbol::IsPrivateBit) BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
BIT_FIELD_ACCESSORS(Symbol, flags, is_well_known_symbol, BOOL_ACCESSORS(Symbol, flags, is_well_known_symbol, kWellKnownSymbolBit)
Symbol::IsWellKnownSymbolBit) BOOL_ACCESSORS(Symbol, flags, is_public, kPublicBit)
BIT_FIELD_ACCESSORS(Symbol, flags, is_public, Symbol::IsPublicBit) BOOL_ACCESSORS(Symbol, flags, is_interesting_symbol, kInterestingSymbolBit)
BIT_FIELD_ACCESSORS(Symbol, flags, is_interesting_symbol,
Symbol::IsInterestingSymbolBit)
bool Symbol::is_private_field() const { bool Symbol::is_private_field() const {
bool value = Symbol::IsPrivateFieldBit::decode(flags()); bool value = BooleanBit::get(flags(), kPrivateFieldBit);
DCHECK_IMPLIES(value, is_private()); DCHECK_IMPLIES(value, is_private());
return value; return value;
} }
void Symbol::set_is_private_field() { void Symbol::set_is_private_field() {
int old_value = flags();
// TODO(gsathya): Re-order the bits to have these next to each other // TODO(gsathya): Re-order the bits to have these next to each other
// and just do the bit shifts once. // and just do the bit shifts once.
set_flags(Symbol::IsPrivateBit::update(flags(), true)); set_flags(BooleanBit::set(old_value, kPrivateBit, true) |
set_flags(Symbol::IsPrivateFieldBit::update(flags(), true)); BooleanBit::set(old_value, kPrivateFieldBit, true));
} }
bool Name::IsUniqueName() const { bool Name::IsUniqueName() const {
...@@ -52,6 +51,13 @@ uint32_t Name::hash_field() { ...@@ -52,6 +51,13 @@ uint32_t Name::hash_field() {
void Name::set_hash_field(uint32_t value) { void Name::set_hash_field(uint32_t value) {
WRITE_UINT32_FIELD(this, kHashFieldOffset, 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) { bool Name::Equals(Name* other) {
......
...@@ -67,8 +67,13 @@ class Name : public HeapObject { ...@@ -67,8 +67,13 @@ class Name : public HeapObject {
int NameShortPrint(Vector<char> str); int NameShortPrint(Vector<char> str);
// Layout description. // Layout description.
static const int kHashFieldOffset = HeapObject::kHeaderSize; static const int kHashFieldSlot = HeapObject::kHeaderSize;
static const int kHeaderSize = kHashFieldOffset + kInt32Size; #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 // 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 // and if it is a string that is an array index. The least significant bit
...@@ -176,22 +181,18 @@ class Symbol : public Name { ...@@ -176,22 +181,18 @@ class Symbol : public Name {
DECL_VERIFIER(Symbol) DECL_VERIFIER(Symbol)
// Layout description. // Layout description.
static const int kFlagsOffset = Name::kHeaderSize; static const int kNameOffset = Name::kSize;
static const int kNameOffset = kFlagsOffset + kInt32Size; static const int kFlagsOffset = kNameOffset + kPointerSize;
static const int kSize = kNameOffset + kPointerSize; static const int kSize = kFlagsOffset + kPointerSize;
// Flags layout. // Flags layout.
#define FLAGS_BIT_FIELDS(V, _) \ static const int kPrivateBit = 0;
V(IsPrivateBit, bool, 1, _) \ static const int kWellKnownSymbolBit = 1;
V(IsWellKnownSymbolBit, bool, 1, _) \ static const int kPublicBit = 2;
V(IsPublicBit, bool, 1, _) \ static const int kInterestingSymbolBit = 3;
V(IsInterestingSymbolBit, bool, 1, _) \ static const int kPrivateFieldBit = 4;
V(IsPrivateFieldBit, bool, 1, _)
typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
typedef FixedBodyDescriptor<kNameOffset, kSize, kSize> BodyDescriptor;
// No weak fields. // No weak fields.
typedef BodyDescriptor BodyDescriptorWeak; typedef BodyDescriptor BodyDescriptorWeak;
......
...@@ -19,17 +19,8 @@ ...@@ -19,17 +19,8 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
INT32_ACCESSORS(String, length, kLengthOffset) SMI_ACCESSORS(String, length, kLengthOffset)
SYNCHRONIZED_SMI_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);
}
CAST_ACCESSOR(ConsString) CAST_ACCESSOR(ConsString)
CAST_ACCESSOR(ExternalOneByteString) CAST_ACCESSOR(ExternalOneByteString)
......
...@@ -341,8 +341,8 @@ class String : public Name { ...@@ -341,8 +341,8 @@ class String : public Name {
inline bool IsFlat(); inline bool IsFlat();
// Layout description. // Layout description.
static const int kLengthOffset = Name::kHeaderSize; static const int kLengthOffset = Name::kSize;
static const int kHeaderSize = kLengthOffset + kInt32Size; static const int kSize = kLengthOffset + kPointerSize;
// Max char codes. // Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar; static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
...@@ -360,7 +360,7 @@ class String : public Name { ...@@ -360,7 +360,7 @@ class String : public Name {
// See include/v8.h for the definition. // See include/v8.h for the definition.
static const int kMaxLength = v8::String::kMaxLength; 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"); "Unexpected max String length");
// Max length for computing hash. For strings longer than this limit the // Max length for computing hash. For strings longer than this limit the
...@@ -474,6 +474,9 @@ class SeqString : public String { ...@@ -474,6 +474,9 @@ class SeqString : public String {
public: public:
DECL_CAST(SeqString) DECL_CAST(SeqString)
// Layout description.
static const int kHeaderSize = String::kSize;
// Truncate the string in-place if possible and return the result. // Truncate the string in-place if possible and return the result.
// In case of new_length == 0, the empty string is returned without // In case of new_length == 0, the empty string is returned without
// truncating the original string. // truncating the original string.
...@@ -617,7 +620,7 @@ class ConsString : public String { ...@@ -617,7 +620,7 @@ class ConsString : public String {
DECL_CAST(ConsString) DECL_CAST(ConsString)
// Layout description. // 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 kSecondOffset = kFirstOffset + kPointerSize;
static const int kSize = kSecondOffset + kPointerSize; static const int kSize = kSecondOffset + kPointerSize;
...@@ -656,7 +659,7 @@ class ThinString : public String { ...@@ -656,7 +659,7 @@ class ThinString : public String {
DECL_VERIFIER(ThinString) DECL_VERIFIER(ThinString)
// Layout description. // Layout description.
static const int kActualOffset = String::kHeaderSize; static const int kActualOffset = String::kSize;
static const int kSize = kActualOffset + kPointerSize; static const int kSize = kActualOffset + kPointerSize;
typedef FixedBodyDescriptor<kActualOffset, kSize, kSize> BodyDescriptor; typedef FixedBodyDescriptor<kActualOffset, kSize, kSize> BodyDescriptor;
...@@ -693,7 +696,7 @@ class SlicedString : public String { ...@@ -693,7 +696,7 @@ class SlicedString : public String {
DECL_CAST(SlicedString) DECL_CAST(SlicedString)
// Layout description. // 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 kOffsetOffset = kParentOffset + kPointerSize;
static const int kSize = kOffsetOffset + kPointerSize; static const int kSize = kOffsetOffset + kPointerSize;
...@@ -726,7 +729,7 @@ class ExternalString : public String { ...@@ -726,7 +729,7 @@ class ExternalString : public String {
DECL_CAST(ExternalString) DECL_CAST(ExternalString)
// Layout description. // 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 kUncachedSize = kResourceOffset + kPointerSize;
static const int kResourceDataOffset = kResourceOffset + kPointerSize; static const int kResourceDataOffset = kResourceOffset + kPointerSize;
static const int kSize = kResourceDataOffset + kPointerSize; static const int kSize = kResourceDataOffset + kPointerSize;
......
This diff is collapsed.
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