[vm] Replace KernelConstantsMap with array

This CL replaces the KernelConstantsMap (backed by an Array that got
replaced on growing) by an Array that is allocated to be the required
size.

Does not cache the start of the constants table in the constructor
as proposed in [1], because the constants table is null when the
ConstantReader constructor is called in the KernelLoader constructor.

[1] https://dart-review.googlesource.com/c/sdk/+/196925/6..10/runtime/vm/compiler/frontend/constant_reader.cc#b116

Closes: https://github.com/dart-lang/sdk/issues/45903

TEST=vm test suite, including GC tests.

Change-Id: Ie111bedc7eb7fcd627ab700a9906245bc7dd14ce
Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-debug-x64-try,vm-kernel-linux-debug-x64c-try,vm-kernel-linux-release-simarm64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try
Fixed: 45903
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200871
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
Daco Harkes 2021-05-26 09:41:42 +00:00 committed by commit-bot@chromium.org
parent 1d0bac85bc
commit cd0f6aed25
3 changed files with 32 additions and 49 deletions

View file

@ -87,21 +87,20 @@ InstancePtr ConstantReader::ReadConstant(intptr_t constant_index) {
{
SafepointMutexLocker ml(
H.thread()->isolate_group()->kernel_constants_mutex());
KernelConstantsMap constant_map(H.info().constants());
result_ ^= constant_map.GetOrNull(constant_index);
ASSERT(constant_map.Release().ptr() == H.info().constants());
const auto& constants_array = Array::Handle(Z, H.info().constants());
ASSERT(constant_index < constants_array.Length());
result_ ^= constants_array.At(constant_index);
}
// On miss, evaluate, and insert value.
if (result_.IsNull()) {
if (result_.ptr() == Object::sentinel().ptr()) {
LeaveCompilerScope cs(H.thread());
result_ = ReadConstantInternal(constant_index);
SafepointMutexLocker ml(
H.thread()->isolate_group()->kernel_constants_mutex());
KernelConstantsMap constant_map(H.info().constants());
auto insert = constant_map.InsertNewOrGetValue(constant_index, result_);
ASSERT(insert == result_.ptr());
H.info().set_constants(constant_map.Release()); // update!
const auto& constants_array = Array::Handle(Z, H.info().constants());
ASSERT(constant_index < constants_array.Length());
constants_array.SetAt(constant_index, result_);
}
return result_.ptr();
}
@ -120,12 +119,22 @@ bool ConstantReader::IsInstanceConstant(intptr_t constant_index,
return false;
}
intptr_t ConstantReader::NavigateToIndex(KernelReaderHelper* reader,
intptr_t constant_index) {
intptr_t ConstantReader::NumConstants() {
ASSERT(!H.constants_table().IsNull());
KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
return NumConstants(&reader);
}
intptr_t ConstantReader::NumConstants(KernelReaderHelper* reader) {
// Get reader directly into raw bytes of constant table/constant mapping.
// Get the length of the constants (at the end of the mapping).
reader->SetOffset(reader->ReaderSize() - 4);
const intptr_t num_constants = reader->ReadUInt32();
return reader->ReadUInt32();
}
intptr_t ConstantReader::NavigateToIndex(KernelReaderHelper* reader,
intptr_t constant_index) {
const intptr_t num_constants = NumConstants(reader);
// Get the binary offset of the constant at the wanted index.
reader->SetOffset(reader->ReaderSize() - 4 - (num_constants * 4) +

View file

@ -35,9 +35,12 @@ class ConstantReader {
// into sub-constants).
InstancePtr ReadConstant(intptr_t constant_index);
intptr_t NumConstants();
private:
InstancePtr ReadConstantInternal(intptr_t constant_index);
intptr_t NavigateToIndex(KernelReaderHelper* reader, intptr_t constant_index);
intptr_t NumConstants(KernelReaderHelper* reader);
KernelReaderHelper* helper_;
Zone* zone_;
@ -49,38 +52,6 @@ class ConstantReader {
DISALLOW_COPY_AND_ASSIGN(ConstantReader);
};
class KernelConstMapKeyEqualsTraits : public AllStatic {
public:
static const char* Name() { return "KernelConstMapKeyEqualsTraits"; }
static bool ReportStats() { return false; }
static bool IsMatch(const Object& a, const Object& b) {
const Smi& key1 = Smi::Cast(a);
const Smi& key2 = Smi::Cast(b);
return (key1.Value() == key2.Value());
}
static bool IsMatch(const intptr_t key1, const Object& b) {
return KeyAsSmi(key1) == Smi::Cast(b).ptr();
}
static uword Hash(const Object& obj) {
const Smi& key = Smi::Cast(obj);
return HashValue(key.Value());
}
static uword Hash(const intptr_t key) {
return HashValue(Smi::Value(KeyAsSmi(key)));
}
static ObjectPtr NewKey(const intptr_t key) { return KeyAsSmi(key); }
private:
static uword HashValue(intptr_t pos) { return pos % (Smi::kMaxValue - 13); }
static SmiPtr KeyAsSmi(const intptr_t key) {
ASSERT(key >= 0);
return Smi::New(key);
}
};
typedef UnorderedHashMap<KernelConstMapKeyEqualsTraits> KernelConstantsMap;
} // namespace kernel
} // namespace dart

View file

@ -699,13 +699,16 @@ ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) {
}
}
// Sets the constants array to an empty hash and leaves the constant
// table's raw bytes in place for lazy reading. We can fix up all
// "pending" processing now, and must ensure we don't create new
// ones from this point on.
// Sets the constants array to an empty array with the length equal to
// the number of constants. The array gets filled lazily while reading
// constants.
ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
const Array& array =
Array::Handle(Z, HashTables::New<KernelConstantsMap>(16, Heap::kOld));
ConstantReader constant_reader(&helper_, &active_class_);
const intptr_t num_consts = constant_reader.NumConstants();
const Array& array = Array::Handle(Z, Array::New(num_consts, Heap::kOld));
for (intptr_t i = 0; i < num_consts; i++) {
array.SetAt(i, Object::sentinel());
}
kernel_program_info_.set_constants(array);
H.SetConstants(array); // for caching
AnnotateNativeProcedures();