mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:45:06 +00:00
[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:
parent
2dfcce6a90
commit
3aa7a9e2b4
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue