diff --git a/include/v8.h b/include/v8.h index 4cd77fd934..f3e8c33c52 100644 --- a/include/v8.h +++ b/include/v8.h @@ -9152,7 +9152,7 @@ class Internals { V8_INLINE static int GetInstanceType(const internal::Object* obj) { typedef internal::Object O; O* map = ReadField(obj, kHeapObjectMapOffset); - return ReadField(map, kMapInstanceTypeOffset); + return ReadField(map, kMapInstanceTypeOffset); } V8_INLINE static int GetOddballKind(const internal::Object* obj) { diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 2c26f7ad89..8575b0336c 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -1580,7 +1580,7 @@ void MacroAssembler::CompareObjectType(Register object, void MacroAssembler::CompareInstanceType(Register map, Register type_reg, InstanceType type) { - ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + ldrh(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); cmp(type_reg, Operand(type)); } diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc index 0f9ddced80..885ee0875f 100644 --- a/src/arm64/macro-assembler-arm64.cc +++ b/src/arm64/macro-assembler-arm64.cc @@ -1678,12 +1678,9 @@ void MacroAssembler::AssertGeneratorObject(Register object) { Register temp = temps.AcquireX(); Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); - // Load instance type - Ldrb(temp, FieldMemOperand(temp, Map::kInstanceTypeOffset)); - Label do_check; - // Check if JSGeneratorObject - Cmp(temp, JS_GENERATOR_OBJECT_TYPE); + // Load instance type and check if JSGeneratorObject + CompareInstanceType(temp, temp, JS_GENERATOR_OBJECT_TYPE); B(eq, &do_check); // Check if JSAsyncGeneratorObject @@ -2712,7 +2709,7 @@ void MacroAssembler::CompareObjectType(Register object, void MacroAssembler::CompareInstanceType(Register map, Register type_reg, InstanceType type) { - Ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + Ldrh(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); Cmp(type_reg, type); } diff --git a/src/builtins/mips/builtins-mips.cc b/src/builtins/mips/builtins-mips.cc index 8738e08b21..167bc1b829 100644 --- a/src/builtins/mips/builtins-mips.cc +++ b/src/builtins/mips/builtins-mips.cc @@ -2315,8 +2315,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { __ JumpIfSmi(a1, &non_constructor); // Dispatch based on instance type. - __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); - __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); + __ GetObjectType(a1, t1, t2); __ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction), RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); diff --git a/src/builtins/mips64/builtins-mips64.cc b/src/builtins/mips64/builtins-mips64.cc index 2e8b67015f..811ae637ad 100644 --- a/src/builtins/mips64/builtins-mips64.cc +++ b/src/builtins/mips64/builtins-mips64.cc @@ -2334,8 +2334,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { __ JumpIfSmi(a1, &non_constructor); // Dispatch based on instance type. - __ Ld(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); - __ Lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); + __ GetObjectType(a1, t1, t2); __ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction), RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index a756be8c1e..fc73a7505a 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -1330,7 +1330,7 @@ TNode CodeStubAssembler::LoadMapBitField3(SloppyTNode map) { TNode CodeStubAssembler::LoadMapInstanceType(SloppyTNode map) { return UncheckedCast( - LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8())); + LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint16())); } TNode CodeStubAssembler::LoadMapElementsKind(SloppyTNode map) { diff --git a/src/compiler/access-builder.cc b/src/compiler/access-builder.cc index b6259492ad..ac4fc4363b 100644 --- a/src/compiler/access-builder.cc +++ b/src/compiler/access-builder.cc @@ -550,7 +550,7 @@ FieldAccess AccessBuilder::ForMapDescriptors() { FieldAccess AccessBuilder::ForMapInstanceType() { FieldAccess access = { kTaggedBase, Map::kInstanceTypeOffset, Handle(), - MaybeHandle(), TypeCache::Get().kUint8, MachineType::Uint8(), + MaybeHandle(), TypeCache::Get().kUint16, MachineType::Uint16(), kNoWriteBarrier}; return access; } diff --git a/src/globals.h b/src/globals.h index f9dfeeb824..c4947b9cbe 100644 --- a/src/globals.h +++ b/src/globals.h @@ -151,6 +151,7 @@ const int kMinUInt32 = 0; const int kUInt8Size = sizeof(uint8_t); const int kCharSize = sizeof(char); const int kShortSize = sizeof(short); // NOLINT +const int kUInt16Size = sizeof(uint16_t); const int kIntSize = sizeof(int); const int kInt32Size = sizeof(int32_t); const int kInt64Size = sizeof(int64_t); diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 1946c3ad6e..d72a1db566 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -2398,7 +2398,6 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, map->set_map_after_allocation(reinterpret_cast(root(kMetaMapRootIndex)), SKIP_WRITE_BARRIER); map->set_instance_type(instance_type); - WRITE_BYTE_FIELD(map, Map::kSoonToBeInstanceTypeTooOffset, 0); map->set_instance_size(instance_size); // Initialize to only containing tagged fields. if (FLAG_unbox_double_fields) { @@ -2440,7 +2439,6 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type, map->set_prototype(null_value(), SKIP_WRITE_BARRIER); map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER); map->set_instance_size(instance_size); - WRITE_BYTE_FIELD(map, Map::kSoonToBeInstanceTypeTooOffset, 0); if (map->IsJSObjectMap()) { map->SetInObjectPropertiesStartInWords(instance_size / kPointerSize - inobject_properties); diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index 2e007f82b8..6b39b43b52 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -483,7 +483,7 @@ void MacroAssembler::CmpObjectType(Register heap_object, void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { - cmpb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); + cmpw(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); } void MacroAssembler::AssertSmi(Register object) { diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index 2a4c84d199..de5de02f09 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -4118,7 +4118,7 @@ void MacroAssembler::GetObjectType(Register object, Register map, Register type_reg) { lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); - lbu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + lhu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); } diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc index 898a7130ad..25bc8baf80 100644 --- a/src/mips64/macro-assembler-mips64.cc +++ b/src/mips64/macro-assembler-mips64.cc @@ -4396,7 +4396,7 @@ void MacroAssembler::GetObjectType(Register object, Register map, Register type_reg) { Ld(map, FieldMemOperand(object, HeapObject::kMapOffset)); - Lbu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + Lhu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); } diff --git a/src/objects-inl.h b/src/objects-inl.h index 98af174beb..3d5ad4c974 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -3132,12 +3132,13 @@ int HeapObject::SizeFromMap(Map* map) const { } InstanceType Map::instance_type() const { - return static_cast(READ_BYTE_FIELD(this, kInstanceTypeOffset)); + return static_cast( + READ_UINT16_FIELD(this, kInstanceTypeOffset)); } void Map::set_instance_type(InstanceType value) { - WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value); + WRITE_UINT16_FIELD(this, kInstanceTypeOffset, value); } int Map::UnusedPropertyFields() const { diff --git a/src/objects.h b/src/objects.h index 22b2692b36..8decea50b2 100644 --- a/src/objects.h +++ b/src/objects.h @@ -554,12 +554,11 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1; V(MODULE_INFO_ENTRY, ModuleInfoEntry, module_info_entry) \ V(ASYNC_GENERATOR_REQUEST, AsyncGeneratorRequest, async_generator_request) -// We use the full 8 bits of the instance_type field to encode heap object -// instance types. The high-order bit (bit 7) is set if the object is not a -// string, and cleared if it is a string. -const uint32_t kIsNotStringMask = 0x80; +// We use the full 16 bits of the instance_type field to encode heap object +// instance types. All the high-order bits (bit 7-15) are cleared if the object +// is a string, and contain set bits if it is not a string. +const uint32_t kIsNotStringMask = 0xff80; const uint32_t kStringTag = 0x0; -const uint32_t kNotStringTag = 0x80; // Bit 6 indicates that the object is an internalized string (if set) or not. // Bit 7 has to be clear as well. @@ -619,7 +618,7 @@ static inline bool IsShortcutCandidate(int type) { return ((type & kShortcutTypeMask) == kShortcutTypeTag); } -enum InstanceType : uint8_t { +enum InstanceType : uint16_t { // String types. INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag | kInternalizedTag, // FIRST_PRIMITIVE_TYPE @@ -670,7 +669,10 @@ enum InstanceType : uint8_t { kOneByteStringTag | kThinStringTag | kNotInternalizedTag, // Non-string names - SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE + SYMBOL_TYPE = + 1 + (kIsNotInternalizedMask | kShortExternalStringMask | + kOneByteDataHintMask | kStringEncodingMask | + kStringRepresentationMask), // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE // Other primitives (cannot contain non-map-word pointers to heap objects). HEAP_NUMBER_TYPE, @@ -839,6 +841,7 @@ enum InstanceType : uint8_t { LAST_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE, }; +STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag); STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType); STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType); STATIC_ASSERT(JS_SPECIAL_API_OBJECT_TYPE == Internals::kJSSpecialApiObjectType); diff --git a/src/objects/map.h b/src/objects/map.h index e3038f51e4..d1882f0776 100644 --- a/src/objects/map.h +++ b/src/objects/map.h @@ -105,10 +105,7 @@ typedef std::vector> MapHandles; // +----+----------+---------------------------------------------+ // | Int | The second int field | // `---+----------+---------------------------------------------+ -// | Byte | [instance_type] | -// +----------+---------------------------------------------+ -// | Byte | Free byte, soon will be used as a second | -// | | byte of [instance_type]. | +// | Short | [instance_type] | // +----------+---------------------------------------------+ // | Byte | [bit_field] | // | | - has_non_instance_prototype (bit 0) | @@ -730,9 +727,7 @@ class Map : public HeapObject { V(kInObjectPropertiesStartOrConstructorFunctionIndexOffset, kUInt8Size) \ V(kUsedOrUnusedInstanceSizeInWordsOffset, kUInt8Size) \ V(kVisitorIdOffset, kUInt8Size) \ - V(kInstanceTypeOffset, kUInt8Size) \ - /* TODO(ishell): Extend kInstanceTypeOffset field to two bytes. */ \ - V(kSoonToBeInstanceTypeTooOffset, kUInt8Size) \ + V(kInstanceTypeOffset, kUInt16Size) \ V(kBitFieldOffset, kUInt8Size) \ V(kBitField2Offset, kUInt8Size) \ V(kBitField3Offset, kUInt32Size) \ diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc index 12b27843e5..75e176c09c 100644 --- a/src/ppc/macro-assembler-ppc.cc +++ b/src/ppc/macro-assembler-ppc.cc @@ -1365,8 +1365,8 @@ void MacroAssembler::CompareObjectType(Register object, Register map, void MacroAssembler::CompareInstanceType(Register map, Register type_reg, InstanceType type) { STATIC_ASSERT(Map::kInstanceTypeOffset < 4096); - STATIC_ASSERT(LAST_TYPE < 256); - lbz(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + STATIC_ASSERT(LAST_TYPE <= 0xffff); + lhz(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); cmpi(type_reg, Operand(type)); } diff --git a/src/s390/macro-assembler-s390.cc b/src/s390/macro-assembler-s390.cc index 8f844666a6..44f1ba5abb 100644 --- a/src/s390/macro-assembler-s390.cc +++ b/src/s390/macro-assembler-s390.cc @@ -1392,8 +1392,8 @@ void MacroAssembler::CompareObjectType(Register object, Register map, void MacroAssembler::CompareInstanceType(Register map, Register type_reg, InstanceType type) { STATIC_ASSERT(Map::kInstanceTypeOffset < 4096); - STATIC_ASSERT(LAST_TYPE < 256); - LoadlB(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + STATIC_ASSERT(LAST_TYPE <= 0xffff); + LoadHalfWordP(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); CmpP(type_reg, Operand(type)); } diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 98a6c23a22..e305aaa1a5 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -1962,8 +1962,7 @@ void MacroAssembler::CmpObjectType(Register heap_object, void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { - cmpb(FieldOperand(map, Map::kInstanceTypeOffset), - Immediate(static_cast(type))); + cmpw(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); } void TurboAssembler::SlowTruncateToIDelayed(Zone* zone, Register result_reg) { diff --git a/test/unittests/object-unittest.cc b/test/unittests/object-unittest.cc index aff7e47aa7..47772a0f20 100644 --- a/test/unittests/object-unittest.cc +++ b/test/unittests/object-unittest.cc @@ -15,6 +15,42 @@ namespace v8 { namespace internal { +namespace { + +bool IsInStringInstanceTypeList(InstanceType instance_type) { + switch (instance_type) { +#define TEST_INSTANCE_TYPE(type, ...) \ + case InstanceType::type: \ + STATIC_ASSERT(InstanceType::type < InstanceType::FIRST_NONSTRING_TYPE); + + STRING_TYPE_LIST(TEST_INSTANCE_TYPE) +#undef TEST_INSTANCE_TYPE + return true; + default: + EXPECT_LE(InstanceType::FIRST_NONSTRING_TYPE, instance_type); + return false; + } +} + +void CheckOneInstanceType(InstanceType instance_type) { + if (IsInStringInstanceTypeList(instance_type)) { + EXPECT_TRUE((instance_type & kIsNotStringMask) == kStringTag) + << "Failing IsString mask check for " << instance_type; + } else { + EXPECT_FALSE((instance_type & kIsNotStringMask) == kStringTag) + << "Failing !IsString mask check for " << instance_type; + } +} + +} // namespace + +TEST(Object, InstanceTypeList) { +#define TEST_INSTANCE_TYPE(type) CheckOneInstanceType(InstanceType::type); + + INSTANCE_TYPE_LIST(TEST_INSTANCE_TYPE) +#undef TEST_INSTANCE_TYPE +} + TEST(Object, InstanceTypeListOrder) { int current = 0; int last = -1; diff --git a/tools/gen-postmortem-metadata.py b/tools/gen-postmortem-metadata.py index cba230064c..a618d74ed3 100644 --- a/tools/gen-postmortem-metadata.py +++ b/tools/gen-postmortem-metadata.py @@ -60,7 +60,6 @@ consts_misc = [ { 'name': 'IsNotStringMask', 'value': 'kIsNotStringMask' }, { 'name': 'StringTag', 'value': 'kStringTag' }, - { 'name': 'NotStringTag', 'value': 'kNotStringTag' }, { 'name': 'StringEncodingMask', 'value': 'kStringEncodingMask' }, { 'name': 'TwoByteStringTag', 'value': 'kTwoByteStringTag' }, @@ -249,7 +248,7 @@ extras_accessors = [ 'JSTypedArray, length, Object, kLengthOffset', 'Map, instance_size_in_words, char, kInstanceSizeInWordsOffset', 'Map, inobject_properties_start_or_constructor_function_index, char, kInObjectPropertiesStartOrConstructorFunctionIndexOffset', - 'Map, instance_type, char, kInstanceTypeOffset', + 'Map, instance_type, uint16_t, kInstanceTypeOffset', 'Map, bit_field, char, kBitFieldOffset', 'Map, bit_field2, char, kBitField2Offset', 'Map, bit_field3, int, kBitField3Offset', @@ -373,7 +372,7 @@ def load_objects_from_file(objfilename, checktypes): # do so without the embedded newlines. # for line in objfile: - if (line.startswith('enum InstanceType : uint8_t {')): + if (line.startswith('enum InstanceType : uint16_t {')): in_insttype = True; continue;