[vm] Detect when class table overflows

We only have 16bits for cids so class table
can't contain more than 65535 classes.

TEST=ci

Bug: b/255934984
Change-Id: I79d45f4f28399b0a61293ace40b8718f2569ef3c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/266320
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
Vyacheslav Egorov 2022-10-27 22:15:32 +00:00 committed by Commit Queue
parent 2dfcce6a90
commit 3aa7a9e2b4
2 changed files with 23 additions and 14 deletions

View file

@ -4,7 +4,6 @@
#include "vm/class_table.h"
#include <limits>
#include <memory>
#include "platform/atomic.h"
@ -80,12 +79,6 @@ void ClassTable::Register(const Class& cls) {
}
void ClassTable::RegisterTopLevel(const Class& cls) {
if (top_level_classes_.num_cids() >= std::numeric_limits<classid_t>::max()) {
FATAL1("Fatal error in ClassTable::RegisterTopLevel: invalid index %" Pd
"\n",
top_level_classes_.num_cids());
}
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(cls.id() == kIllegalCid);

View file

@ -5,6 +5,7 @@
#ifndef RUNTIME_VM_CLASS_TABLE_H_
#define RUNTIME_VM_CLASS_TABLE_H_
#include <limits>
#include <memory>
#include <tuple>
#include <utility>
@ -148,7 +149,7 @@ class ClassTableAllocator : public ValueObject {
//
// Each column is a continous array of a the given type. All columns have
// the same number of used elements (|num_cids()|) and the same capacity.
template <typename... Columns>
template <typename CidType, typename... Columns>
class CidIndexedTable {
public:
explicit CidIndexedTable(ClassTableAllocator* allocator)
@ -169,17 +170,19 @@ class CidIndexedTable {
},
columns_);
capacity_ = new_capacity;
num_cids_ = new_num_cids;
SetNumCids(new_num_cids);
}
void AllocateIndex(intptr_t index, bool* did_grow) {
*did_grow = EnsureCapacity(index);
num_cids_ = Utils::Maximum(num_cids_, index + 1);
SetNumCids(Utils::Maximum(num_cids_, index + 1));
}
intptr_t AddRow(bool* did_grow) {
*did_grow = EnsureCapacity(num_cids_);
return num_cids_++;
intptr_t id = num_cids_;
SetNumCids(num_cids_ + 1);
return id;
}
void ShrinkTo(intptr_t new_num_cids) {
@ -268,6 +271,13 @@ class CidIndexedTable {
AcqRelAtomic<T*> ptr = {nullptr};
};
void SetNumCids(intptr_t new_num_cids) {
if (new_num_cids > std::numeric_limits<CidType>::max()) {
FATAL("Too many classes");
}
num_cids_ = new_num_cids;
}
bool EnsureCapacity(intptr_t index) {
if (index >= capacity_) {
SetNumCidsAndCapacity(num_cids_, index + kCapacityIncrement);
@ -538,9 +548,15 @@ class ClassTable : public MallocAllocated {
};
#if !defined(PRODUCT)
CidIndexedTable<ClassPtr, uint32_t, UnboxedFieldBitmap, uint8_t> classes_;
CidIndexedTable<ClassIdTagType,
ClassPtr,
uint32_t,
UnboxedFieldBitmap,
uint8_t>
classes_;
#else
CidIndexedTable<ClassPtr, uint32_t, UnboxedFieldBitmap> classes_;
CidIndexedTable<ClassIdTagType, ClassPtr, uint32_t, UnboxedFieldBitmap>
classes_;
#endif
#ifndef PRODUCT
@ -551,7 +567,7 @@ class ClassTable : public MallocAllocated {
};
#endif // !PRODUCT
CidIndexedTable<ClassPtr> top_level_classes_;
CidIndexedTable<classid_t, ClassPtr> top_level_classes_;
};
} // namespace dart