dart-sdk/runtime/vm/megamorphic_cache_table.cc
Martin Kustermann 63b567add2 [vm] Split isolate initialization logic into two pieces
This splits `Dart::InitializeIsolate()` into

* `Dart::InitializeIsolateGroup()` that sets up an `IsolateGroup`
  => This is only done at isolate group creation time when the very
     first isolate is created.

* `Dart::InitializeIsolate()` that sets up an `Isolate`.
  => This is done for every isolate.

This is purely refactoring / code cleanup.

TEST=ci

Change-Id: Ica906444f79fe49849b9e11e96f7c89184cb9d09
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311603
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2023-06-29 08:04:20 +00:00

119 lines
3.9 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/megamorphic_cache_table.h"
#include <stdlib.h>
#include "vm/compiler/jit/compiler.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
namespace dart {
MegamorphicCachePtr MegamorphicCacheTable::Lookup(Thread* thread,
const String& name,
const Array& descriptor) {
auto object_store = thread->isolate_group()->object_store();
SafepointMutexLocker ml(thread->isolate_group()->megamorphic_table_mutex());
ASSERT(name.IsSymbol());
// TODO(rmacnak): ASSERT(descriptor.IsCanonical());
// TODO(rmacnak): Make a proper hashtable a la symbol table.
auto& table =
GrowableObjectArray::Handle(object_store->megamorphic_cache_table());
MegamorphicCache& cache = MegamorphicCache::Handle();
if (table.IsNull()) {
table = GrowableObjectArray::New(Heap::kOld);
object_store->set_megamorphic_cache_table(table);
} else {
for (intptr_t i = 0; i < table.Length(); i++) {
cache ^= table.At(i);
if ((cache.target_name() == name.ptr()) &&
(cache.arguments_descriptor() == descriptor.ptr())) {
return cache.ptr();
}
}
}
cache = MegamorphicCache::New(name, descriptor);
table.Add(cache, Heap::kOld);
return cache.ptr();
}
void MegamorphicCacheTable::PrintSizes(Thread* thread) {
auto isolate_group = thread->isolate_group();
SafepointMutexLocker ml(isolate_group->megamorphic_table_mutex());
StackZone zone(thread);
intptr_t size = 0;
MegamorphicCache& cache = MegamorphicCache::Handle();
Array& buckets = Array::Handle();
const GrowableObjectArray& table = GrowableObjectArray::Handle(
isolate_group->object_store()->megamorphic_cache_table());
if (table.IsNull()) return;
intptr_t max_size = 0;
for (intptr_t i = 0; i < table.Length(); i++) {
cache ^= table.At(i);
buckets = cache.buckets();
size += MegamorphicCache::InstanceSize();
size += Array::InstanceSize(buckets.Length());
if (buckets.Length() > max_size) {
max_size = buckets.Length();
}
}
OS::PrintErr("%" Pd " megamorphic caches using %" Pd "KB.\n", table.Length(),
size / 1024);
intptr_t* probe_counts = new intptr_t[max_size];
intptr_t entry_count = 0;
intptr_t max_probe_count = 0;
for (intptr_t i = 0; i < max_size; i++) {
probe_counts[i] = 0;
}
for (intptr_t i = 0; i < table.Length(); i++) {
cache ^= table.At(i);
buckets = cache.buckets();
intptr_t mask = cache.mask();
intptr_t capacity = mask + 1;
for (intptr_t j = 0; j < capacity; j++) {
intptr_t class_id =
Smi::Value(Smi::RawCast(cache.GetClassId(buckets, j)));
if (class_id != kIllegalCid) {
intptr_t probe_count = 0;
intptr_t probe_index =
(class_id * MegamorphicCache::kSpreadFactor) & mask;
intptr_t probe_cid;
while (true) {
probe_count++;
probe_cid =
Smi::Value(Smi::RawCast(cache.GetClassId(buckets, probe_index)));
if (probe_cid == class_id) {
break;
}
probe_index = (probe_index + 1) & mask;
}
probe_counts[probe_count]++;
if (probe_count > max_probe_count) {
max_probe_count = probe_count;
}
entry_count++;
}
}
}
intptr_t cumulative_entries = 0;
for (intptr_t i = 0; i <= max_probe_count; i++) {
cumulative_entries += probe_counts[i];
OS::PrintErr("Megamorphic probe %" Pd ": %" Pd " (%lf)\n", i,
probe_counts[i],
static_cast<double>(cumulative_entries) /
static_cast<double>(entry_count));
}
delete[] probe_counts;
}
} // namespace dart