[runtime] Change backing store of LayoutDescriptor to ByteArray.
BUG=v8:6277 Change-Id: I80314e6c5146e1f5021d07081b9eda3da5da6834 Reviewed-on: https://chromium-review.googlesource.com/518047 Commit-Queue: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#45632}
This commit is contained in:
parent
0f11aa626c
commit
d8a42e4c09
@ -153,6 +153,7 @@ const int kShortSize = sizeof(short); // NOLINT
|
|||||||
const int kIntSize = sizeof(int);
|
const int kIntSize = sizeof(int);
|
||||||
const int kInt32Size = sizeof(int32_t);
|
const int kInt32Size = sizeof(int32_t);
|
||||||
const int kInt64Size = sizeof(int64_t);
|
const int kInt64Size = sizeof(int64_t);
|
||||||
|
const int kUInt32Size = sizeof(uint32_t);
|
||||||
const int kSizetSize = sizeof(size_t);
|
const int kSizetSize = sizeof(size_t);
|
||||||
const int kFloatSize = sizeof(float);
|
const int kFloatSize = sizeof(float);
|
||||||
const int kDoubleSize = sizeof(double);
|
const int kDoubleSize = sizeof(double);
|
||||||
|
@ -20,9 +20,11 @@ Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) {
|
|||||||
// The whole bit vector fits into a smi.
|
// The whole bit vector fits into a smi.
|
||||||
return handle(LayoutDescriptor::FromSmi(Smi::kZero), isolate);
|
return handle(LayoutDescriptor::FromSmi(Smi::kZero), isolate);
|
||||||
}
|
}
|
||||||
length = GetSlowModeBackingStoreLength(length);
|
int backing_store_length = GetSlowModeBackingStoreLength(length);
|
||||||
return Handle<LayoutDescriptor>::cast(isolate->factory()->NewFixedTypedArray(
|
Handle<LayoutDescriptor> result = Handle<LayoutDescriptor>::cast(
|
||||||
length, kExternalUint32Array, true));
|
isolate->factory()->NewByteArray(backing_store_length));
|
||||||
|
memset(result->GetDataStartAddress(), 0, result->DataSize());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -47,11 +49,11 @@ bool LayoutDescriptor::GetIndexes(int field_index, int* layout_word_index,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*layout_word_index = field_index / kNumberOfBits;
|
*layout_word_index = field_index / kBitsPerLayoutWord;
|
||||||
CHECK((!IsSmi() && (*layout_word_index < length())) ||
|
CHECK((!IsSmi() && (*layout_word_index < length())) ||
|
||||||
(IsSmi() && (*layout_word_index < 1)));
|
(IsSmi() && (*layout_word_index < 1)));
|
||||||
|
|
||||||
*layout_bit_index = field_index % kNumberOfBits;
|
*layout_bit_index = field_index % kBitsPerLayoutWord;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,13 +74,13 @@ LayoutDescriptor* LayoutDescriptor::SetTagged(int field_index, bool tagged) {
|
|||||||
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
||||||
|
|
||||||
if (IsSlowLayout()) {
|
if (IsSlowLayout()) {
|
||||||
uint32_t value = get_scalar(layout_word_index);
|
uint32_t value = get_layout_word(layout_word_index);
|
||||||
if (tagged) {
|
if (tagged) {
|
||||||
value &= ~layout_mask;
|
value &= ~layout_mask;
|
||||||
} else {
|
} else {
|
||||||
value |= layout_mask;
|
value |= layout_mask;
|
||||||
}
|
}
|
||||||
set(layout_word_index, value);
|
set_layout_word(layout_word_index, value);
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
|
uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
|
||||||
@ -105,7 +107,7 @@ bool LayoutDescriptor::IsTagged(int field_index) {
|
|||||||
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
||||||
|
|
||||||
if (IsSlowLayout()) {
|
if (IsSlowLayout()) {
|
||||||
uint32_t value = get_scalar(layout_word_index);
|
uint32_t value = get_layout_word(layout_word_index);
|
||||||
return (value & layout_mask) == 0;
|
return (value & layout_mask) == 0;
|
||||||
} else {
|
} else {
|
||||||
uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
|
uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
|
||||||
@ -128,7 +130,7 @@ bool LayoutDescriptor::IsSlowLayout() { return !IsSmi(); }
|
|||||||
|
|
||||||
|
|
||||||
int LayoutDescriptor::capacity() {
|
int LayoutDescriptor::capacity() {
|
||||||
return IsSlowLayout() ? (length() * kNumberOfBits) : kSmiValueSize;
|
return IsSlowLayout() ? (length() * kBitsPerByte) : kSmiValueSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -147,20 +149,12 @@ LayoutDescriptor* LayoutDescriptor::cast_gc_safe(Object* object) {
|
|||||||
return LayoutDescriptor::cast(object);
|
return LayoutDescriptor::cast(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LayoutDescriptor::GetSlowModeBackingStoreLength(int length) {
|
int LayoutDescriptor::GetSlowModeBackingStoreLength(int length) {
|
||||||
length = (length + kNumberOfBits - 1) / kNumberOfBits;
|
|
||||||
DCHECK_LT(0, length);
|
DCHECK_LT(0, length);
|
||||||
|
// We allocate kPointerSize rounded blocks of memory anyway so we increase
|
||||||
if (SmiValuesAre32Bits() && (length & 1)) {
|
// the length of allocated array to utilize that "lost" space which could
|
||||||
// On 64-bit systems if the length is odd then the half-word space would be
|
// also help to avoid layout descriptor reallocations.
|
||||||
// lost anyway (due to alignment and the fact that we are allocating
|
return RoundUp(length, kBitsPerByte * kPointerSize) / kBitsPerByte;
|
||||||
// uint32-typed array), so we increase the length of allocated array
|
|
||||||
// to utilize that "lost" space which could also help to avoid layout
|
|
||||||
// descriptor reallocations.
|
|
||||||
++length;
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,14 +107,15 @@ Handle<LayoutDescriptor> LayoutDescriptor::EnsureCapacity(
|
|||||||
DCHECK(new_layout_descriptor->IsSlowLayout());
|
DCHECK(new_layout_descriptor->IsSlowLayout());
|
||||||
|
|
||||||
if (layout_descriptor->IsSlowLayout()) {
|
if (layout_descriptor->IsSlowLayout()) {
|
||||||
memcpy(new_layout_descriptor->DataPtr(), layout_descriptor->DataPtr(),
|
memcpy(new_layout_descriptor->GetDataStartAddress(),
|
||||||
|
layout_descriptor->GetDataStartAddress(),
|
||||||
layout_descriptor->DataSize());
|
layout_descriptor->DataSize());
|
||||||
return new_layout_descriptor;
|
return new_layout_descriptor;
|
||||||
} else {
|
} else {
|
||||||
// Fast layout.
|
// Fast layout.
|
||||||
uint32_t value =
|
uint32_t value =
|
||||||
static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value());
|
static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value());
|
||||||
new_layout_descriptor->set(0, value);
|
new_layout_descriptor->set_layout_word(0, value);
|
||||||
return new_layout_descriptor;
|
return new_layout_descriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +140,7 @@ bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length,
|
|||||||
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
|
||||||
|
|
||||||
uint32_t value = IsSlowLayout()
|
uint32_t value = IsSlowLayout()
|
||||||
? get_scalar(layout_word_index)
|
? get_layout_word(layout_word_index)
|
||||||
: static_cast<uint32_t>(Smi::cast(this)->value());
|
: static_cast<uint32_t>(Smi::cast(this)->value());
|
||||||
|
|
||||||
bool is_tagged = (value & layout_mask) == 0;
|
bool is_tagged = (value & layout_mask) == 0;
|
||||||
@ -147,21 +148,21 @@ bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length,
|
|||||||
value = value & ~(layout_mask - 1); // Clear bits we are not interested in.
|
value = value & ~(layout_mask - 1); // Clear bits we are not interested in.
|
||||||
int sequence_length = CountTrailingZeros32(value) - layout_bit_index;
|
int sequence_length = CountTrailingZeros32(value) - layout_bit_index;
|
||||||
|
|
||||||
if (layout_bit_index + sequence_length == kNumberOfBits) {
|
if (layout_bit_index + sequence_length == kBitsPerLayoutWord) {
|
||||||
// This is a contiguous sequence till the end of current word, proceed
|
// This is a contiguous sequence till the end of current word, proceed
|
||||||
// counting in the subsequent words.
|
// counting in the subsequent words.
|
||||||
if (IsSlowLayout()) {
|
if (IsSlowLayout()) {
|
||||||
int len = length();
|
|
||||||
++layout_word_index;
|
++layout_word_index;
|
||||||
for (; layout_word_index < len; layout_word_index++) {
|
int num_words = number_of_layout_words();
|
||||||
value = get_scalar(layout_word_index);
|
for (; layout_word_index < num_words; layout_word_index++) {
|
||||||
|
value = get_layout_word(layout_word_index);
|
||||||
bool cur_is_tagged = (value & 1) == 0;
|
bool cur_is_tagged = (value & 1) == 0;
|
||||||
if (cur_is_tagged != is_tagged) break;
|
if (cur_is_tagged != is_tagged) break;
|
||||||
if (!is_tagged) value = ~value; // Count set bits instead.
|
if (!is_tagged) value = ~value; // Count set bits instead.
|
||||||
int cur_sequence_length = CountTrailingZeros32(value);
|
int cur_sequence_length = CountTrailingZeros32(value);
|
||||||
sequence_length += cur_sequence_length;
|
sequence_length += cur_sequence_length;
|
||||||
if (sequence_length >= max_sequence_length) break;
|
if (sequence_length >= max_sequence_length) break;
|
||||||
if (cur_sequence_length != kNumberOfBits) break;
|
if (cur_sequence_length != kBitsPerLayoutWord) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_tagged && (field_index + sequence_length == capacity())) {
|
if (is_tagged && (field_index + sequence_length == capacity())) {
|
||||||
@ -241,14 +242,15 @@ LayoutDescriptor* LayoutDescriptor::Trim(Heap* heap, Map* map,
|
|||||||
DCHECK_LT(kSmiValueSize, layout_descriptor_length);
|
DCHECK_LT(kSmiValueSize, layout_descriptor_length);
|
||||||
|
|
||||||
// Trim, clean and reinitialize this slow-mode layout descriptor.
|
// Trim, clean and reinitialize this slow-mode layout descriptor.
|
||||||
int array_length = GetSlowModeBackingStoreLength(layout_descriptor_length);
|
int new_backing_store_length =
|
||||||
int current_length = length();
|
GetSlowModeBackingStoreLength(layout_descriptor_length);
|
||||||
if (current_length != array_length) {
|
int backing_store_length = length();
|
||||||
DCHECK_LT(array_length, current_length);
|
if (new_backing_store_length != backing_store_length) {
|
||||||
int delta = current_length - array_length;
|
DCHECK_LT(new_backing_store_length, backing_store_length);
|
||||||
|
int delta = backing_store_length - new_backing_store_length;
|
||||||
heap->RightTrimFixedArray(this, delta);
|
heap->RightTrimFixedArray(this, delta);
|
||||||
}
|
}
|
||||||
memset(DataPtr(), 0, DataSize());
|
memset(GetDataStartAddress(), 0, DataSize());
|
||||||
LayoutDescriptor* layout_descriptor =
|
LayoutDescriptor* layout_descriptor =
|
||||||
Initialize(this, map, descriptors, num_descriptors);
|
Initialize(this, map, descriptors, num_descriptors);
|
||||||
DCHECK_EQ(this, layout_descriptor);
|
DCHECK_EQ(this, layout_descriptor);
|
||||||
|
@ -21,8 +21,10 @@ namespace internal {
|
|||||||
// Otherwise the field is considered tagged. If the queried bit lays "outside"
|
// Otherwise the field is considered tagged. If the queried bit lays "outside"
|
||||||
// of the descriptor then the field is also considered tagged.
|
// of the descriptor then the field is also considered tagged.
|
||||||
// Once a layout descriptor is created it is allowed only to append properties
|
// Once a layout descriptor is created it is allowed only to append properties
|
||||||
// to it.
|
// to it. GC uses layout descriptors to iterate objects. Avoid heap pointers
|
||||||
class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
|
// in a layout descriptor because they can lead to data races in GC when
|
||||||
|
// GC moves objects in parallel.
|
||||||
|
class LayoutDescriptor : public ByteArray {
|
||||||
public:
|
public:
|
||||||
V8_INLINE bool IsTagged(int field_index);
|
V8_INLINE bool IsTagged(int field_index);
|
||||||
|
|
||||||
@ -94,7 +96,10 @@ class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
|
|||||||
LayoutDescriptor* SetTaggedForTesting(int field_index, bool tagged);
|
LayoutDescriptor* SetTaggedForTesting(int field_index, bool tagged);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int kNumberOfBits = 32;
|
static const int kBitsPerLayoutWord = 32;
|
||||||
|
int number_of_layout_words() { return length() / kUInt32Size; }
|
||||||
|
uint32_t get_layout_word(int index) const { return get_uint32(index); }
|
||||||
|
void set_layout_word(int index, uint32_t value) { set_uint32(index, value); }
|
||||||
|
|
||||||
V8_INLINE static Handle<LayoutDescriptor> New(Isolate* isolate, int length);
|
V8_INLINE static Handle<LayoutDescriptor> New(Isolate* isolate, int length);
|
||||||
V8_INLINE static LayoutDescriptor* FromSmi(Smi* smi);
|
V8_INLINE static LayoutDescriptor* FromSmi(Smi* smi);
|
||||||
|
@ -310,9 +310,7 @@ bool HeapObject::IsArrayList() const { return IsFixedArray(); }
|
|||||||
|
|
||||||
bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArray(); }
|
bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArray(); }
|
||||||
|
|
||||||
bool Object::IsLayoutDescriptor() const {
|
bool Object::IsLayoutDescriptor() const { return IsSmi() || IsByteArray(); }
|
||||||
return IsSmi() || IsFixedTypedArrayBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HeapObject::IsFeedbackVector() const {
|
bool HeapObject::IsFeedbackVector() const {
|
||||||
return map() == GetHeap()->feedback_vector_map();
|
return map() == GetHeap()->feedback_vector_map();
|
||||||
@ -3694,7 +3692,7 @@ void StringCharacterStream::VisitTwoByteString(
|
|||||||
|
|
||||||
int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
|
int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
|
||||||
|
|
||||||
byte ByteArray::get(int index) {
|
byte ByteArray::get(int index) const {
|
||||||
DCHECK(index >= 0 && index < this->length());
|
DCHECK(index >= 0 && index < this->length());
|
||||||
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
|
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
|
||||||
}
|
}
|
||||||
@ -3718,7 +3716,7 @@ void ByteArray::copy_out(int index, byte* buffer, int length) {
|
|||||||
memcpy(buffer, src_addr, length);
|
memcpy(buffer, src_addr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ByteArray::get_int(int index) {
|
int ByteArray::get_int(int index) const {
|
||||||
DCHECK(index >= 0 && index < this->length() / kIntSize);
|
DCHECK(index >= 0 && index < this->length() / kIntSize);
|
||||||
return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
|
return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
|
||||||
}
|
}
|
||||||
@ -3728,11 +3726,22 @@ void ByteArray::set_int(int index, int value) {
|
|||||||
WRITE_INT_FIELD(this, kHeaderSize + index * kIntSize, value);
|
WRITE_INT_FIELD(this, kHeaderSize + index * kIntSize, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ByteArray::get_uint32(int index) const {
|
||||||
|
DCHECK(index >= 0 && index < this->length() / kUInt32Size);
|
||||||
|
return READ_UINT32_FIELD(this, kHeaderSize + index * kUInt32Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteArray::set_uint32(int index, uint32_t value) {
|
||||||
|
DCHECK(index >= 0 && index < this->length() / kUInt32Size);
|
||||||
|
WRITE_UINT32_FIELD(this, kHeaderSize + index * kUInt32Size, value);
|
||||||
|
}
|
||||||
|
|
||||||
ByteArray* ByteArray::FromDataStartAddress(Address address) {
|
ByteArray* ByteArray::FromDataStartAddress(Address address) {
|
||||||
DCHECK_TAG_ALIGNED(address);
|
DCHECK_TAG_ALIGNED(address);
|
||||||
return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
|
return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ByteArray::DataSize() const { return RoundUp(length(), kPointerSize); }
|
||||||
|
|
||||||
int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
|
int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
|
||||||
|
|
||||||
|
@ -1526,10 +1526,10 @@ void LayoutDescriptor::Print(std::ostream& os) { // NOLINT
|
|||||||
os << "<uninitialized>";
|
os << "<uninitialized>";
|
||||||
} else {
|
} else {
|
||||||
os << "slow";
|
os << "slow";
|
||||||
int len = length();
|
int num_words = number_of_layout_words();
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < num_words; i++) {
|
||||||
if (i > 0) os << " |";
|
if (i > 0) os << " |";
|
||||||
PrintBitMask(os, get_scalar(i));
|
PrintBitMask(os, get_layout_word(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
|
@ -3187,7 +3187,7 @@ class ByteArray: public FixedArrayBase {
|
|||||||
inline int Size();
|
inline int Size();
|
||||||
|
|
||||||
// Setter and getter.
|
// Setter and getter.
|
||||||
inline byte get(int index);
|
inline byte get(int index) const;
|
||||||
inline void set(int index, byte value);
|
inline void set(int index, byte value);
|
||||||
|
|
||||||
// Copy in / copy out whole byte slices.
|
// Copy in / copy out whole byte slices.
|
||||||
@ -3195,9 +3195,12 @@ class ByteArray: public FixedArrayBase {
|
|||||||
inline void copy_in(int index, const byte* buffer, int length);
|
inline void copy_in(int index, const byte* buffer, int length);
|
||||||
|
|
||||||
// Treat contents as an int array.
|
// Treat contents as an int array.
|
||||||
inline int get_int(int index);
|
inline int get_int(int index) const;
|
||||||
inline void set_int(int index, int value);
|
inline void set_int(int index, int value);
|
||||||
|
|
||||||
|
inline uint32_t get_uint32(int index) const;
|
||||||
|
inline void set_uint32(int index, uint32_t value);
|
||||||
|
|
||||||
static int SizeFor(int length) {
|
static int SizeFor(int length) {
|
||||||
return OBJECT_POINTER_ALIGN(kHeaderSize + length);
|
return OBJECT_POINTER_ALIGN(kHeaderSize + length);
|
||||||
}
|
}
|
||||||
@ -3214,6 +3217,8 @@ class ByteArray: public FixedArrayBase {
|
|||||||
// Returns data start address.
|
// Returns data start address.
|
||||||
inline Address GetDataStartAddress();
|
inline Address GetDataStartAddress();
|
||||||
|
|
||||||
|
inline int DataSize() const;
|
||||||
|
|
||||||
// Returns a pointer to the ByteArray object for a given data start address.
|
// Returns a pointer to the ByteArray object for a given data start address.
|
||||||
static inline ByteArray* FromDataStartAddress(Address address);
|
static inline ByteArray* FromDataStartAddress(Address address);
|
||||||
|
|
||||||
|
@ -602,7 +602,7 @@ TEST(LayoutDescriptorCreateNewSlow) {
|
|||||||
LayoutDescriptor* layout_desc = *layout_descriptor;
|
LayoutDescriptor* layout_desc = *layout_descriptor;
|
||||||
CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
|
CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
|
||||||
CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
|
CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
|
||||||
CHECK(layout_descriptor->IsFixedTypedArrayBase());
|
CHECK(layout_desc->IsSlowLayout());
|
||||||
// Now make it look like a forwarding pointer to layout_descriptor_copy.
|
// Now make it look like a forwarding pointer to layout_descriptor_copy.
|
||||||
MapWord map_word = layout_desc->map_word();
|
MapWord map_word = layout_desc->map_word();
|
||||||
CHECK(!map_word.IsForwardingAddress());
|
CHECK(!map_word.IsForwardingAddress());
|
||||||
@ -982,7 +982,7 @@ TEST(DescriptorArrayTrimming) {
|
|||||||
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true));
|
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true));
|
||||||
CHECK(map->layout_descriptor()->IsSlowLayout());
|
CHECK(map->layout_descriptor()->IsSlowLayout());
|
||||||
CHECK(map->owns_descriptors());
|
CHECK(map->owns_descriptors());
|
||||||
CHECK_EQ(2, map->layout_descriptor()->length());
|
CHECK_EQ(8, map->layout_descriptor()->length());
|
||||||
|
|
||||||
{
|
{
|
||||||
// Add transitions to double fields.
|
// Add transitions to double fields.
|
||||||
@ -1002,7 +1002,7 @@ TEST(DescriptorArrayTrimming) {
|
|||||||
CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor());
|
CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor());
|
||||||
}
|
}
|
||||||
CHECK(map->layout_descriptor()->IsSlowLayout());
|
CHECK(map->layout_descriptor()->IsSlowLayout());
|
||||||
CHECK_EQ(4, map->layout_descriptor()->length());
|
CHECK_EQ(16, map->layout_descriptor()->length());
|
||||||
|
|
||||||
// The unused tail of the layout descriptor is now "durty" because of sharing.
|
// The unused tail of the layout descriptor is now "durty" because of sharing.
|
||||||
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
|
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
|
||||||
@ -1022,7 +1022,7 @@ TEST(DescriptorArrayTrimming) {
|
|||||||
CHECK_EQ(map->NumberOfOwnDescriptors(),
|
CHECK_EQ(map->NumberOfOwnDescriptors(),
|
||||||
map->instance_descriptors()->number_of_descriptors());
|
map->instance_descriptors()->number_of_descriptors());
|
||||||
CHECK(map->layout_descriptor()->IsSlowLayout());
|
CHECK(map->layout_descriptor()->IsSlowLayout());
|
||||||
CHECK_EQ(2, map->layout_descriptor()->length());
|
CHECK_EQ(8, map->layout_descriptor()->length());
|
||||||
|
|
||||||
{
|
{
|
||||||
// Add transitions to tagged fields.
|
// Add transitions to tagged fields.
|
||||||
|
Loading…
Reference in New Issue
Block a user