mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:51:19 +00:00
Revert "Move megamorphic cache table into the Dart heap."
We're somewhere attempting to recompile the megamoprhic miss function. Review URL: https://codereview.chromium.org//1334283004 .
This commit is contained in:
parent
3068f1e092
commit
33b037125f
|
@ -1012,7 +1012,7 @@ DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
|
|||
const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2));
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const MegamorphicCache& cache = MegamorphicCache::Handle(
|
||||
MegamorphicCacheTable::Lookup(isolate, name, descriptor));
|
||||
isolate->megamorphic_cache_table()->Lookup(name, descriptor));
|
||||
Class& cls = Class::Handle(receiver.clazz());
|
||||
ASSERT(!cls.IsNull());
|
||||
if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
|
||||
|
|
|
@ -158,7 +158,7 @@ const char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot,
|
|||
OS::Print("Size of vm isolate snapshot = %" Pd "\n",
|
||||
snapshot->length());
|
||||
vm_isolate_->heap()->PrintSizes();
|
||||
MegamorphicCacheTable::PrintSizes(vm_isolate_);
|
||||
vm_isolate_->megamorphic_cache_table()->PrintSizes();
|
||||
intptr_t size;
|
||||
intptr_t capacity;
|
||||
Symbols::GetStats(vm_isolate_, &size, &capacity);
|
||||
|
@ -294,7 +294,7 @@ RawError* Dart::InitializeIsolate(const uint8_t* snapshot_buffer, void* data) {
|
|||
}
|
||||
if (FLAG_trace_isolates) {
|
||||
I->heap()->PrintSizes();
|
||||
MegamorphicCacheTable::PrintSizes(I);
|
||||
I->megamorphic_cache_table()->PrintSizes();
|
||||
}
|
||||
} else {
|
||||
// Populate the isolate's symbol table with all symbols from the
|
||||
|
@ -311,7 +311,7 @@ RawError* Dart::InitializeIsolate(const uint8_t* snapshot_buffer, void* data) {
|
|||
StubCode::Init(I);
|
||||
}
|
||||
|
||||
MegamorphicCacheTable::InitMissHandler(I);
|
||||
I->megamorphic_cache_table()->InitMissHandler();
|
||||
if (snapshot_buffer == NULL) {
|
||||
if (!I->object_store()->PreallocateObjects()) {
|
||||
return I->object_store()->sticky_error();
|
||||
|
|
|
@ -1284,12 +1284,13 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
|||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = R0;
|
||||
const Register cacheR = R1;
|
||||
const Register targetR = R1;
|
||||
|
|
|
@ -1257,12 +1257,13 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
|||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = R0;
|
||||
const Register cacheR = R1;
|
||||
const Register targetR = R1;
|
||||
|
|
|
@ -1296,12 +1296,13 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
|||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
|
||||
table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = EDI;
|
||||
const Register cacheR = EBX;
|
||||
const Register targetR = EBX;
|
||||
|
|
|
@ -1282,12 +1282,13 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
|||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
__ Comment("MegamorphicInstanceCall");
|
||||
const Register receiverR = T0;
|
||||
const Register cacheR = T1;
|
||||
|
|
|
@ -1311,12 +1311,13 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
|||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = RDI;
|
||||
const Register cacheR = RBX;
|
||||
const Register targetR = RCX;
|
||||
|
|
|
@ -1544,7 +1544,7 @@ void Isolate::Shutdown() {
|
|||
|
||||
if (FLAG_trace_isolates) {
|
||||
heap()->PrintSizes();
|
||||
MegamorphicCacheTable::PrintSizes(this);
|
||||
megamorphic_cache_table()->PrintSizes();
|
||||
Symbols::DumpStats();
|
||||
OS::Print("[-] Stopping isolate:\n"
|
||||
"\tisolate: %s\n", name());
|
||||
|
@ -1623,6 +1623,9 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
|
|||
// Visit objects in the class table.
|
||||
class_table()->VisitObjectPointers(visitor);
|
||||
|
||||
// Visit objects in the megamorphic cache.
|
||||
megamorphic_cache_table()->VisitObjectPointers(visitor);
|
||||
|
||||
// Visit objects in per isolate stubs.
|
||||
StubCode::VisitObjectPointers(visitor);
|
||||
|
||||
|
|
|
@ -145,6 +145,10 @@ class Isolate : public BaseIsolate {
|
|||
return OFFSET_OF(Isolate, class_table_);
|
||||
}
|
||||
|
||||
MegamorphicCacheTable* megamorphic_cache_table() {
|
||||
return &megamorphic_cache_table_;
|
||||
}
|
||||
|
||||
Dart_MessageNotifyCallback message_notify_callback() const {
|
||||
return message_notify_callback_;
|
||||
}
|
||||
|
@ -811,6 +815,7 @@ class Isolate : public BaseIsolate {
|
|||
StoreBuffer* store_buffer_;
|
||||
ThreadRegistry* thread_registry_;
|
||||
ClassTable class_table_;
|
||||
MegamorphicCacheTable megamorphic_cache_table_;
|
||||
Dart_MessageNotifyCallback message_notify_callback_;
|
||||
char* name_;
|
||||
char* debugger_name_;
|
||||
|
|
|
@ -6,52 +6,50 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "vm/object.h"
|
||||
#include "vm/object_store.h"
|
||||
#include "vm/stub_code.h"
|
||||
#include "vm/symbols.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
RawMegamorphicCache* MegamorphicCacheTable::Lookup(Isolate* isolate,
|
||||
const String& name,
|
||||
const Array& descriptor) {
|
||||
ASSERT(name.IsSymbol());
|
||||
// TODO(rmacnak): ASSERT(descriptor.IsCanonical());
|
||||
MegamorphicCacheTable::MegamorphicCacheTable()
|
||||
: miss_handler_function_(NULL),
|
||||
miss_handler_code_(NULL),
|
||||
capacity_(0),
|
||||
length_(0),
|
||||
table_(NULL) {
|
||||
}
|
||||
|
||||
// TODO(rmacnak): Make a proper hashtable a la symbol table.
|
||||
GrowableObjectArray& table = GrowableObjectArray::Handle(
|
||||
isolate->object_store()->megamorphic_cache_table());
|
||||
if (table.IsNull()) {
|
||||
table = GrowableObjectArray::New();
|
||||
ASSERT((table.Length() % kEntrySize) == 0);
|
||||
isolate->object_store()->set_megamorphic_cache_table(table);
|
||||
} else {
|
||||
for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
|
||||
if ((table.At(i + kEntryNameOffset) == name.raw()) &&
|
||||
(table.At(i + kEntryDescriptorOffset) == descriptor.raw())) {
|
||||
return MegamorphicCache::RawCast(table.At(i + kEntryCacheOffset));
|
||||
}
|
||||
|
||||
MegamorphicCacheTable::~MegamorphicCacheTable() {
|
||||
free(table_);
|
||||
}
|
||||
|
||||
|
||||
RawMegamorphicCache* MegamorphicCacheTable::Lookup(const String& name,
|
||||
const Array& descriptor) {
|
||||
for (intptr_t i = 0; i < length_; ++i) {
|
||||
if ((table_[i].name == name.raw()) &&
|
||||
(table_[i].descriptor == descriptor.raw())) {
|
||||
return table_[i].cache;
|
||||
}
|
||||
}
|
||||
|
||||
if (length_ == capacity_) {
|
||||
capacity_ += kCapacityIncrement;
|
||||
table_ =
|
||||
reinterpret_cast<Entry*>(realloc(table_, capacity_ * sizeof(*table_)));
|
||||
}
|
||||
|
||||
ASSERT(length_ < capacity_);
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::Handle(MegamorphicCache::New());
|
||||
table.Add(name);
|
||||
table.Add(descriptor);
|
||||
table.Add(cache);
|
||||
ASSERT((table.Length() % kEntrySize) == 0);
|
||||
Entry entry = { name.raw(), descriptor.raw(), cache.raw() };
|
||||
table_[length_++] = entry;
|
||||
return cache.raw();
|
||||
}
|
||||
|
||||
|
||||
RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) {
|
||||
ASSERT(isolate->object_store()->megamorphic_miss_handler() !=
|
||||
Function::null());
|
||||
return isolate->object_store()->megamorphic_miss_handler();
|
||||
}
|
||||
|
||||
|
||||
void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) {
|
||||
void MegamorphicCacheTable::InitMissHandler() {
|
||||
// The miss handler for a class ID not found in the table is invoked as a
|
||||
// normal Dart function.
|
||||
const Code& code =
|
||||
|
@ -71,27 +69,37 @@ void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) {
|
|||
0)); // No token position.
|
||||
function.set_is_debuggable(false);
|
||||
function.set_is_visible(false);
|
||||
miss_handler_code_ = code.raw();
|
||||
miss_handler_function_ = function.raw();
|
||||
function.AttachCode(code);
|
||||
|
||||
isolate->object_store()->set_megamorphic_miss_handler(function);
|
||||
}
|
||||
|
||||
|
||||
void MegamorphicCacheTable::PrintSizes(Isolate* isolate) {
|
||||
void MegamorphicCacheTable::VisitObjectPointers(ObjectPointerVisitor* v) {
|
||||
ASSERT(v != NULL);
|
||||
v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_code_));
|
||||
v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_function_));
|
||||
for (intptr_t i = 0; i < length_; ++i) {
|
||||
v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].name));
|
||||
v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].descriptor));
|
||||
v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].cache));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MegamorphicCacheTable::PrintSizes() {
|
||||
StackZone zone(Thread::Current());
|
||||
intptr_t size = 0;
|
||||
MegamorphicCache& cache = MegamorphicCache::Handle();
|
||||
Array& buckets = Array::Handle();
|
||||
const GrowableObjectArray& table = GrowableObjectArray::Handle(
|
||||
isolate->object_store()->megamorphic_cache_table());
|
||||
for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
|
||||
cache ^= table.At(i + kEntryCacheOffset);
|
||||
for (intptr_t i = 0; i < length_; ++i) {
|
||||
cache = table_[i].cache;
|
||||
buckets = cache.buckets();
|
||||
size += MegamorphicCache::InstanceSize();
|
||||
size += Array::InstanceSize(buckets.Length());
|
||||
}
|
||||
OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
|
||||
table.Length() / kEntrySize, size / 1024);
|
||||
length_, size / 1024);
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace dart {
|
|||
|
||||
class Array;
|
||||
class Function;
|
||||
class Isolate;
|
||||
class ObjectPointerVisitor;
|
||||
class RawArray;
|
||||
class RawFunction;
|
||||
|
@ -20,24 +19,36 @@ class RawMegamorphicCache;
|
|||
class RawString;
|
||||
class String;
|
||||
|
||||
class MegamorphicCacheTable : public AllStatic {
|
||||
class MegamorphicCacheTable {
|
||||
public:
|
||||
static RawFunction* miss_handler(Isolate* isolate);
|
||||
static void InitMissHandler(Isolate* isolate);
|
||||
MegamorphicCacheTable();
|
||||
~MegamorphicCacheTable();
|
||||
|
||||
static RawMegamorphicCache* Lookup(Isolate* isolate,
|
||||
const String& name,
|
||||
const Array& descriptor);
|
||||
RawFunction* miss_handler() const { return miss_handler_function_; }
|
||||
void InitMissHandler();
|
||||
|
||||
static void PrintSizes(Isolate* isolate);
|
||||
RawMegamorphicCache* Lookup(const String& name, const Array& descriptor);
|
||||
|
||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||
|
||||
void PrintSizes();
|
||||
|
||||
private:
|
||||
enum {
|
||||
kEntryNameOffset = 0,
|
||||
kEntryDescriptorOffset,
|
||||
kEntryCacheOffset,
|
||||
kEntrySize
|
||||
struct Entry {
|
||||
RawString* name;
|
||||
RawArray* descriptor;
|
||||
RawMegamorphicCache* cache;
|
||||
};
|
||||
|
||||
static const int kCapacityIncrement = 128;
|
||||
|
||||
RawFunction* miss_handler_function_;
|
||||
RawCode* miss_handler_code_;
|
||||
intptr_t capacity_;
|
||||
intptr_t length_;
|
||||
Entry* table_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MegamorphicCacheTable);
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -13795,8 +13795,9 @@ RawMegamorphicCache* MegamorphicCache::New() {
|
|||
const intptr_t capacity = kInitialCapacity;
|
||||
const Array& buckets = Array::Handle(
|
||||
Array::New(kEntryLength * capacity, Heap::kOld));
|
||||
ASSERT(Isolate::Current()->megamorphic_cache_table()->miss_handler() != NULL);
|
||||
const Function& handler = Function::Handle(
|
||||
MegamorphicCacheTable::miss_handler(Isolate::Current()));
|
||||
Isolate::Current()->megamorphic_cache_table()->miss_handler());
|
||||
for (intptr_t i = 0; i < capacity; ++i) {
|
||||
SetEntry(buckets, i, smi_illegal_cid(), handler);
|
||||
}
|
||||
|
@ -13817,7 +13818,7 @@ void MegamorphicCache::EnsureCapacity() const {
|
|||
Array::Handle(Array::New(kEntryLength * new_capacity));
|
||||
|
||||
Function& target = Function::Handle(
|
||||
MegamorphicCacheTable::miss_handler(Isolate::Current()));
|
||||
Isolate::Current()->megamorphic_cache_table()->miss_handler());
|
||||
for (intptr_t i = 0; i < new_capacity; ++i) {
|
||||
SetEntry(new_buckets, i, smi_illegal_cid(), target);
|
||||
}
|
||||
|
|
|
@ -88,9 +88,7 @@ ObjectStore::ObjectStore()
|
|||
empty_uint32_array_(TypedData::null()),
|
||||
handle_message_function_(Function::null()),
|
||||
library_load_error_table_(Array::null()),
|
||||
compile_time_constants_(Array::null()),
|
||||
megamorphic_cache_table_(GrowableObjectArray::null()),
|
||||
megamorphic_miss_handler_(Function::null()) {
|
||||
compile_time_constants_(Array::null()) {
|
||||
for (RawObject** current = from(); current <= to(); current++) {
|
||||
ASSERT(*current == Object::null());
|
||||
}
|
||||
|
|
|
@ -433,19 +433,6 @@ class ObjectStore {
|
|||
compile_time_constants_ = value.raw();
|
||||
}
|
||||
|
||||
RawGrowableObjectArray* megamorphic_cache_table() const {
|
||||
return megamorphic_cache_table_;
|
||||
}
|
||||
void set_megamorphic_cache_table(const GrowableObjectArray& value) {
|
||||
megamorphic_cache_table_ = value.raw();
|
||||
}
|
||||
RawFunction* megamorphic_miss_handler() const {
|
||||
return megamorphic_miss_handler_;
|
||||
}
|
||||
void set_megamorphic_miss_handler(const Function& value) {
|
||||
megamorphic_miss_handler_ = value.raw();
|
||||
}
|
||||
|
||||
// Visit all object pointers.
|
||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||
|
||||
|
@ -536,10 +523,8 @@ class ObjectStore {
|
|||
RawFunction* handle_message_function_;
|
||||
RawArray* library_load_error_table_;
|
||||
RawArray* compile_time_constants_;
|
||||
RawGrowableObjectArray* megamorphic_cache_table_;
|
||||
RawFunction* megamorphic_miss_handler_;
|
||||
RawObject** to() {
|
||||
return reinterpret_cast<RawObject**>(&megamorphic_miss_handler_);
|
||||
return reinterpret_cast<RawObject**>(&compile_time_constants_);
|
||||
}
|
||||
|
||||
friend class SnapshotReader;
|
||||
|
|
Loading…
Reference in a new issue