mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:59:47 +00:00
Revert "Reland "[vm] Unify hash codes in type objects""
This reverts commitf96d179ae4
. Reason for revert: failures on Flutter Windows bots (https://github.com/flutter/flutter/issues/127666) Original change's description: > Reland "[vm] Unify hash codes in type objects" > > This is a reland of commite82a2230fd
> > Original change's description: > > [vm] Unify hash codes in type objects > > > > TEST=ci > > > > Change-Id: I53d2268c3aab6fc4583c3201051b68f8fc05d56d > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305361 > > Commit-Queue: Alexander Markov <alexmarkov@google.com> > > Reviewed-by: Ryan Macnak <rmacnak@google.com> > > TEST=ci > Change-Id: I333ed4297ad4af97000c98dfe4547b4cab6cb313 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305780 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Alexander Markov <alexmarkov@google.com> Change-Id: I1a933e39b81e99e732db56e616b24d6ec604f01b No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306000 Auto-Submit: Alexander Markov <alexmarkov@google.com> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
This commit is contained in:
parent
e213846ba0
commit
c57f889d43
|
@ -257,6 +257,14 @@ DEFINE_NATIVE_ENTRY(AbstractType_equality, 0, 2) {
|
|||
return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Type_getHashCode, 0, 1) {
|
||||
const Type& type = Type::CheckedHandle(zone, arguments->NativeArgAt(0));
|
||||
intptr_t hash_val = type.Hash();
|
||||
ASSERT(hash_val > 0);
|
||||
ASSERT(Smi::IsValid(hash_val));
|
||||
return Smi::New(hash_val);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Type_equality, 0, 2) {
|
||||
const Type& type = Type::CheckedHandle(zone, arguments->NativeArgAt(0));
|
||||
const Instance& other =
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace dart {
|
|||
V(AbstractType_getHashCode, 1) \
|
||||
V(AbstractType_toString, 1) \
|
||||
V(Type_equality, 2) \
|
||||
V(Type_getHashCode, 1) \
|
||||
V(LibraryPrefix_isLoaded, 1) \
|
||||
V(LibraryPrefix_setLoaded, 1) \
|
||||
V(LibraryPrefix_loadingUnit, 1) \
|
||||
|
|
|
@ -1076,7 +1076,10 @@ void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) {
|
|||
//
|
||||
// Caching of the canonical hash codes happens for:
|
||||
//
|
||||
// * UntaggedAbstractType::hash_
|
||||
// * UntaggedType::hash_
|
||||
// * UntaggedFunctionType::hash_
|
||||
// * UntaggedRecordType::hash_
|
||||
// * UntaggedTypeParameter::hash_
|
||||
// * UntaggedTypeArguments::hash_
|
||||
// * InstancePtr (weak table)
|
||||
// * ArrayPtr (weak table)
|
||||
|
@ -1093,14 +1096,25 @@ void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) {
|
|||
class ClearTypeHashVisitor : public ObjectVisitor {
|
||||
public:
|
||||
explicit ClearTypeHashVisitor(Zone* zone)
|
||||
: type_(AbstractType::Handle(zone)),
|
||||
: type_param_(TypeParameter::Handle(zone)),
|
||||
type_(Type::Handle(zone)),
|
||||
function_type_(FunctionType::Handle(zone)),
|
||||
record_type_(RecordType::Handle(zone)),
|
||||
type_args_(TypeArguments::Handle(zone)) {}
|
||||
|
||||
void VisitObject(ObjectPtr obj) override {
|
||||
if (obj->IsType() || obj->IsTypeParameter() || obj->IsFunctionType() ||
|
||||
obj->IsRecordType()) {
|
||||
if (obj->IsTypeParameter()) {
|
||||
type_param_ ^= obj;
|
||||
type_param_.SetHash(0);
|
||||
} else if (obj->IsType()) {
|
||||
type_ ^= obj;
|
||||
type_.SetHash(0);
|
||||
} else if (obj->IsFunctionType()) {
|
||||
function_type_ ^= obj;
|
||||
function_type_.SetHash(0);
|
||||
} else if (obj->IsRecordType()) {
|
||||
record_type_ ^= obj;
|
||||
record_type_.SetHash(0);
|
||||
} else if (obj->IsTypeArguments()) {
|
||||
type_args_ ^= obj;
|
||||
type_args_.SetHash(0);
|
||||
|
@ -1108,7 +1122,10 @@ class ClearTypeHashVisitor : public ObjectVisitor {
|
|||
}
|
||||
|
||||
private:
|
||||
AbstractType& type_;
|
||||
TypeParameter& type_param_;
|
||||
Type& type_;
|
||||
FunctionType& function_type_;
|
||||
RecordType& record_type_;
|
||||
TypeArguments& type_args_;
|
||||
};
|
||||
|
||||
|
|
|
@ -1199,6 +1199,15 @@ void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
|
|||
__ Bind(normal_ir_body); // Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ ldr(R0, Address(SP, 0 * target::kWordSize));
|
||||
__ ldr(R0, FieldAddress(R0, target::Type::hash_offset()));
|
||||
__ cmp(R0, Operand(0));
|
||||
READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE));
|
||||
__ Bind(normal_ir_body); // Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
Label equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
|
||||
|
@ -1262,7 +1271,7 @@ void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
|||
void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ ldr(R0, Address(SP, 0 * target::kWordSize));
|
||||
__ ldr(R0, FieldAddress(R0, target::AbstractType::hash_offset()));
|
||||
__ ldr(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
|
||||
__ cmp(R0, Operand(0));
|
||||
READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE));
|
||||
__ Bind(normal_ir_body); // Hash not yet computed.
|
||||
|
|
|
@ -1359,6 +1359,16 @@ void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
|
|||
__ Bind(normal_ir_body);
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ ldr(R0, Address(SP, 0 * target::kWordSize));
|
||||
__ LoadCompressedSmi(R0, FieldAddress(R0, target::Type::hash_offset()));
|
||||
__ cbz(normal_ir_body, R0, kObjectBytes);
|
||||
__ ret();
|
||||
// Hash not yet computed.
|
||||
__ Bind(normal_ir_body);
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
Label equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
|
||||
|
@ -1423,7 +1433,7 @@ void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
|
|||
Label* normal_ir_body) {
|
||||
__ ldr(R0, Address(SP, 0 * target::kWordSize));
|
||||
__ LoadCompressedSmi(R0,
|
||||
FieldAddress(R0, target::AbstractType::hash_offset()));
|
||||
FieldAddress(R0, target::FunctionType::hash_offset()));
|
||||
__ cbz(normal_ir_body, R0, kObjectBytes);
|
||||
__ ret();
|
||||
// Hash not yet computed.
|
||||
|
|
|
@ -1342,6 +1342,17 @@ void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
|
|||
// Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ movl(EAX, Address(ESP, +1 * target::kWordSize)); // Type object.
|
||||
__ movl(EAX, FieldAddress(EAX, target::Type::hash_offset()));
|
||||
__ testl(EAX, EAX);
|
||||
__ j(EQUAL, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
__ Bind(normal_ir_body);
|
||||
// Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
Label equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
|
||||
|
@ -1405,8 +1416,8 @@ void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
|||
|
||||
void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ movl(EAX, Address(ESP, +1 * target::kWordSize)); // AbstractType object.
|
||||
__ movl(EAX, FieldAddress(EAX, target::AbstractType::hash_offset()));
|
||||
__ movl(EAX, Address(ESP, +1 * target::kWordSize)); // FunctionType object.
|
||||
__ movl(EAX, FieldAddress(EAX, target::FunctionType::hash_offset()));
|
||||
__ testl(EAX, EAX);
|
||||
__ j(EQUAL, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
|
|
|
@ -1396,6 +1396,16 @@ void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
|
|||
__ Bind(normal_ir_body);
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ lx(A0, Address(SP, 0 * target::kWordSize));
|
||||
__ LoadCompressed(A0, FieldAddress(A0, target::Type::hash_offset()));
|
||||
__ beqz(A0, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
// Hash not yet computed.
|
||||
__ Bind(normal_ir_body);
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
Label equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
|
||||
|
@ -1458,7 +1468,7 @@ void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
|||
void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ lx(A0, Address(SP, 0 * target::kWordSize));
|
||||
__ LoadCompressed(A0, FieldAddress(A0, target::AbstractType::hash_offset()));
|
||||
__ LoadCompressed(A0, FieldAddress(A0, target::FunctionType::hash_offset()));
|
||||
__ beqz(A0, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
// Hash not yet computed.
|
||||
|
|
|
@ -1248,6 +1248,19 @@ void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
|
|||
// Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ movq(RAX, Address(RSP, +1 * target::kWordSize)); // Type object.
|
||||
__ LoadCompressedSmi(RAX, FieldAddress(RAX, target::Type::hash_offset()));
|
||||
ASSERT(kSmiTag == 0);
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ OBJ(test)(RAX, RAX);
|
||||
__ j(ZERO, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
__ Bind(normal_ir_body);
|
||||
// Hash not yet computed.
|
||||
}
|
||||
|
||||
void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
Label equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
|
||||
|
@ -1311,9 +1324,9 @@ void AsmIntrinsifier::Type_equality(Assembler* assembler,
|
|||
|
||||
void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ movq(RAX, Address(RSP, +1 * target::kWordSize)); // AbstractType object.
|
||||
__ movq(RAX, Address(RSP, +1 * target::kWordSize)); // FunctionType object.
|
||||
__ LoadCompressedSmi(RAX,
|
||||
FieldAddress(RAX, target::AbstractType::hash_offset()));
|
||||
FieldAddress(RAX, target::FunctionType::hash_offset()));
|
||||
ASSERT(kSmiTag == 0);
|
||||
ASSERT(kSmiTagShift == 1);
|
||||
__ OBJ(test)(RAX, RAX);
|
||||
|
|
|
@ -374,6 +374,7 @@ namespace dart {
|
|||
V(_TwoByteString, ==, TwoByteString_equality, 0x4ea9ddc9) \
|
||||
V(_AbstractType, get:hashCode, AbstractType_getHashCode, 0x75e0d454) \
|
||||
V(_AbstractType, ==, AbstractType_equality, 0x465868ae) \
|
||||
V(_Type, get:hashCode, Type_getHashCode, 0x75e0d454) \
|
||||
V(_Type, ==, Type_equality, 0x465868ae) \
|
||||
V(::, _getHash, Object_getHash, 0xc60ff758) \
|
||||
|
||||
|
|
|
@ -717,7 +717,6 @@ class Pointer : public AllStatic {
|
|||
class AbstractType : public AllStatic {
|
||||
public:
|
||||
static word flags_offset();
|
||||
static word hash_offset();
|
||||
static word type_test_stub_entry_point_offset();
|
||||
static word InstanceSize();
|
||||
FINAL_CLASS();
|
||||
|
@ -725,6 +724,7 @@ class AbstractType : public AllStatic {
|
|||
|
||||
class Type : public AllStatic {
|
||||
public:
|
||||
static word hash_offset();
|
||||
static word arguments_offset();
|
||||
static word InstanceSize();
|
||||
FINAL_CLASS();
|
||||
|
@ -732,6 +732,7 @@ class Type : public AllStatic {
|
|||
|
||||
class FunctionType : public AllStatic {
|
||||
public:
|
||||
static word hash_offset();
|
||||
static word packed_parameter_counts_offset();
|
||||
static word packed_type_parameter_counts_offset();
|
||||
static word named_parameter_names_offset();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -103,7 +103,6 @@
|
|||
CONSTANT(SubtypeTestCache, kTestResult) \
|
||||
CONSTANT(TypeArguments, kMaxElements) \
|
||||
FIELD(AbstractType, flags_offset) \
|
||||
FIELD(AbstractType, hash_offset) \
|
||||
FIELD(AbstractType, type_test_stub_entry_point_offset) \
|
||||
FIELD(ArgumentsDescriptor, count_offset) \
|
||||
FIELD(ArgumentsDescriptor, size_offset) \
|
||||
|
@ -354,6 +353,7 @@
|
|||
FIELD(TimelineStream, enabled_offset) \
|
||||
FIELD(TwoByteString, data_offset) \
|
||||
FIELD(Type, arguments_offset) \
|
||||
FIELD(Type, hash_offset) \
|
||||
FIELD(Finalizer, type_arguments_offset) \
|
||||
FIELD(Finalizer, callback_offset) \
|
||||
FIELD(FinalizerBase, all_entries_offset) \
|
||||
|
@ -367,6 +367,7 @@
|
|||
FIELD(FinalizerEntry, token_offset) \
|
||||
FIELD(FinalizerEntry, value_offset) \
|
||||
FIELD(NativeFinalizer, callback_offset) \
|
||||
FIELD(FunctionType, hash_offset) \
|
||||
FIELD(FunctionType, named_parameter_names_offset) \
|
||||
FIELD(FunctionType, packed_parameter_counts_offset) \
|
||||
FIELD(FunctionType, packed_type_parameter_counts_offset) \
|
||||
|
|
|
@ -21601,7 +21601,10 @@ bool AbstractType::IsSubtypeOfFutureOr(
|
|||
return false;
|
||||
}
|
||||
|
||||
uword AbstractType::ComputeHash() const {
|
||||
uword AbstractType::Hash() const {
|
||||
// All subclasses should implement this appropriately, so the only value that
|
||||
// should reach this implementation should be the null value.
|
||||
ASSERT(IsNull());
|
||||
// AbstractType is an abstract class.
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
|
|
|
@ -8528,9 +8528,6 @@ class AbstractType : public Instance {
|
|||
static intptr_t flags_offset() {
|
||||
return OFFSET_OF(UntaggedAbstractType, flags_);
|
||||
}
|
||||
static intptr_t hash_offset() {
|
||||
return OFFSET_OF(UntaggedAbstractType, hash_);
|
||||
}
|
||||
|
||||
bool IsFinalized() const {
|
||||
const auto state = type_state();
|
||||
|
@ -8666,8 +8663,7 @@ class AbstractType : public Instance {
|
|||
// list and mark ambiguous triplets to be printed.
|
||||
virtual void EnumerateURIs(URIs* uris) const;
|
||||
|
||||
uword Hash() const;
|
||||
virtual uword ComputeHash() const;
|
||||
virtual uword Hash() const;
|
||||
|
||||
// The name of this type's class, i.e. without the type argument names of this
|
||||
// type.
|
||||
|
@ -8841,8 +8837,6 @@ class AbstractType : public Instance {
|
|||
const AbstractType& other_type,
|
||||
TypeEquality kind) const;
|
||||
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
UntaggedAbstractType::TypeState type_state() const {
|
||||
return static_cast<UntaggedAbstractType::TypeState>(
|
||||
UntaggedAbstractType::TypeStateBits::decode(untag()->flags()));
|
||||
|
@ -8853,7 +8847,6 @@ class AbstractType : public Instance {
|
|||
|
||||
HEAP_OBJECT_IMPLEMENTATION(AbstractType, Instance);
|
||||
friend class Class;
|
||||
friend class ClearTypeHashVisitor;
|
||||
friend class Function;
|
||||
friend class TypeArguments;
|
||||
};
|
||||
|
@ -8865,6 +8858,7 @@ class Type : public AbstractType {
|
|||
static intptr_t arguments_offset() {
|
||||
return OFFSET_OF(UntaggedType, arguments_);
|
||||
}
|
||||
static intptr_t hash_offset() { return OFFSET_OF(UntaggedType, hash_); }
|
||||
virtual bool HasTypeClass() const {
|
||||
ASSERT(type_class_id() != kIllegalCid);
|
||||
return true;
|
||||
|
@ -8917,7 +8911,8 @@ class Type : public AbstractType {
|
|||
virtual void PrintName(NameVisibility visibility,
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
virtual uword ComputeHash() const;
|
||||
virtual uword Hash() const;
|
||||
uword ComputeHash() const;
|
||||
|
||||
static intptr_t InstanceSize() {
|
||||
return RoundedAllocationSize(sizeof(UntaggedType));
|
||||
|
@ -8992,6 +8987,8 @@ class Type : public AbstractType {
|
|||
Heap::Space space = Heap::kOld);
|
||||
|
||||
private:
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
// Takes an intptr_t since the cids of some classes are larger than will fit
|
||||
// in ClassIdTagType. This allows us to guard against that case, instead of
|
||||
// silently truncating the cid.
|
||||
|
@ -9002,6 +8999,7 @@ class Type : public AbstractType {
|
|||
FINAL_HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
|
||||
friend class Class;
|
||||
friend class TypeArguments;
|
||||
friend class ClearTypeHashVisitor;
|
||||
};
|
||||
|
||||
// A FunctionType represents the type of a function. It describes most of the
|
||||
|
@ -9022,6 +9020,9 @@ class FunctionType : public AbstractType {
|
|||
using PackedNumOptionalParameters =
|
||||
UntaggedFunctionType::PackedNumOptionalParameters;
|
||||
|
||||
static intptr_t hash_offset() {
|
||||
return OFFSET_OF(UntaggedFunctionType, hash_);
|
||||
}
|
||||
virtual bool HasTypeClass() const { return false; }
|
||||
FunctionTypePtr ToNullability(Nullability value, Heap::Space space) const;
|
||||
virtual classid_t type_class_id() const { return kIllegalCid; }
|
||||
|
@ -9057,7 +9058,8 @@ class FunctionType : public AbstractType {
|
|||
virtual void PrintName(NameVisibility visibility,
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
virtual uword ComputeHash() const;
|
||||
virtual uword Hash() const;
|
||||
uword ComputeHash() const;
|
||||
|
||||
bool IsSubtypeOf(
|
||||
const FunctionType& other,
|
||||
|
@ -9286,10 +9288,13 @@ class FunctionType : public AbstractType {
|
|||
static FunctionTypePtr Clone(const FunctionType& orig, Heap::Space space);
|
||||
|
||||
private:
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
static FunctionTypePtr New(Heap::Space space);
|
||||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(FunctionType, AbstractType);
|
||||
friend class Class;
|
||||
friend class ClearTypeHashVisitor;
|
||||
friend class Function;
|
||||
};
|
||||
|
||||
|
@ -9363,6 +9368,8 @@ class TypeParameter : public AbstractType {
|
|||
virtual void PrintName(NameVisibility visibility,
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
virtual uword Hash() const;
|
||||
|
||||
// Returns type corresponding to [this] type parameter from the
|
||||
// given [instantiator_type_arguments] and [function_type_arguments].
|
||||
// Unlike InstantiateFrom, nullability of type parameter is not applied to
|
||||
|
@ -9391,7 +9398,8 @@ class TypeParameter : public AbstractType {
|
|||
Nullability nullability);
|
||||
|
||||
private:
|
||||
virtual uword ComputeHash() const;
|
||||
uword ComputeHash() const;
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
void set_owner(const Object& value) const;
|
||||
|
||||
|
@ -9399,6 +9407,7 @@ class TypeParameter : public AbstractType {
|
|||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
|
||||
friend class Class;
|
||||
friend class ClearTypeHashVisitor;
|
||||
};
|
||||
|
||||
class Number : public Instance {
|
||||
|
@ -11037,6 +11046,7 @@ class RecordShape {
|
|||
// names of the named fields.
|
||||
class RecordType : public AbstractType {
|
||||
public:
|
||||
static intptr_t hash_offset() { return OFFSET_OF(UntaggedRecordType, hash_); }
|
||||
virtual bool HasTypeClass() const { return false; }
|
||||
RecordTypePtr ToNullability(Nullability value, Heap::Space space) const;
|
||||
virtual classid_t type_class_id() const { return kIllegalCid; }
|
||||
|
@ -11072,7 +11082,8 @@ class RecordType : public AbstractType {
|
|||
virtual void PrintName(NameVisibility visibility,
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
virtual uword ComputeHash() const;
|
||||
virtual uword Hash() const;
|
||||
uword ComputeHash() const;
|
||||
|
||||
bool IsSubtypeOf(
|
||||
const RecordType& other,
|
||||
|
@ -11103,6 +11114,8 @@ class RecordType : public AbstractType {
|
|||
Heap::Space space = Heap::kOld);
|
||||
|
||||
private:
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
void set_shape(RecordShape shape) const;
|
||||
void set_field_types(const Array& value) const;
|
||||
|
||||
|
@ -11111,6 +11124,7 @@ class RecordType : public AbstractType {
|
|||
FINAL_HEAP_OBJECT_IMPLEMENTATION(RecordType, AbstractType);
|
||||
friend class Class;
|
||||
friend class ClassFinalizer;
|
||||
friend class ClearTypeHashVisitor;
|
||||
friend class Record;
|
||||
};
|
||||
|
||||
|
@ -13039,7 +13053,7 @@ ObjectPtr MegamorphicCache::GetTargetFunction(const Array& array,
|
|||
return array.At((index * kEntryLength) + kTargetFunctionIndex);
|
||||
}
|
||||
|
||||
inline uword AbstractType::Hash() const {
|
||||
inline uword Type::Hash() const {
|
||||
ASSERT(IsFinalized());
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
if (result != 0) {
|
||||
|
@ -13048,7 +13062,37 @@ inline uword AbstractType::Hash() const {
|
|||
return ComputeHash();
|
||||
}
|
||||
|
||||
inline void AbstractType::SetHash(intptr_t value) const {
|
||||
inline void Type::SetHash(intptr_t value) const {
|
||||
// This is only safe because we create a new Smi, which does not cause
|
||||
// heap allocation.
|
||||
untag()->set_hash(Smi::New(value));
|
||||
}
|
||||
|
||||
inline uword FunctionType::Hash() const {
|
||||
ASSERT(IsFinalized());
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return ComputeHash();
|
||||
}
|
||||
|
||||
inline void FunctionType::SetHash(intptr_t value) const {
|
||||
// This is only safe because we create a new Smi, which does not cause
|
||||
// heap allocation.
|
||||
untag()->set_hash(Smi::New(value));
|
||||
}
|
||||
|
||||
inline uword RecordType::Hash() const {
|
||||
ASSERT(IsFinalized());
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return ComputeHash();
|
||||
}
|
||||
|
||||
inline void RecordType::SetHash(intptr_t value) const {
|
||||
// This is only safe because we create a new Smi, which does not cause
|
||||
// heap allocation.
|
||||
untag()->set_hash(Smi::New(value));
|
||||
|
@ -13058,6 +13102,21 @@ inline intptr_t RecordType::NumFields() const {
|
|||
return Array::LengthOf(field_types());
|
||||
}
|
||||
|
||||
inline uword TypeParameter::Hash() const {
|
||||
ASSERT(IsFinalized());
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return ComputeHash();
|
||||
}
|
||||
|
||||
inline void TypeParameter::SetHash(intptr_t value) const {
|
||||
// This is only safe because we create a new Smi, which does not cause
|
||||
// heap allocation.
|
||||
untag()->set_hash(Smi::New(value));
|
||||
}
|
||||
|
||||
inline uword TypeArguments::Hash() const {
|
||||
if (IsNull()) return kAllDynamicHash;
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
|
|
|
@ -2643,7 +2643,6 @@ class UntaggedAbstractType : public UntaggedInstance {
|
|||
// Accessed from generated code.
|
||||
std::atomic<uint32_t> flags_;
|
||||
COMPRESSED_POINTER_FIELD(CodePtr, type_test_stub)
|
||||
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
|
||||
VISIT_FROM(type_test_stub)
|
||||
|
||||
uint32_t flags() const { return flags_.load(std::memory_order_relaxed); }
|
||||
|
@ -2683,7 +2682,8 @@ class UntaggedType : public UntaggedAbstractType {
|
|||
RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
|
||||
|
||||
COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, arguments)
|
||||
VISIT_TO(arguments)
|
||||
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
|
||||
VISIT_TO(hash)
|
||||
|
||||
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
|
||||
|
||||
|
@ -2707,7 +2707,8 @@ class UntaggedFunctionType : public UntaggedAbstractType {
|
|||
COMPRESSED_POINTER_FIELD(AbstractTypePtr, result_type)
|
||||
COMPRESSED_POINTER_FIELD(ArrayPtr, parameter_types)
|
||||
COMPRESSED_POINTER_FIELD(ArrayPtr, named_parameter_names);
|
||||
VISIT_TO(named_parameter_names)
|
||||
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
|
||||
VISIT_TO(hash)
|
||||
AtomicBitFieldContainer<uint32_t> packed_parameter_counts_;
|
||||
AtomicBitFieldContainer<uint16_t> packed_type_parameter_counts_;
|
||||
|
||||
|
@ -2757,7 +2758,8 @@ class UntaggedRecordType : public UntaggedAbstractType {
|
|||
|
||||
COMPRESSED_SMI_FIELD(SmiPtr, shape)
|
||||
COMPRESSED_POINTER_FIELD(ArrayPtr, field_types)
|
||||
VISIT_TO(field_types)
|
||||
COMPRESSED_SMI_FIELD(SmiPtr, hash)
|
||||
VISIT_TO(hash)
|
||||
|
||||
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
|
||||
};
|
||||
|
@ -2772,6 +2774,7 @@ class UntaggedTypeParameter : public UntaggedAbstractType {
|
|||
private:
|
||||
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
|
||||
|
||||
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
|
||||
// FunctionType or Smi (class id).
|
||||
COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
|
||||
VISIT_TO(owner)
|
||||
|
|
|
@ -27,6 +27,11 @@ class _Type extends _AbstractType {
|
|||
throw "Unreachable";
|
||||
}
|
||||
|
||||
@pragma("vm:recognized", "asm-intrinsic")
|
||||
@pragma("vm:exact-result-type", "dart:core#_Smi")
|
||||
@pragma("vm:external-name", "Type_getHashCode")
|
||||
external int get hashCode;
|
||||
|
||||
@pragma("vm:recognized", "asm-intrinsic")
|
||||
@pragma("vm:exact-result-type", bool)
|
||||
@pragma("vm:external-name", "Type_equality")
|
||||
|
|
Loading…
Reference in a new issue