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

Unified Diff: runtime/vm/compiler.cc

Issue 14820028: Delay Class parsing until the class is actually used. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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/compiler.cc
===================================================================
--- runtime/vm/compiler.cc (revision 23046)
+++ runtime/vm/compiler.cc (working copy)
@@ -99,6 +99,132 @@
}
+static void AddRelatedClassesToList(const Class& cls,
+ const GrowableObjectArray& parse_list,
+ const GrowableObjectArray& patch_list) {
+ Isolate* isolate = Isolate::Current();
+ Class& parse_class = Class::Handle(isolate);
+ Type& interface_type = Type::Handle(isolate);
+ Array& interfaces = Array::Handle(isolate);
+
+ // Add all the interfaces implemented by the class that have not been
+ // already parsed to the parse list. Mark the interface as parsed so that
+ // we don't recursively add it back into the list.
+ interfaces ^= cls.interfaces();
+ for (intptr_t i = 0; i < interfaces.Length(); i++) {
+ interface_type ^= interfaces.At(i);
+ parse_class ^= interface_type.type_class();
+ if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
+ parse_list.Add(parse_class);
+ parse_class.set_is_marked_for_parsing();
+ }
+ }
+
+ // Walk up the super_class chain and add these classes to the list if they
+ // have not been already parsed to the parse list. Mark the class as parsed
+ // so that we don't recursively add it back into the list.
+ parse_class ^= cls.SuperClass();
+ while (!parse_class.IsNull()) {
+ if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
+ parse_list.Add(parse_class);
+ parse_class.set_is_marked_for_parsing();
+ }
+ parse_class ^= parse_class.SuperClass();
+ }
+
+ // Add patch classes if they exist to the parse list if they have not already
+ // been parsed and patched. Mark the class as parsed so that we don't
+ // recursively add it back into the list.
+ const GrowableObjectArray& patch_class_array =
+ GrowableObjectArray::Handle(cls.patch_classes());
+ if (!patch_class_array.IsNull()) {
+ for (intptr_t i = 0; i < patch_class_array.Length(); i++) {
+ parse_class ^= patch_class_array.At(i);
+ ASSERT(!parse_class.IsNull());
+ if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
+ patch_list.Add(parse_class);
+ parse_class.set_is_marked_for_parsing();
+ }
+ }
+ }
+}
+
+
+RawError* Compiler::CompileClass(const Class& cls) {
+ // If class is a top level class it is already parsed.
+ if (cls.IsTopLevel()) {
+ return Error::null();
+ }
+ // If the class is already marked for parsing return immediately.
+ if (cls.is_marked_for_parsing()) {
+ return Error::null();
+ }
+ // Parse the class and all the interfaces it implements and super classes.
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ if (FLAG_trace_compiler) {
+ OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString());
+ }
+
+ Class& parse_class = Class::Handle();
+ const GrowableObjectArray& parse_list =
+ GrowableObjectArray::Handle(GrowableObjectArray::New(4));
+ const GrowableObjectArray& patch_list =
+ GrowableObjectArray::Handle(GrowableObjectArray::New(4));
+
+ // Add the primary class which needs to be parsed to the parse list.
+ // Mark the class as parsed so that we don't recursively add the same
+ // class back into the list.
+ parse_list.Add(cls);
+ cls.set_is_marked_for_parsing();
+
+ // Add all super classes, interface classes and patch class if one
+ // exists to the corresponding lists.
+ for (intptr_t i = 0; i < parse_list.Length(); i++) {
Ivan Posva 2013/05/23 05:10:37 This is a very unusual way to do fix-point iterati
siva 2013/05/23 20:19:46 Added a comment with an uppercase NOTE to make sur
+ parse_class ^= parse_list.At(i);
+ AddRelatedClassesToList(parse_class, parse_list, patch_list);
+ }
+
+ // Parse all the classes that have been added above.
+ for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) {
+ parse_class ^= parse_list.At(i);
+ ASSERT(!parse_class.IsNull());
+ Parser::ParseClass(parse_class);
+ }
+
+ // Parse all the patch classes that have been added above.
+ for (intptr_t i = 0; i < patch_list.Length(); i++) {
+ parse_class ^= patch_list.At(i);
+ ASSERT(!parse_class.IsNull());
+ Parser::ParseClass(parse_class);
+ }
+
+ // Finalize these classes.
+ for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) {
+ parse_class ^= parse_list.At(i);
+ ASSERT(!parse_class.IsNull());
+ ClassFinalizer::FinalizeClass(parse_class);
+ parse_class.reset_is_marked_for_parsing();
+ }
+
+ isolate->set_long_jump_base(base);
+ return Error::null();
+ } else {
+ Error& error = Error::Handle();
+ error = isolate->object_store()->sticky_error();
+ isolate->object_store()->clear_sticky_error();
+ isolate->set_long_jump_base(base);
+ return error.raw();
+ }
+ UNREACHABLE();
+ return Error::null();
+}
+
+
static void InstallUnoptimizedCode(const Function& function) {
// Disable optimized code.
ASSERT(function.HasOptimizedCode());

Powered by Google App Engine
This is Rietveld 408576698