[vm] Fix ObjectPtr::IsSmi and other ObjectPtr::Is* methods to account for Smis

Arbitrary ObjectPtr can be a non-heap object (Smi), so methods
ObjectPtr::Is* which test class id should account for Smi.

Changed ObjectPtr::GetClassId to account for Smi similarly to
Object::GetClassId. Added unsafe ObjectPtr::GetClassIdOfHeapObject
which can be used when caller knows the heap nature of the object.

This change also fixes Integer::GetInt64Value which was relying on ObjectPtr::IsSmi.

TEST=vm/cc/Smi, vm/cc/Mint

Change-Id: I1391600e2acedc7b2a8f35c814df113ec9ba8698
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380280
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2024-08-14 17:09:07 +00:00
committed by Commit Queue
parent eaabb3f8ab
commit bf2fba78e0
27 changed files with 155 additions and 156 deletions
+1 -1
View File
@@ -195,7 +195,7 @@ class WorkSet {
uint32_t GetHeaderHash(ObjectPtr object) {
uint32_t hash = Object::GetCachedHash(object);
if (hash == 0) {
switch (object->GetClassId()) {
switch (object->GetClassIdOfHeapObject()) {
case kMintCid:
hash = Mint::Value(static_cast<MintPtr>(object));
// Don't write back: doesn't agree with dart:core's identityHash.
+1 -1
View File
@@ -23,7 +23,7 @@ namespace dart {
#define RETURN_OR_PROPAGATE(expr) \
ObjectPtr result = expr; \
if (IsErrorClassId(result->GetClassIdMayBeSmi())) { \
if (IsErrorClassId(result->GetClassId())) { \
Exceptions::PropagateError(Error::Handle(Error::RawCast(result))); \
} \
return result;
+11 -12
View File
@@ -2709,7 +2709,7 @@ class CodeSerializationCluster : public SerializationCluster {
// indirectly by passing the field to the runtime. A const closure
// is a call target because its function may be called indirectly
// via a closure call.
intptr_t cid = target->GetClassIdMayBeSmi();
intptr_t cid = target->GetClassId();
if (!only_call_targets || (cid == kCodeCid) || (cid == kFunctionCid) ||
(cid == kFieldCid) || (cid == kClosureCid)) {
s->Push(target);
@@ -5918,7 +5918,7 @@ class DeltaEncodedTypedDataSerializationCluster : public SerializationCluster {
for (intptr_t i = 0; i < count; i++) {
const TypedDataPtr data = objects_[i];
const intptr_t element_size =
TypedData::ElementSizeInBytes(data->GetClassId());
TypedData::ElementSizeInBytes(data->GetClassIdOfHeapObject());
s->AssignRef(data);
AutoTraceObject(data);
const intptr_t length_in_bytes =
@@ -5935,7 +5935,7 @@ class DeltaEncodedTypedDataSerializationCluster : public SerializationCluster {
for (intptr_t i = 0; i < count; i++) {
const TypedDataPtr data = objects_[i];
AutoTraceObject(data);
const intptr_t cid = data->GetClassId();
const intptr_t cid = data->GetClassIdOfHeapObject();
// Only Uint16 and Uint32 typed data is supported at the moment. So encode
// which this is in the low bit of the length. Uint16 is 0, Uint32 is 1.
ASSERT(cid == kTypedDataUint16ArrayCid ||
@@ -6417,7 +6417,7 @@ class ArraySerializationCluster : public SerializationCluster {
const intptr_t length = Smi::Value(array->untag()->length());
for (intptr_t i = 0; i < length; i++) {
ObjectPtr element = array->untag()->element(i);
intptr_t cid = element->GetClassIdMayBeSmi();
intptr_t cid = element->GetClassId();
if (!IsReadOnlyCid(cid)) allro = false;
if (cid != kSmiCid) allsmi = false;
}
@@ -6643,7 +6643,7 @@ class StringSerializationCluster
StringPtr str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
const intptr_t cid = str->GetClassId();
const intptr_t cid = str->GetClassIdOfHeapObject();
const intptr_t length = Smi::Value(str->untag()->length());
const intptr_t encoded = EncodeLengthAndCid(length, cid);
s->WriteUnsigned(encoded);
@@ -6660,7 +6660,7 @@ class StringSerializationCluster
for (intptr_t i = 0; i < count; i++) {
StringPtr str = objects_[i];
AutoTraceObject(str);
const intptr_t cid = str->GetClassId();
const intptr_t cid = str->GetClassIdOfHeapObject();
const intptr_t length = Smi::Value(str->untag()->length());
const intptr_t encoded = EncodeLengthAndCid(length, cid);
s->WriteUnsigned(encoded);
@@ -7582,7 +7582,7 @@ Serializer::WritingObjectScope::WritingObjectScope(
serializer_->object_currently_writing_.object_ = object;
serializer_->object_currently_writing_.id_ = id;
serializer_->object_currently_writing_.cid_ =
object == nullptr ? -1 : object->GetClassIdMayBeSmi();
object == nullptr ? -1 : object->GetClassId();
}
Serializer::WritingObjectScope::~WritingObjectScope() {
@@ -7603,7 +7603,7 @@ V8SnapshotProfileWriter::ObjectId Serializer::WritingObjectScope::ReserveId(
}
if (name == nullptr) {
// Handle some cases where there are obvious names to assign.
switch (obj->GetClassIdMayBeSmi()) {
switch (obj->GetClassId()) {
case kSmiCid: {
name = OS::SCreate(s->zone(), "%" Pd "", Smi::Value(Smi::RawCast(obj)));
break;
@@ -7649,7 +7649,7 @@ bool Serializer::CreateArtificialNodeIfNeeded(ObjectPtr obj) {
const char* type = nullptr;
const char* name = nullptr;
GrowableArray<std::pair<ObjectPtr, V8SnapshotProfileWriter::Reference>> links;
const classid_t cid = obj->GetClassIdMayBeSmi();
const classid_t cid = obj->GetClassId();
switch (cid) {
// For profiling static call target tables in AOT mode.
case kSmiCid: {
@@ -7775,8 +7775,7 @@ intptr_t Serializer::UnsafeRefId(ObjectPtr object) const {
// The object id weak table holds image offsets for Instructions instead
// of ref indices.
ASSERT(!object->IsHeapObject() || !object->IsInstructions());
if (!Snapshot::IncludesCode(kind_) &&
object->GetClassIdMayBeSmi() == kCodeCid) {
if (!Snapshot::IncludesCode(kind_) && object->GetClassId() == kCodeCid) {
return RefId(Object::null());
}
auto id = heap_->GetObjectId(object);
@@ -8440,7 +8439,7 @@ void Serializer::Trace(ObjectPtr object, intptr_t cid_override) {
cid = kMintCid;
is_canonical = true;
} else {
cid = object->GetClassId();
cid = object->GetClassIdOfHeapObject();
is_canonical = object->untag()->IsCanonical();
}
if (cid_override != kIllegalCid) {
+1 -1
View File
@@ -1056,7 +1056,7 @@ class CidRewriteVisitor : public ObjectVisitor {
TypePtr type = Type::RawCast(obj);
type->untag()->set_type_class_id(Map(type->untag()->type_class_id()));
} else {
intptr_t old_cid = obj->GetClassId();
intptr_t old_cid = obj->GetClassIdOfHeapObject();
intptr_t new_cid = Map(old_cid);
if (old_cid != new_cid) {
// Don't touch objects that are unchanged. In particular, Instructions,
+4 -4
View File
@@ -2391,9 +2391,9 @@ void Precompiler::AttachOptimizedTypeTestingStub() {
: type_(AbstractType::Handle(zone)), types_(types) {}
void VisitObject(ObjectPtr obj) override {
if (obj->GetClassId() == kTypeCid ||
obj->GetClassId() == kFunctionTypeCid ||
obj->GetClassId() == kRecordTypeCid) {
const auto cid = obj->GetClassIdOfHeapObject();
if (cid == kTypeCid || cid == kFunctionTypeCid ||
cid == kRecordTypeCid) {
type_ ^= obj;
types_->Add(type_);
}
@@ -3317,7 +3317,7 @@ void Precompiler::Obfuscate() {
: script_(Script::Handle(zone)), scripts_(scripts) {}
void VisitObject(ObjectPtr obj) override {
if (obj->GetClassId() == kScriptCid) {
if (obj->GetClassIdOfHeapObject() == kScriptCid) {
script_ ^= obj;
scripts_->Add(Script::Cast(script_));
}
+44 -51
View File
@@ -562,9 +562,6 @@ bool Api::StringGetPeerHelper(NativeArguments* arguments,
void** peer) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (!raw_obj->IsHeapObject()) {
return false;
}
intptr_t cid = raw_obj->GetClassId();
if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
auto isolate_group = arguments->thread()->isolate_group();
@@ -577,21 +574,19 @@ bool Api::StringGetPeerHelper(NativeArguments* arguments,
bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArg0();
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid >= kNumPredefinedCids) {
ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
TypedDataPtr native_fields =
reinterpret_cast<CompressedTypedDataPtr*>(
UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
->Decompress(raw_obj->heap_base());
if (native_fields == TypedData::null()) {
*value = 0;
} else {
*value = *bit_cast<intptr_t*, uint8_t*>(native_fields->untag()->data());
}
return true;
intptr_t cid = raw_obj->GetClassId();
if (cid >= kNumPredefinedCids) {
ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
TypedDataPtr native_fields =
reinterpret_cast<CompressedTypedDataPtr*>(
UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
->Decompress(raw_obj->heap_base());
if (native_fields == TypedData::null()) {
*value = 0;
} else {
*value = *bit_cast<intptr_t*, uint8_t*>(native_fields->untag()->data());
}
return true;
}
return false;
}
@@ -601,16 +596,14 @@ bool Api::GetNativeBooleanArgument(NativeArguments* arguments,
bool* value) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kBoolCid) {
*value = (raw_obj == Object::bool_true().ptr());
return true;
}
if (cid == kNullCid) {
*value = false;
return true;
}
intptr_t cid = raw_obj->GetClassId();
if (cid == kBoolCid) {
*value = (raw_obj == Object::bool_true().ptr());
return true;
}
if (cid == kNullCid) {
*value = false;
return true;
}
return false;
}
@@ -620,16 +613,16 @@ bool Api::GetNativeIntegerArgument(NativeArguments* arguments,
int64_t* value) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kMintCid) {
*value = static_cast<MintPtr>(raw_obj)->untag()->value_;
return true;
}
return false;
intptr_t cid = raw_obj->GetClassId();
if (cid == kSmiCid) {
*value = Smi::Value(static_cast<SmiPtr>(raw_obj));
return true;
}
*value = Smi::Value(static_cast<SmiPtr>(raw_obj));
return true;
if (cid == kMintCid) {
*value = static_cast<MintPtr>(raw_obj)->untag()->value_;
return true;
}
return false;
}
bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
@@ -637,21 +630,21 @@ bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
double* value) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kDoubleCid) {
*value = static_cast<DoublePtr>(raw_obj)->untag()->value_;
return true;
}
if (cid == kMintCid) {
*value =
static_cast<double>(static_cast<MintPtr>(raw_obj)->untag()->value_);
return true;
}
return false;
intptr_t cid = raw_obj->GetClassId();
if (cid == kDoubleCid) {
*value = static_cast<DoublePtr>(raw_obj)->untag()->value_;
return true;
}
*value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
return true;
if (cid == kSmiCid) {
*value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
return true;
}
if (cid == kMintCid) {
*value =
static_cast<double>(static_cast<MintPtr>(raw_obj)->untag()->value_);
return true;
}
return false;
}
bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
@@ -660,7 +653,7 @@ bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
intptr_t* field_values) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
intptr_t cid = raw_obj->GetClassIdMayBeSmi();
intptr_t cid = raw_obj->GetClassId();
int class_num_fields = arguments->thread()
->isolate_group()
->class_table()
+1 -5
View File
@@ -210,11 +210,7 @@ class Api : AllStatic {
}
static intptr_t ClassId(Dart_Handle handle) {
ObjectPtr raw = UnwrapHandle(handle);
if (!raw->IsHeapObject()) {
return kSmiCid;
}
return raw->GetClassId();
return UnwrapHandle(handle)->GetClassId();
}
// Generates a handle used to designate an error return.
+2 -3
View File
@@ -327,8 +327,7 @@ void GCCompactor::Compact(Page* pages, FreeList* freelist, Mutex* pages_lock) {
const intptr_t length = typed_data_views_.length();
for (intptr_t i = 0; i < length; ++i) {
auto raw_view = typed_data_views_[i];
const classid_t cid =
raw_view->untag()->typed_data()->GetClassIdMayBeSmi();
const classid_t cid = raw_view->untag()->typed_data()->GetClassId();
// If we have external typed data we can simply return, since the backing
// store lives in C-heap and will not move. Otherwise we have to update
@@ -622,7 +621,7 @@ uword CompactorTask::SlideBlock(uword first_object,
memmove(reinterpret_cast<void*>(new_addr),
reinterpret_cast<void*>(old_addr), size);
if (IsTypedDataClassId(new_obj->GetClassId())) {
if (IsTypedDataClassId(new_obj->GetClassIdOfHeapObject())) {
static_cast<TypedDataPtr>(new_obj)->untag()->RecomputeDataField();
}
}
+2 -3
View File
@@ -481,8 +481,7 @@ class IncrementalForwardingVisitor : public ObjectPointerVisitor,
const intptr_t length = typed_data_views_.length();
for (intptr_t i = 0; i < length; ++i) {
auto raw_view = typed_data_views_[i];
const classid_t cid =
raw_view->untag()->typed_data()->GetClassIdMayBeSmi();
const classid_t cid = raw_view->untag()->typed_data()->GetClassId();
// If we have external typed data we can simply return, since the backing
// store lives in C-heap and will not move. Otherwise we have to update
// the inner pointer.
@@ -755,7 +754,7 @@ class EpilogueTask : public ThreadPool::Task {
ObjectPtr copied_obj = UntaggedObject::FromAddr(copied);
copied_obj->untag()->ClearIsEvacuationCandidateUnsynchronized();
if (IsTypedDataClassId(copied_obj->GetClassId())) {
if (IsTypedDataClassId(copied_obj->GetClassIdOfHeapObject())) {
static_cast<TypedDataPtr>(copied_obj)
->untag()
->RecomputeDataField();
+3 -3
View File
@@ -138,7 +138,7 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
}
}
const intptr_t class_id = obj->GetClassId();
const intptr_t class_id = obj->GetClassIdOfHeapObject();
ASSERT(class_id != kIllegalCid);
ASSERT(class_id != kFreeListElement);
ASSERT(class_id != kForwardingCorpse);
@@ -239,7 +239,7 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
while (MarkerWorkList::Pop(&old_work_list_, &new_work_list_, &obj)) {
ASSERT(!has_evacuation_candidate_);
const intptr_t class_id = obj->GetClassId();
const intptr_t class_id = obj->GetClassIdOfHeapObject();
ASSERT(class_id != kIllegalCid);
ASSERT(class_id != kFreeListElement);
ASSERT(class_id != kForwardingCorpse);
@@ -301,7 +301,7 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
while (old_work_list_.Pop(&obj)) {
ASSERT(!has_evacuation_candidate_);
const intptr_t class_id = obj->GetClassId();
const intptr_t class_id = obj->GetClassIdOfHeapObject();
ASSERT(class_id != kIllegalCid);
ASSERT(class_id != kFreeListElement);
ASSERT(class_id != kForwardingCorpse);
+2 -2
View File
@@ -762,7 +762,7 @@ class HeapMapAsJSONVisitor : public ObjectVisitor {
explicit HeapMapAsJSONVisitor(JSONArray* array) : array_(array) {}
void VisitObject(ObjectPtr obj) override {
array_->AddValue(obj->untag()->HeapSize() / kObjectAlignment);
array_->AddValue(obj->GetClassId());
array_->AddValue(obj->GetClassIdOfHeapObject());
}
private:
@@ -1188,7 +1188,7 @@ class CollectStoreBufferEvacuateVisitor : public ObjectPointerVisitor {
RELEASE_ASSERT_WITH_MSG(obj->IsOldObject(), msg_);
RELEASE_ASSERT_WITH_MSG(!obj->untag()->IsCardRemembered(), msg_);
if (obj.GetClassId() == kArrayCid) {
if (obj.GetClassIdOfHeapObject() == kArrayCid) {
const uword length =
Smi::Value(static_cast<UntaggedArray*>(obj.untag())->length());
RELEASE_ASSERT_WITH_MSG(!Array::UseCardMarkingForAllocation(length),
+10 -9
View File
@@ -185,8 +185,8 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
// Validate 'this' is a typed data view.
const uword view_header = ReadHeaderRelaxed(view);
ASSERT(!IsForwarding(view_header) || view->IsOldObject());
ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()) ||
IsUnmodifiableTypedDataViewClassId(view->GetClassIdMayBeSmi()));
ASSERT(IsTypedDataViewClassId(view->GetClassId()) ||
IsUnmodifiableTypedDataViewClassId(view->GetClassId()));
// Validate that the backing store is not a forwarding word. There is a data
// race reader the backing store's header unless there is only one worker.
@@ -200,7 +200,8 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
// views. This can cause the RecomputeDataFieldForInternalTypedData to
// run inappropriately, but when the object copy continues it will fix
// the data_ pointer.
ASSERT_EQUAL(IsExternalTypedDataClassId(td->GetClassId()), is_external);
ASSERT_EQUAL(IsExternalTypedDataClassId(td->GetClassIdOfHeapObject()),
is_external);
}
}
#endif
@@ -214,7 +215,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
// Now we update the inner pointer.
#if defined(DEBUG)
if (!parallel) {
ASSERT(IsTypedDataClassId(td->GetClassId()));
ASSERT(IsTypedDataClassId(td->GetClassIdOfHeapObject()));
}
#endif
view->untag()->RecomputeDataFieldForInternalTypedData();
@@ -901,7 +902,7 @@ class CollectStoreBufferScavengeVisitor : public ObjectPointerVisitor {
RELEASE_ASSERT_WITH_MSG(obj->IsOldObject(), msg_);
RELEASE_ASSERT_WITH_MSG(!obj->untag()->IsCardRemembered(), msg_);
if (obj.GetClassId() == kArrayCid) {
if (obj.GetClassIdOfHeapObject() == kArrayCid) {
const uword length =
Smi::Value(static_cast<UntaggedArray*>(obj.untag())->length());
RELEASE_ASSERT_WITH_MSG(!Array::UseCardMarkingForAllocation(length),
@@ -1421,7 +1422,7 @@ intptr_t ScavengerVisitorBase<parallel>::ProcessObject(ObjectPtr obj) {
}
#endif
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
if (UNLIKELY(cid == kWeakPropertyCid)) {
WeakPropertyPtr weak_property = static_cast<WeakPropertyPtr>(obj);
if (!IsScavengeSurvivor(weak_property->untag()->key())) {
@@ -1719,7 +1720,7 @@ void Scavenger::PruneWeak(GCLinkedList<Type, PtrType>* list) {
while (weak != Object::null()) {
PtrType next;
if (weak->IsOldObject()) {
ASSERT(weak->GetClassId() == Type::kClassId);
ASSERT(weak->GetClassIdOfHeapObject() == Type::kClassId);
next = weak->untag()->next_seen_by_gc_.Decompress(weak->heap_base());
weak->untag()->next_seen_by_gc_ = Type::null();
list->Enqueue(weak);
@@ -1727,13 +1728,13 @@ void Scavenger::PruneWeak(GCLinkedList<Type, PtrType>* list) {
uword header = ReadHeaderRelaxed(weak);
if (IsForwarding(header)) {
weak = static_cast<PtrType>(ForwardedObj(header));
ASSERT(weak->GetClassId() == Type::kClassId);
ASSERT(weak->GetClassIdOfHeapObject() == Type::kClassId);
next = weak->untag()->next_seen_by_gc_.Decompress(weak->heap_base());
weak->untag()->next_seen_by_gc_ = Type::null();
list->Enqueue(weak);
} else {
// Collected in this scavenge.
ASSERT(weak->GetClassId() == Type::kClassId);
ASSERT(weak->GetClassIdOfHeapObject() == Type::kClassId);
next = weak->untag()->next_seen_by_gc_.Decompress(weak->heap_base());
}
}
+3 -3
View File
@@ -131,7 +131,7 @@ uword ObjectOffsetTrait::Hash(Key key) {
uword body = UntaggedObject::ToAddr(obj) + sizeof(UntaggedObject);
uword end = UntaggedObject::ToAddr(obj) + obj->untag()->HeapSize();
uint32_t hash = obj->GetClassId();
uint32_t hash = obj->GetClassIdOfHeapObject();
// Don't include the header. Objects in the image are pre-marked, but objects
// in the current isolate are not.
for (uword cursor = body; cursor < end; cursor += sizeof(uint32_t)) {
@@ -147,7 +147,7 @@ bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
ASSERT(!a->IsSmi());
ASSERT(!b->IsSmi());
if (a->GetClassId() != b->GetClassId()) {
if (a->GetClassIdOfHeapObject() != b->GetClassIdOfHeapObject()) {
return false;
}
@@ -258,7 +258,7 @@ intptr_t ImageWriter::SizeInSnapshotForBytes(intptr_t length) {
}
intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw_object) {
const classid_t cid = raw_object->GetClassId();
const classid_t cid = raw_object->GetClassIdOfHeapObject();
switch (cid) {
case kCompressedStackMapsCid: {
+3 -3
View File
@@ -74,8 +74,8 @@ class ObjectLocator : public ObjectVisitor {
: context_(context), count_(0) {}
void VisitObject(ObjectPtr obj) override {
InstanceMorpher* morpher =
context_->instance_morpher_by_cid_.LookupValue(obj->GetClassId());
InstanceMorpher* morpher = context_->instance_morpher_by_cid_.LookupValue(
obj->GetClassIdOfHeapObject());
if (morpher != nullptr) {
morpher->AddObject(obj);
count_++;
@@ -1978,7 +1978,7 @@ class InvalidationCollector : public ObjectVisitor {
virtual ~InvalidationCollector() {}
void VisitObject(ObjectPtr obj) override {
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
if (cid == kFunctionCid) {
const Function& func =
Function::Handle(zone_, static_cast<FunctionPtr>(obj));
+1 -1
View File
@@ -5478,7 +5478,7 @@ class CidCountingVisitor : public ObjectVisitor {
virtual ~CidCountingVisitor() {}
virtual void VisitObject(ObjectPtr obj) {
if (obj->GetClassId() == cid_) {
if (obj->GetClassIdOfHeapObject() == cid_) {
count_++;
}
}
+1 -2
View File
@@ -97,8 +97,7 @@ void NativeEntry::MaybePropagateError(NativeArguments* arguments) {
// the kThreadInNative state.
ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
ObjectPtr retval = arguments->ReturnValue();
if (UNLIKELY(retval->IsHeapObject() &&
IsErrorClassId(retval->GetClassId()))) {
if (UNLIKELY(IsErrorClassId(retval->GetClassId()))) {
thread->UnwindScopes(thread->top_exit_frame_info());
TransitionGeneratedToVM transition(thread);
+7 -6
View File
@@ -1558,7 +1558,7 @@ void Object::FinalizeVMIsolate(IsolateGroup* isolate_group) {
void Object::FinalizeReadOnlyObject(ObjectPtr object) {
NoSafepointScope no_safepoint;
intptr_t cid = object->GetClassId();
intptr_t cid = object->GetClassIdOfHeapObject();
if (cid == kOneByteStringCid) {
OneByteStringPtr str = static_cast<OneByteStringPtr>(object);
if (String::GetCachedHash(str) == 0) {
@@ -2756,7 +2756,7 @@ void Object::InitializeObject(uword address,
void Object::CheckHandle() const {
#if defined(DEBUG)
if (ptr_ != Object::null()) {
intptr_t cid = ptr_->GetClassIdMayBeSmi();
intptr_t cid = ptr_->GetClassId();
if (cid >= kNumPredefinedCids) {
cid = kInstanceCid;
}
@@ -2908,6 +2908,7 @@ bool Object::IsNotTemporaryScopedHandle() const {
ObjectPtr Object::Clone(const Object& orig,
Heap::Space space,
bool load_with_relaxed_atomics) {
ASSERT(orig.ptr()->IsHeapObject());
// Generic function types should be cloned with FunctionType::Clone.
ASSERT(!orig.IsFunctionType() || !FunctionType::Cast(orig).IsGeneric());
const Class& cls = Class::Handle(orig.clazz());
@@ -2937,7 +2938,7 @@ ObjectPtr Object::Clone(const Object& orig,
size - kHeaderSizeInBytes);
}
if (IsTypedDataClassId(raw_clone->GetClassId())) {
if (IsTypedDataClassId(raw_clone->GetClassIdOfHeapObject())) {
auto raw_typed_data = TypedData::RawCast(raw_clone);
raw_typed_data.untag()->RecomputeDataField();
}
@@ -23532,7 +23533,7 @@ uword String::Hash(const uint16_t* characters, intptr_t len) {
}
intptr_t String::CharSize() const {
intptr_t class_id = ptr()->GetClassId();
intptr_t class_id = ptr()->GetClassIdOfHeapObject();
if (class_id == kOneByteStringCid) {
return kOneByteChar;
}
@@ -24313,8 +24314,8 @@ bool String::EqualsIgnoringPrivateKey(const String& str1, const String& str2) {
return true; // Both handles point to the same raw instance.
}
NoSafepointScope no_safepoint;
intptr_t str1_class_id = str1.ptr()->GetClassId();
intptr_t str2_class_id = str2.ptr()->GetClassId();
intptr_t str1_class_id = str1.ptr()->GetClassIdOfHeapObject();
intptr_t str2_class_id = str2.ptr()->GetClassIdOfHeapObject();
switch (str1_class_id) {
case kOneByteStringCid:
EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2);
+15 -15
View File
@@ -338,10 +338,7 @@ class Object {
bool IsImmutable() const { return ptr()->untag()->IsImmutable(); }
void SetImmutable() const { ptr()->untag()->SetImmutable(); }
void ClearImmutable() const { ptr()->untag()->ClearImmutable(); }
intptr_t GetClassId() const {
return !ptr()->IsHeapObject() ? static_cast<intptr_t>(kSmiCid)
: ptr()->untag()->GetClassId();
}
intptr_t GetClassId() const { return ptr()->GetClassId(); }
inline ClassPtr clazz() const;
static intptr_t tags_offset() { return OFFSET_OF(UntaggedObject, tags_); }
@@ -7163,7 +7160,7 @@ class Code : public Object {
if (!owner->IsHeapObject()) {
return RawSmiValue(static_cast<SmiPtr>(owner));
}
return owner->GetClassId();
return owner->GetClassIdOfHeapObject();
}
static intptr_t owner_offset() { return OFFSET_OF(UntaggedCode, owner_); }
@@ -10326,11 +10323,11 @@ class String : public Instance {
bool IsSymbol() const { return ptr()->untag()->IsCanonical(); }
bool IsOneByteString() const {
return ptr()->GetClassId() == kOneByteStringCid;
return ptr()->GetClassIdOfHeapObject() == kOneByteStringCid;
}
bool IsTwoByteString() const {
return ptr()->GetClassId() == kTwoByteStringCid;
return ptr()->GetClassIdOfHeapObject() == kTwoByteStringCid;
}
char* ToMallocCString() const;
@@ -10914,7 +10911,9 @@ class Array : public Instance {
untag()->set_element<std::memory_order_release>(index, value.ptr());
}
bool IsImmutable() const { return ptr()->GetClassId() == kImmutableArrayCid; }
bool IsImmutable() const {
return ptr()->GetClassIdOfHeapObject() == kImmutableArrayCid;
}
// Position of element type in type arguments.
static constexpr intptr_t kElementTypeTypeArgPos = 0;
@@ -11538,15 +11537,15 @@ class TypedDataBase : public PointerBase {
}
intptr_t LengthInBytes() const {
return ElementSizeInBytes(ptr()->GetClassId()) * Length();
return ElementSizeInBytes(ptr()->GetClassIdOfHeapObject()) * Length();
}
TypedDataElementType ElementType() const {
return ElementType(ptr()->GetClassId());
return ElementType(ptr()->GetClassIdOfHeapObject());
}
intptr_t ElementSizeInBytes() const {
return element_size(ElementType(ptr()->GetClassId()));
return element_size(ElementType(ptr()->GetClassIdOfHeapObject()));
}
static intptr_t ElementSizeInBytes(classid_t cid) {
@@ -11821,7 +11820,7 @@ class TypedDataView : public TypedDataBase {
static bool IsExternalTypedDataView(const TypedDataView& view_obj) {
const auto& data = Instance::Handle(Data(view_obj));
intptr_t cid = data.ptr()->GetClassId();
intptr_t cid = data.ptr()->GetClassIdOfHeapObject();
ASSERT(IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid));
return IsExternalTypedDataClassId(cid);
}
@@ -13237,13 +13236,14 @@ ClassPtr Object::clazz() const {
if ((raw_value & kSmiTagMask) == kSmiTag) {
return Smi::Class();
}
return IsolateGroup::Current()->class_table()->At(ptr()->GetClassId());
return IsolateGroup::Current()->class_table()->At(
ptr()->GetClassIdOfHeapObject());
}
DART_FORCE_INLINE
void Object::setPtr(ObjectPtr value, intptr_t default_cid) {
ptr_ = value;
intptr_t cid = value->GetClassIdMayBeSmi();
intptr_t cid = value->GetClassId();
// Free-list elements cannot be wrapped in a handle.
ASSERT(cid != kFreeListElement);
ASSERT(cid != kForwardingCorpse);
@@ -13426,7 +13426,7 @@ inline void TypeArguments::SetHash(intptr_t value) const {
}
inline uint16_t String::CharAt(StringPtr str, intptr_t index) {
switch (str->GetClassId()) {
switch (str->GetClassIdOfHeapObject()) {
case kOneByteStringCid:
return OneByteString::CharAt(static_cast<OneByteStringPtr>(str), index);
case kTwoByteStringCid:
+10 -10
View File
@@ -205,7 +205,7 @@ class ObjectGraph::Stack : public ObjectPointerVisitor {
void Visit(void* ptr, ObjectPtr obj) {
if (obj->IsHeapObject() && !obj->untag()->InVMIsolateHeap() &&
object_ids_->GetValueExclusive(obj) == 0) { // not visited yet
if (!include_vm_objects_ && !IsUserClass(obj->GetClassId())) {
if (!include_vm_objects_ && !IsUserClass(obj->GetClassIdOfHeapObject())) {
return;
}
object_ids_->SetValueExclusive(obj, 1);
@@ -241,7 +241,7 @@ class ObjectGraph::Stack : public ObjectPointerVisitor {
if (direction == ObjectGraph::Visitor::kProceed) {
set_gc_root_type(node.gc_root_type);
ASSERT(obj->IsHeapObject());
switch (obj->GetClassId()) {
switch (obj->GetClassIdOfHeapObject()) {
case kWeakArrayCid:
VisitWeakArray(static_cast<WeakArrayPtr>(obj));
break;
@@ -440,7 +440,7 @@ class InstanceAccumulator : public ObjectVisitor {
: stack_(stack), class_id_(class_id) {}
void VisitObject(ObjectPtr obj) override {
if (obj->GetClassId() == class_id_) {
if (obj->GetClassIdOfHeapObject() == class_id_) {
ObjectPtr rawobj = obj;
stack_->VisitPointer(&rawobj);
}
@@ -495,7 +495,7 @@ class SizeExcludingClassVisitor : public SizeVisitor {
public:
explicit SizeExcludingClassVisitor(intptr_t skip) : skip_(skip) {}
virtual bool ShouldSkip(ObjectPtr obj) const {
return obj->GetClassId() == skip_;
return obj->GetClassIdOfHeapObject() == skip_;
}
private:
@@ -550,7 +550,7 @@ class RetainingPathVisitor : public ObjectGraph::Visitor {
bool ShouldSkip(ObjectPtr obj) {
// A retaining path through ICData is never the only retaining path,
// and it is less informative than its alternatives.
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
switch (cid) {
case kICDataCid:
return true;
@@ -988,7 +988,7 @@ class Pass1Visitor : public ObjectVisitor,
if (obj->IsPseudoObject()) return;
writer_->AssignObjectId(obj);
const auto cid = obj->GetClassId();
const auto cid = obj->GetClassIdOfHeapObject();
if (object_slots_->ContainsOnlyTaggedPointers(cid)) {
obj->untag()->VisitPointersPrecise(this);
@@ -1123,7 +1123,7 @@ class Pass2Visitor : public ObjectVisitor,
void VisitObject(ObjectPtr obj) override {
if (obj->IsPseudoObject()) return;
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
writer_->WriteUnsigned(cid + kNumExtraCids);
writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->untag()->HeapSize());
@@ -1753,7 +1753,7 @@ void HeapSnapshotWriter::Write() {
uint32_t HeapSnapshotWriter::GetHeapSnapshotIdentityHash(Thread* thread,
ObjectPtr obj) {
if (!obj->IsHeapObject()) return 0;
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
uint32_t hash = 0;
switch (cid) {
case kForwardingCorpse:
@@ -1843,7 +1843,7 @@ CountObjectsVisitor::CountObjectsVisitor(Thread* thread, intptr_t class_count)
}
void CountObjectsVisitor::VisitObject(ObjectPtr obj) {
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
intptr_t size = obj->untag()->HeapSize();
if (obj->IsNewObject()) {
new_count_[cid] += 1;
@@ -1861,7 +1861,7 @@ void CountObjectsVisitor::VisitHandle(uword addr) {
if (!obj->IsHeapObject()) {
return;
}
intptr_t cid = obj->GetClassId();
intptr_t cid = obj->GetClassIdOfHeapObject();
intptr_t size = handle->external_size();
if (obj->IsNewObject()) {
new_external_size_[cid] += size;
+4 -4
View File
@@ -462,7 +462,7 @@ class IdentityMap {
uint32_t GetHeaderHash(ObjectPtr object) {
uint32_t hash = Object::GetCachedHash(object);
if (hash == 0) {
switch (object->GetClassId()) {
switch (object->GetClassIdOfHeapObject()) {
case kMintCid:
hash = Mint::Value(static_cast<MintPtr>(object));
// Don't write back: doesn't agree with dart:core's identityHash.
@@ -1021,7 +1021,7 @@ class RetainingPath {
int length = working_list->length();
do { // This loop is here so that we can skip children processing
const intptr_t cid = raw->GetClassId();
const intptr_t cid = raw->GetClassIdOfHeapObject();
if (traversal_rules_ == TraversalRules::kInternalToIsolateGroup) {
if (CanShareObjectAcrossIsolates(raw)) {
@@ -1964,7 +1964,7 @@ class ObjectCopy : public Base {
void CopyTypedData(TypedDataPtr from, TypedDataPtr to) {
auto raw_from = from.untag();
auto raw_to = to.untag();
const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassId();
const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassIdOfHeapObject();
raw_to->length_ = raw_from->length_;
raw_to->RecomputeDataField();
const intptr_t length =
@@ -1975,7 +1975,7 @@ class ObjectCopy : public Base {
void CopyTypedData(const TypedData& from, const TypedData& to) {
auto raw_from = from.ptr().untag();
auto raw_to = to.ptr().untag();
const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassId();
const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassIdOfHeapObject();
ASSERT(raw_to->length_ == raw_from->length_);
raw_to->RecomputeDataField();
const intptr_t length =
+11 -5
View File
@@ -369,11 +369,14 @@ ISOLATE_UNIT_TEST_CASE(Smi) {
Object& smi_object = Object::Handle(smi.ptr());
EXPECT(smi.IsSmi());
EXPECT(smi_object.IsSmi());
EXPECT(smi_object.ptr()->IsSmi());
EXPECT_EQ(5, smi.Value());
const Object& object = Object::Handle();
EXPECT(!object.IsSmi());
EXPECT(!object.ptr()->IsSmi());
smi_object = Object::null();
EXPECT(!smi_object.IsSmi());
EXPECT(!smi_object.ptr()->IsSmi());
EXPECT(smi.Equals(Smi::Handle(Smi::New(5))));
EXPECT(!smi.Equals(Smi::Handle(Smi::New(6))));
@@ -397,6 +400,7 @@ ISOLATE_UNIT_TEST_CASE(Smi) {
EXPECT_EQ(5, smi.AsInt64Value());
EXPECT_EQ(5.0, smi.AsDoubleValue());
EXPECT_EQ(5, Integer::GetInt64Value(smi.ptr()));
Smi& a = Smi::Handle(Smi::New(5));
Smi& b = Smi::Handle(Smi::New(3));
@@ -535,6 +539,9 @@ ISOLATE_UNIT_TEST_CASE(Mint) {
}
Integer& i = Integer::Handle(Integer::New(DART_2PART_UINT64_C(1, 0)));
EXPECT(i.IsMint());
EXPECT(i.ptr()->IsMint());
EXPECT(!i.IsSmi());
EXPECT(!i.ptr()->IsSmi());
EXPECT(!i.IsZero());
EXPECT(!i.IsNegative());
Integer& i1 = Integer::Handle(Integer::New(DART_2PART_UINT64_C(1010, 0)));
@@ -544,6 +551,7 @@ ISOLATE_UNIT_TEST_CASE(Mint) {
EXPECT(!i.Equals(i1));
int64_t test = DART_2PART_UINT64_C(1010, 0);
EXPECT_EQ(test, i2.value());
EXPECT_EQ(test, Integer::GetInt64Value(i2.ptr()));
Mint& a = Mint::Handle();
a ^= Integer::New(DART_2PART_UINT64_C(5, 0));
@@ -8140,8 +8148,7 @@ static void SubtypeTestCacheCheckContents(Zone* zone,
const intptr_t entry_start = i * SubtypeTestCache::kTestEntryLength;
{
const intptr_t cid =
array.At(entry_start + SubtypeTestCache::kTestResult)
->GetClassIdMayBeSmi();
array.At(entry_start + SubtypeTestCache::kTestResult)->GetClassId();
EXPECT(cid == kNullCid || cid == kBoolCid);
}
@@ -8152,8 +8159,7 @@ static void SubtypeTestCacheCheckContents(Zone* zone,
#define USED_INPUT_CASE(Input, ExpectedCids) \
case (Input) + 1: { \
RELEASE_ASSERT((Input) + 1 == check_ordering); \
const intptr_t cid = \
array.At(entry_start + (Input))->GetClassIdMayBeSmi(); \
const intptr_t cid = array.At(entry_start + (Input))->GetClassId(); \
if (!(ExpectedCids)) { \
FAIL("expected: " #ExpectedCids ", got: cid %" Pd "", cid); \
} \
@@ -8195,7 +8201,7 @@ static void SubtypeTestCacheCheckContents(Zone* zone,
// STCs and never set unused inputs, the only thing we know is that the
// entry is GC-safe. Since we don't expect valid values for unused inputs,
// we just check if it's either a Smi or null.
const intptr_t cid = array.At(entry_start + i)->GetClassIdMayBeSmi();
const intptr_t cid = array.At(entry_start + i)->GetClassId();
EXPECT(cid == kSmiCid || cid == kNullCid);
}
}
+3 -2
View File
@@ -560,7 +560,7 @@ VARIABLE_COMPRESSED_VISITOR(Context, raw_obj->untag()->num_variables_)
VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(
TypedData,
TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
TypedData::ElementSizeInBytes(raw_obj->GetClassIdOfHeapObject()) *
Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
VARIABLE_COMPRESSED_VISITOR(Record,
@@ -715,7 +715,8 @@ intptr_t UntaggedInstance::VisitInstancePointers(
uword tags = raw_obj->untag()->tags_;
intptr_t instance_size = SizeTag::decode(tags);
if (instance_size == 0) {
instance_size = visitor->class_table()->SizeAt(raw_obj->GetClassId());
instance_size =
visitor->class_table()->SizeAt(raw_obj->GetClassIdOfHeapObject());
}
// Calculate the first and last raw object pointer fields.
+4 -1
View File
@@ -882,9 +882,12 @@ DART_FORCE_INLINE uword UntaggedObject::to_offset(intptr_t length) {
}
}
inline intptr_t ObjectPtr::GetClassId() const {
inline intptr_t ObjectPtr::GetClassIdOfHeapObject() const {
return untag()->GetClassId();
}
inline intptr_t ObjectPtr::GetClassId() const {
return IsHeapObject() ? GetClassIdOfHeapObject() : kSmiCid;
}
#define POINTER_FIELD(type, name) \
public: \
+1 -1
View File
@@ -3512,7 +3512,7 @@ class GetInstancesVisitor : public ObjectGraph::Visitor {
if (raw_obj->IsPseudoObject()) {
return kProceed;
}
if (table_->CollectInstancesFor(raw_obj->GetClassId())) {
if (table_->CollectInstancesFor(raw_obj->GetClassIdOfHeapObject())) {
if (count_ < limit_) {
storage_->Add(Object::Handle(raw_obj));
}
+1 -1
View File
@@ -231,7 +231,7 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
// May forward raw code. Note we don't just visit the pc marker slot first
// because the visitor's forwarding might not be idempotent.
visitor->VisitPointer(&pc_marker);
if (pc_marker->IsHeapObject() && (pc_marker->GetClassId() == kCodeCid)) {
if (pc_marker->GetClassId() == kCodeCid) {
code ^= pc_marker;
code_start = code.PayloadStart();
ASSERT(code.compressed_stackmaps() != CompressedStackMaps::null());
+8 -6
View File
@@ -135,22 +135,24 @@ class ObjectPtr {
bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
bool IsRawNull() const { return GetClassId() == kNullCid; }
bool IsDartInstance() const {
return (!IsHeapObject() || !IsInternalOnlyClassId(GetClassId()));
return (!IsHeapObject() ||
!IsInternalOnlyClassId(GetClassIdOfHeapObject()));
}
// Only works with heap objects.
bool IsFreeListElement() const {
return ((GetClassId() == kFreeListElement));
return ((GetClassIdOfHeapObject() == kFreeListElement));
}
// Only works with heap objects.
bool IsForwardingCorpse() const {
return ((GetClassId() == kForwardingCorpse));
return ((GetClassIdOfHeapObject() == kForwardingCorpse));
}
// Only works with heap objects.
bool IsPseudoObject() const {
return IsFreeListElement() || IsForwardingCorpse();
}
intptr_t GetClassId() const;
intptr_t GetClassIdMayBeSmi() const {
return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
}
intptr_t GetClassIdOfHeapObject() const;
void Validate(IsolateGroup* isolate_group) const;
+1 -1
View File
@@ -1037,7 +1037,7 @@ class RestoreWriteBarrierInvariantVisitor : public ObjectPointerVisitor {
// To avoid adding too much work into the remembered set, skip large
// arrays. Write barrier elimination will not remove the barrier
// if we can trigger GC between array allocation and store.
if (obj->GetClassId() == kArrayCid) {
if (obj->GetClassIdOfHeapObject() == kArrayCid) {
const auto length = Smi::Value(Array::RawCast(obj)->untag()->length());
if (length > Array::kMaxLengthForWriteBarrierElimination) {
continue;