Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Unified Diff: runtime/vm/class_finalizer.cc

Issue 10871005: Make ClassFinalizer indifferent on whether we are generating a snapshot or not. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 11113)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -17,8 +17,6 @@
DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
-DEFINE_FLAG(bool, verify_implements, false,
- "Verify that all classes implement their interface.");
DECLARE_FLAG(bool, enable_type_checks);
@@ -30,10 +28,16 @@
}
+bool ClassFinalizer::FinalizeAllClasses() {
+ ClassFinalizer class_finalizer(kNotGeneratingSnapshot);
+ return class_finalizer.FinalizePendingClasses();
+}
+
+
// Class finalization occurs:
// a) when bootstrap process completes (VerifyBootstrapClasses).
// b) after the user classes are loaded (dart_api).
-bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) {
+bool ClassFinalizer::FinalizePendingClasses() const {
bool retval = true;
Isolate* isolate = Isolate::Current();
ASSERT(isolate != NULL);
@@ -64,7 +68,7 @@
// Finalize all classes.
for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
- FinalizeClass(cls, generating_snapshot);
+ FinalizeClass(cls);
}
if (FLAG_print_classes) {
for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -72,14 +76,6 @@
PrintClassInformation(cls);
}
}
- if (FLAG_verify_implements) {
- for (intptr_t i = 0; i < class_array.Length(); i++) {
- cls ^= class_array.At(i);
- if (!cls.is_interface()) {
- VerifyClassImplements(cls);
- }
- }
- }
// Clear pending classes array.
class_array = GrowableObjectArray::New();
object_store->set_pending_classes(class_array);
@@ -107,78 +103,6 @@
}
-#if defined (DEBUG)
-// Collect all interfaces of the class 'cls' and check that every function
-// defined in each interface can be found in the class.
-// No need to check instance fields since they have been turned into
-// getters/setters.
-void ClassFinalizer::VerifyClassImplements(const Class& cls) {
- ASSERT(!cls.is_interface());
- const GrowableObjectArray& interfaces =
- GrowableObjectArray::Handle(GrowableObjectArray::New());
- CollectInterfaces(cls, interfaces);
- const String& class_name = String::Handle(cls.Name());
- Class& interface_class = Class::Handle();
- String& interface_name = String::Handle();
- Array& interface_functions = Array::Handle();
- for (int i = 0; i < interfaces.Length(); i++) {
- interface_class ^= interfaces.At(i);
- interface_name = interface_class.Name();
- interface_functions = interface_class.functions();
- for (intptr_t f = 0; f < interface_functions.Length(); f++) {
- Function& interface_function = Function::Handle();
- interface_function ^= interface_functions.At(f);
- const String& function_name = String::Handle(interface_function.name());
- // Check for constructor/factory.
- if (function_name.StartsWith(interface_name)) {
- // TODO(srdjan): convert 'InterfaceName.' to 'ClassName.' and check.
- continue;
- }
- if (interface_function.kind() == RawFunction::kConstImplicitGetter) {
- // This interface constants are not overridable.
- continue;
- }
- // Lookup function in 'cls' and all its super classes.
- Class& test_class = Class::Handle(cls.raw());
- Function& class_function =
- Function::Handle(test_class.LookupDynamicFunction(function_name));
- while (class_function.IsNull()) {
- test_class = test_class.SuperClass();
- if (test_class.IsNull()) break;
- class_function = test_class.LookupDynamicFunction(function_name);
- }
- if (class_function.IsNull()) {
- OS::PrintErr("%s implements '%s' missing: '%s'\n",
- class_name.ToCString(),
- interface_name.ToCString(),
- function_name.ToCString());
- } else {
- Error& malformed_error = Error::Handle();
- if (!class_function.IsSubtypeOf(TypeArguments::Handle(),
- interface_function,
- TypeArguments::Handle(),
- &malformed_error)) {
- if (!malformed_error.IsNull()) {
- OS::PrintErr("%s\n", malformed_error.ToErrorCString());
- }
- OS::PrintErr("The type of instance method '%s' in class '%s' is not "
- "a subtype of the type of '%s' in interface '%s'\n",
- function_name.ToCString(),
- class_name.ToCString(),
- function_name.ToCString(),
- interface_name.ToCString());
- }
- }
- }
- }
-}
-#else
-
-void ClassFinalizer::VerifyClassImplements(const Class& cls) {}
-
-#endif
-
-
void ClassFinalizer::VerifyBootstrapClasses() {
if (FLAG_trace_class_finalization) {
OS::Print("VerifyBootstrapClasses START.\n");
@@ -273,7 +197,8 @@
}
// Finalize classes that aren't pre-finalized by Object::Init().
- if (!FinalizePendingClasses()) {
+ ClassFinalizer class_finalizer(kGeneratingSnapshot);
+ if (!class_finalizer.FinalizePendingClasses()) {
// TODO(srdjan): Exit like a real VM instead.
const Error& err = Error::Handle(object_store->sticky_error());
OS::PrintErr("Could not verify bootstrap classes : %s\n",
@@ -308,7 +233,7 @@
// Resolve unresolved supertype (String -> Class).
-void ClassFinalizer::ResolveSuperType(const Class& cls) {
+void ClassFinalizer::ResolveSuperType(const Class& cls) const {
if (cls.is_finalized()) {
return;
}
@@ -467,7 +392,7 @@
void ClassFinalizer::ResolveType(const Class& cls,
const AbstractType& type,
- FinalizationKind finalization) {
+ FinalizationKind finalization) const {
if (type.IsResolved() || type.IsFinalized()) {
return;
}
@@ -518,7 +443,7 @@
}
-void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
+void ClassFinalizer::FinalizeTypeParameters(const Class& cls) const {
const TypeArguments& type_parameters =
TypeArguments::Handle(cls.type_parameters());
if (!type_parameters.IsNull()) {
@@ -552,7 +477,7 @@
void ClassFinalizer::FinalizeTypeArguments(
const Class& cls,
const AbstractTypeArguments& arguments,
- FinalizationKind finalization) {
+ FinalizationKind finalization) const {
ASSERT(arguments.Length() >= cls.NumTypeArguments());
if (!cls.is_finalized()) {
GrowableArray<intptr_t> visited_interfaces;
@@ -606,9 +531,10 @@
}
-RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
- const AbstractType& type,
- FinalizationKind finalization) {
+RawAbstractType* ClassFinalizer::FinalizeType(
+ const Class& cls,
+ const AbstractType& type,
+ FinalizationKind finalization) const {
if (type.IsFinalized()) {
return type.raw();
}
@@ -678,7 +604,7 @@
if (type_argument.IsMalformed()) {
// In production mode, malformed type arguments are mapped to Dynamic.
// In checked mode, a type with malformed type arguments is malformed.
- if (FLAG_enable_type_checks) {
+ if (FLAG_enable_type_checks || generating_snapshot_) {
const Error& error = Error::Handle(type_argument.malformed_error());
const String& type_name =
String::Handle(parameterized_type.UserVisibleName());
@@ -813,7 +739,7 @@
} else {
// This type is a function type alias. Its class may need to be finalized
// and checked for illegal self reference.
- FinalizeClass(type_class, false);
+ FinalizeClass(type_class);
// Finalizing the signature function here (as in the canonical case above)
// would not mark the canonical signature type as finalized.
const Type& signature_type = Type::Handle(type_class.SignatureType());
@@ -829,8 +755,9 @@
}
-void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
- const Function& function) {
+void ClassFinalizer::ResolveAndFinalizeSignature(
+ const Class& cls,
+ const Function& function) const {
// Resolve result type.
AbstractType& type = AbstractType::Handle(function.result_type());
// In case of a factory, the parser sets the factory result type to a type
@@ -899,7 +826,7 @@
// Resolve and finalize the upper bounds of the type parameters of class cls.
-void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
+void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) const {
const intptr_t num_type_params = cls.NumTypeParameters();
TypeParameter& type_param = TypeParameter::Handle();
AbstractType& bound = AbstractType::Handle();
@@ -920,7 +847,7 @@
}
-void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
+void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) const {
// Note that getters and setters are explicitly listed as such in the list of
// functions of a class, so we do not need to consider fields as implicitly
// generating getters and setters.
@@ -1079,7 +1006,7 @@
}
-void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) {
+void ClassFinalizer::FinalizeClass(const Class& cls) const {
if (cls.is_finalized()) {
return;
}
@@ -1098,7 +1025,7 @@
// Finalize super class.
const Class& super_class = Class::Handle(cls.SuperClass());
if (!super_class.IsNull()) {
- FinalizeClass(super_class, generating_snapshot);
+ FinalizeClass(super_class);
}
// Finalize type parameters before finalizing the super type.
FinalizeTypeParameters(cls);
@@ -1132,7 +1059,7 @@
if (cls.HasFactoryClass()) {
const Class& factory_class = Class::Handle(cls.FactoryClass());
if (!factory_class.is_finalized()) {
- FinalizeClass(factory_class, generating_snapshot);
+ FinalizeClass(factory_class);
// Finalizing the factory class may indirectly finalize this interface.
if (cls.is_finalized()) {
return;
@@ -1159,7 +1086,7 @@
}
// Check to ensure we don't have classes with native fields in libraries
// which do not have a native resolver.
- if (!generating_snapshot && cls.num_native_fields() != 0) {
+ if (!generating_snapshot_ && cls.num_native_fields() != 0) {
const Library& lib = Library::Handle(cls.library());
if (lib.native_entry_resolver() == NULL) {
const String& cls_name = String::Handle(cls.Name());
@@ -1204,7 +1131,7 @@
// Returns false if the function type alias illegally refers to itself.
bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
- GrowableArray<intptr_t>* visited) {
+ GrowableArray<intptr_t>* visited) const {
ASSERT(cls.IsSignatureClass());
ASSERT(!cls.IsCanonicalSignatureClass());
ASSERT(!cls.is_finalized());
@@ -1254,36 +1181,6 @@
}
-bool ClassFinalizer::AddInterfaceIfUnique(
- const GrowableObjectArray& interface_list,
- const AbstractType& interface,
- AbstractType* conflicting) {
- String& interface_class_name = String::Handle(interface.ClassName());
- String& existing_interface_class_name = String::Handle();
- String& interface_name = String::Handle();
- String& existing_interface_name = String::Handle();
- AbstractType& other_interface = AbstractType::Handle();
- for (intptr_t i = 0; i < interface_list.Length(); i++) {
- other_interface ^= interface_list.At(i);
- existing_interface_class_name = other_interface.ClassName();
- if (interface_class_name.Equals(existing_interface_class_name)) {
- // Same interface class name, now check names of type arguments.
- interface_name = interface.Name();
- existing_interface_name = other_interface.Name();
- // TODO(regis): Revisit depending on the outcome of issue 4905685.
- if (!interface_name.Equals(existing_interface_name)) {
- *conflicting = other_interface.raw();
- return false;
- } else {
- return true;
- }
- }
- }
- interface_list.Add(interface);
- return true;
-}
-
-
// Walks the graph of explicitly declared interfaces of classes and
// interfaces recursively. Resolves unresolved interfaces.
// Returns false if there is an interface reference that cannot be
@@ -1292,7 +1189,7 @@
// graph. If we visit an interface a second time on a given path,
// we found a loop.
void ClassFinalizer::ResolveInterfaces(const Class& cls,
- GrowableArray<intptr_t>* visited) {
+ GrowableArray<intptr_t>* visited) const {
ASSERT(visited != NULL);
const intptr_t cls_index = cls.id();
for (int i = 0; i < visited->length(); i++) {
@@ -1448,13 +1345,14 @@
const Class& cls,
const Type& type,
FinalizationKind finalization,
- const char* format, ...) {
+ const char* format, ...) const {
va_list args;
va_start(args, format);
LanguageError& error = LanguageError::Handle();
if (FLAG_enable_type_checks ||
!type.HasResolvedTypeClass() ||
- (finalization == kCanonicalizeWellFormed)) {
+ (finalization == kCanonicalizeWellFormed) ||
+ generating_snapshot_) {
const Script& script = Script::Handle(cls.script());
if (prev_error.IsNull()) {
error ^= Parser::FormatError(
@@ -1463,7 +1361,7 @@
error ^= Parser::FormatErrorWithAppend(
prev_error, script, type.token_pos(), "Error", format, args);
}
- if (finalization == kCanonicalizeWellFormed) {
+ if ((finalization == kCanonicalizeWellFormed) || generating_snapshot_) {
ReportError(error);
}
}

Powered by Google App Engine
This is Rietveld 408576698