[runtime] Extend InstanceType to uint16_t range of values.
Bug: v8:5799 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: Iff62cf07d85b48975d7a21da388bbf6addeb56f1 Reviewed-on: https://chromium-review.googlesource.com/781633 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#49589}
This commit is contained in:
parent
9a0908a7f4
commit
cb46310a79
@ -9152,7 +9152,7 @@ class Internals {
|
||||
V8_INLINE static int GetInstanceType(const internal::Object* obj) {
|
||||
typedef internal::Object O;
|
||||
O* map = ReadField<O*>(obj, kHeapObjectMapOffset);
|
||||
return ReadField<uint8_t>(map, kMapInstanceTypeOffset);
|
||||
return ReadField<uint16_t>(map, kMapInstanceTypeOffset);
|
||||
}
|
||||
|
||||
V8_INLINE static int GetOddballKind(const internal::Object* obj) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -1330,7 +1330,7 @@ TNode<Uint32T> CodeStubAssembler::LoadMapBitField3(SloppyTNode<Map> map) {
|
||||
|
||||
TNode<Int32T> CodeStubAssembler::LoadMapInstanceType(SloppyTNode<Map> map) {
|
||||
return UncheckedCast<Int32T>(
|
||||
LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8()));
|
||||
LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint16()));
|
||||
}
|
||||
|
||||
TNode<Int32T> CodeStubAssembler::LoadMapElementsKind(SloppyTNode<Map> map) {
|
||||
|
@ -550,7 +550,7 @@ FieldAccess AccessBuilder::ForMapDescriptors() {
|
||||
FieldAccess AccessBuilder::ForMapInstanceType() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
|
||||
MaybeHandle<Map>(), TypeCache::Get().kUint8, MachineType::Uint8(),
|
||||
MaybeHandle<Map>(), TypeCache::Get().kUint16, MachineType::Uint16(),
|
||||
kNoWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -2398,7 +2398,6 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
|
||||
map->set_map_after_allocation(reinterpret_cast<Map*>(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);
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -3132,12 +3132,13 @@ int HeapObject::SizeFromMap(Map* map) const {
|
||||
}
|
||||
|
||||
InstanceType Map::instance_type() const {
|
||||
return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
|
||||
return static_cast<InstanceType>(
|
||||
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 {
|
||||
|
@ -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);
|
||||
|
@ -105,10 +105,7 @@ typedef std::vector<Handle<Map>> 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) \
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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<int8_t>(type)));
|
||||
cmpw(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type));
|
||||
}
|
||||
|
||||
void TurboAssembler::SlowTruncateToIDelayed(Zone* zone, Register result_reg) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user