e83151cc77
in these blocks will not have a safepoint operation - changed boxed_field_list_monitor_ to boxed_field_list_mutex_ as we only need a mutex for guarding access to boxed_field_list_ as changed the lock to use SafepointMutexLocker as the list addition code could potentially allocate and result in GC (safepoint operation) - Added a SafepointMonitorLocker as we have a function Isolate::VisitIsolates which could potentially have safepoints in the enclosed block. - Make the lock around MegamorphicCacheTable::Lookup a SafepointMutexLocker as the look up code seems to be allocating memory while the lock is held. - Changed the ThreadPool and MessageHandler code to account for the new MonitorLocker usage standard - Fixed PortMap::PrintPortsForMessageHandler to use SafepointMutexLocker as the code it encloses calls into Dart - Removed profiler_ field in class Profiler as it doesn't seem to be used. R=johnmccutchan@google.com, srdjan@google.com Review URL: https://codereview.chromium.org/1748953003 .
103 lines
3.9 KiB
C++
103 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/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) {
|
|
// Multiple compilation threads could access this lookup.
|
|
SafepointMutexLocker ml(isolate->mutex());
|
|
ASSERT(name.IsSymbol());
|
|
// TODO(rmacnak): ASSERT(descriptor.IsCanonical());
|
|
|
|
// TODO(rmacnak): Make a proper hashtable a la symbol table.
|
|
GrowableObjectArray& table = GrowableObjectArray::Handle(
|
|
isolate->object_store()->megamorphic_cache_table());
|
|
MegamorphicCache& cache = MegamorphicCache::Handle();
|
|
if (table.IsNull()) {
|
|
table = GrowableObjectArray::New(Heap::kOld);
|
|
isolate->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.raw()) &&
|
|
(cache.arguments_descriptor() == descriptor.raw())) {
|
|
return cache.raw();
|
|
}
|
|
}
|
|
}
|
|
|
|
cache = MegamorphicCache::New(name, descriptor);
|
|
table.Add(cache, Heap::kOld);
|
|
return cache.raw();
|
|
}
|
|
|
|
|
|
RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) {
|
|
ASSERT(isolate->object_store()->megamorphic_miss_function() !=
|
|
Function::null());
|
|
return isolate->object_store()->megamorphic_miss_function();
|
|
}
|
|
|
|
|
|
void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) {
|
|
// The miss handler for a class ID not found in the table is invoked as a
|
|
// normal Dart function.
|
|
const Code& code =
|
|
Code::Handle(StubCode::Generate("_stub_MegamorphicMiss",
|
|
StubCode::GenerateMegamorphicMissStub));
|
|
// When FLAG_lazy_dispatchers=false, this stub can be on the stack during
|
|
// exceptions, but it has a corresponding function so IsStubCode is false and
|
|
// it is considered in the search for an exception handler.
|
|
code.set_exception_handlers(Object::empty_exception_handlers());
|
|
const Class& cls =
|
|
Class::Handle(Type::Handle(Type::Function()).type_class());
|
|
const Function& function =
|
|
Function::Handle(Function::New(Symbols::MegamorphicMiss(),
|
|
RawFunction::kRegularFunction,
|
|
false, // Not static.
|
|
false, // Not const.
|
|
false, // Not abstract.
|
|
false, // Not external.
|
|
false, // Not native.
|
|
cls,
|
|
TokenPosition::kNoSource));
|
|
function.set_result_type(Type::Handle(Type::DynamicType()));
|
|
function.set_is_debuggable(false);
|
|
function.set_is_visible(false);
|
|
function.AttachCode(code);
|
|
|
|
isolate->object_store()->SetMegamorphicMissHandler(code, function);
|
|
}
|
|
|
|
|
|
void MegamorphicCacheTable::PrintSizes(Isolate* isolate) {
|
|
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());
|
|
if (table.IsNull()) return;
|
|
for (intptr_t i = 0; i < table.Length(); i++) {
|
|
cache ^= table.At(i);
|
|
buckets = cache.buckets();
|
|
size += MegamorphicCache::InstanceSize();
|
|
size += Array::InstanceSize(buckets.Length());
|
|
}
|
|
OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
|
|
table.Length(), size / 1024);
|
|
}
|
|
|
|
} // namespace dart
|