| // 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. | |
| #ifndef RUNTIME_VM_CLASS_FINALIZER_H_ | |
| #define RUNTIME_VM_CLASS_FINALIZER_H_ | |
| #include <memory> | |
| #include "vm/allocation.h" | |
| #include "vm/growable_array.h" | |
| #include "vm/object.h" | |
| namespace dart { | |
| // Traverses all pending, unfinalized classes, validates and marks them as | |
| // finalized. | |
| class ClassFinalizer : public AllStatic { | |
| public: | |
| // Modes for finalization. The ordering is relevant. | |
| enum FinalizationKind { | |
| kFinalize, // Finalize type and type arguments. | |
| kCanonicalize // Finalize and canonicalize. | |
| }; | |
| // Finalize given type. | |
| static AbstractTypePtr FinalizeType( | |
| const AbstractType& type, | |
| FinalizationKind finalization = kCanonicalize); | |
| // Return false if we still have classes pending to be finalized. | |
| static bool AllClassesFinalized(); | |
| #if !defined(DART_PRECOMPILED_RUNTIME) | |
| // Useful for sorting classes to make dispatch faster. | |
| static void SortClasses(); | |
| static void RemapClassIds(intptr_t* old_to_new_cid); | |
| static void RehashTypes(); | |
| static void ClearAllCode(bool including_nonchanging_cids = false); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| // Return whether processing pending classes (ObjectStore::pending_classes_) | |
| // failed. The function returns true if the processing was successful. | |
| // If processing fails, an error message is set in the sticky error field | |
| // in the object store. | |
| static bool ProcessPendingClasses(); | |
| // Finalize the types appearing in the declaration of class 'cls', i.e. its | |
| // type parameters and their upper bounds, its super type and interfaces. | |
| // Note that the fields and functions have not been parsed yet (unless cls | |
| // is an anonymous top level class). | |
| static void FinalizeTypesInClass(const Class& cls); | |
| #if !defined(DART_PRECOMPILED_RUNTIME) | |
| // Mark [cls], its superclass and superinterfaces as can_be_future(). | |
| static void MarkClassCanBeFuture(Zone* zone, const Class& cls); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| // Ensures members of the class are loaded, class layout is finalized and size | |
| // registered in class table. | |
| static void FinalizeClass(const Class& cls); | |
| #if !defined(DART_PRECOMPILED_RUNTIME) | |
| // Makes class instantiatable and usable by generated code. | |
| static ErrorPtr AllocateFinalizeClass(const Class& cls); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| #if !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES) | |
| // Completes loading of the class, this populates the function | |
| // and fields of the class. | |
| // | |
| // Returns Error::null() if there is no loading error. | |
| static ErrorPtr LoadClassMembers(const Class& cls); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES) | |
| #if !defined(DART_PRECOMPILED_RUNTIME) | |
| // Verify that the classes have been properly prefinalized. This is | |
| // needed during bootstrapping where the classes have been preloaded. | |
| static void VerifyBootstrapClasses(); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| private: | |
| // Finalize given type argument vector. | |
| static TypeArgumentsPtr FinalizeTypeArguments( | |
| Zone* zone, | |
| const TypeArguments& type_args, | |
| FinalizationKind finalization = kCanonicalize); | |
| static void FinalizeTypeParameters(Zone* zone, | |
| const TypeParameters& type_params, | |
| FinalizationKind finalization); | |
| #if !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES) | |
| static void FinalizeMemberTypes(const Class& cls); | |
| #if !defined(PRODUCT) | |
| static void PrintClassInformation(const Class& cls); | |
| #endif | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| #if !defined(DART_PRECOMPILED_RUNTIME) | |
| // Verify implicit offsets recorded in the VM for direct access to fields of | |
| // Dart instances (e.g: _TypedListView, _ByteDataView). | |
| static void VerifyImplicitFieldOffsets(); | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) | |
| }; | |
| class ClassHiearchyUpdater : public ValueObject { | |
| public: | |
| explicit ClassHiearchyUpdater(Zone* zone) : zone_(zone) {} | |
| // Register class in the lists of direct subclasses and direct implementors. | |
| void Register(const Class& cls); | |
| private: | |
| void MarkImplemented(const Class& interface); | |
| Zone* const zone_; | |
| AbstractType& type_ = AbstractType::Handle(zone_); | |
| Class& super_ = Class::Handle(zone_); | |
| Class& implemented_ = Class::Handle(zone_); | |
| Class& interface_ = Class::Handle(zone_); | |
| Array& interfaces_ = Array::Handle(zone_); | |
| class ClassWorklist { | |
| public: | |
| explicit ClassWorklist(Zone* zone) : zone_(zone) {} | |
| bool IsEmpty() const { return size_ == 0; } | |
| void Add(const Class& cls) { | |
| if (worklist_.length() == size_) { | |
| worklist_.Add(&Class::Handle(zone_)); | |
| } | |
| *worklist_[size_] = cls.ptr(); | |
| size_++; | |
| } | |
| ClassPtr RemoveLast() { | |
| size_--; | |
| return worklist_[size_]->ptr(); | |
| } | |
| private: | |
| Zone* const zone_; | |
| GrowableArray<Class*> worklist_; | |
| intptr_t size_ = 0; | |
| }; | |
| ClassWorklist worklist_{zone_}; | |
| }; | |
| } // namespace dart | |
| #endif // RUNTIME_VM_CLASS_FINALIZER_H_ |