eeeda72067
I ran into issues with the collections library where classes and types were being finalized very late, affecting cha analysis.
class _LinkedCustomHashMap<K, V> extends _CustomHashMap<K, V> with _LinkedHashMapMixin<K, V>
abstract class _LinkedHashMapMixin<K, V> implements LinkedHashMap<K, V> {
Even though LinkedHashMap is a builtin object it can still be implemented after startup.
R=fschneider@google.com, iposva@google.com
Review URL: https://codereview.chromium.org//846213004
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42874 260f80e4-7a28-3924-810f-c04153c831b5
105 lines
3.0 KiB
C++
105 lines
3.0 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/cha.h"
|
|
#include "vm/class_table.h"
|
|
#include "vm/flags.h"
|
|
#include "vm/freelist.h"
|
|
#include "vm/object.h"
|
|
#include "vm/raw_object.h"
|
|
#include "vm/visitor.h"
|
|
|
|
namespace dart {
|
|
|
|
void CHA::AddToLeafClasses(const Class& cls) {
|
|
for (intptr_t i = 0; i < leaf_classes_.length(); i++) {
|
|
if (leaf_classes_[i]->raw() == cls.raw()) {
|
|
return;
|
|
}
|
|
}
|
|
leaf_classes_.Add(&Class::ZoneHandle(isolate_, cls.raw()));
|
|
}
|
|
|
|
|
|
bool CHA::HasSubclasses(const Class& cls) {
|
|
ASSERT(!cls.IsNull());
|
|
ASSERT(cls.id() >= kInstanceCid);
|
|
// Can't track dependencies for classes on the VM heap since those are
|
|
// read-only.
|
|
// TODO(fschneider): Enable tracking of CHA dependent code for VM heap
|
|
// classes.
|
|
if (cls.InVMHeap()) return true;
|
|
|
|
if (cls.IsObjectClass()) {
|
|
// Class Object has subclasses, although we do not keep track of them.
|
|
return true;
|
|
}
|
|
const GrowableObjectArray& direct_subclasses =
|
|
GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
|
|
bool result =
|
|
!direct_subclasses.IsNull() && (direct_subclasses.Length() > 0);
|
|
if (!result) {
|
|
AddToLeafClasses(cls);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
bool CHA::HasSubclasses(intptr_t cid) {
|
|
const ClassTable& class_table = *isolate_->class_table();
|
|
Class& cls = Class::Handle(isolate_, class_table.At(cid));
|
|
return HasSubclasses(cls);
|
|
}
|
|
|
|
|
|
bool CHA::IsImplemented(const Class& cls) {
|
|
// Signature classes have different type checking rules.
|
|
ASSERT(!cls.IsSignatureClass());
|
|
// Can't track dependencies for classes on the VM heap since those are
|
|
// read-only.
|
|
// TODO(fschneider): Enable tracking of CHA dependent code for VM heap
|
|
// classes.
|
|
if (cls.InVMHeap()) return true;
|
|
|
|
bool result = cls.is_implemented();
|
|
if (!result) {
|
|
AddToLeafClasses(cls);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
bool CHA::HasOverride(const Class& cls, const String& function_name) {
|
|
const GrowableObjectArray& cls_direct_subclasses =
|
|
GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
|
|
// Subclasses of Object are not tracked by CHA. Safely assume that overrides
|
|
// exist.
|
|
if (cls.IsObjectClass()) {
|
|
return true;
|
|
}
|
|
|
|
if (cls_direct_subclasses.IsNull()) {
|
|
AddToLeafClasses(cls);
|
|
return false;
|
|
}
|
|
Class& direct_subclass = Class::Handle(isolate_);
|
|
for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
|
|
direct_subclass ^= cls_direct_subclasses.At(i);
|
|
// Unfinalized classes are treated as non-existent for CHA purposes,
|
|
// as that means that no instance of that class exists at runtime.
|
|
if (direct_subclass.is_finalized() &&
|
|
(direct_subclass.LookupDynamicFunction(function_name) !=
|
|
Function::null())) {
|
|
return true;
|
|
}
|
|
if (HasOverride(direct_subclass, function_name)) {
|
|
return true;
|
|
}
|
|
}
|
|
AddToLeafClasses(cls);
|
|
return false;
|
|
}
|
|
|
|
} // namespace dart
|