Version 1.0.1.3 dev channel

Remerge r30576-30582 https://dart.googlecode.com/svn/branches/bleeding_edge
trunk .

SVN merge history for these files had become incorrect, so we needed to remerge
in order to get the merge history in sync with reality.

Desk reviewed with sigmund@google.com .

git-svn-id: http://dart.googlecode.com/svn/trunk@30657 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index 248c309..5a4f54f 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -83,8 +83,11 @@
   Class& direct_subclass = Class::Handle();
   for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
     direct_subclass ^= cls_direct_subclasses.At(i);
-    if (direct_subclass.LookupDynamicFunction(function_name) !=
-        Function::null()) {
+    // 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)) {
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index e0bfc6c..1b2786f 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -28,7 +28,7 @@
       "}\n";
 
   TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 5eab085..b5216dc 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -37,18 +37,18 @@
 // Only methods which owner classes where subclasses can be invalid.
 // TODO(srdjan): Be even more precise by recording the exact CHA optimization.
 static void RemoveOptimizedCode(
-    const GrowableArray<intptr_t>& added_subclasses_to_cids) {
+    const GrowableArray<intptr_t>& added_subclass_to_cids) {
   ASSERT(FLAG_use_cha);
-  if (added_subclasses_to_cids.is_empty()) return;
+  if (added_subclass_to_cids.is_empty()) return;
   // Deoptimize all live frames.
-  DeoptimizeIfOwner(added_subclasses_to_cids);
+  DeoptimizeIfOwner(added_subclass_to_cids);
   // Switch all functions' code to unoptimized.
   const ClassTable& class_table = *Isolate::Current()->class_table();
   Class& cls = Class::Handle();
   Array& array = Array::Handle();
   Function& function = Function::Handle();
-  for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) {
-    intptr_t cid = added_subclasses_to_cids[i];
+  for (intptr_t i = 0; i < added_subclass_to_cids.length(); i++) {
+    intptr_t cid = added_subclass_to_cids[i];
     cls = class_table.At(cid);
     ASSERT(!cls.IsNull());
     array = cls.functions();
@@ -89,30 +89,25 @@
 // Use array instead of set since we expect very few subclassed classes
 // to occur.
 static void CollectFinalizedSuperClasses(
-    const GrowableObjectArray& pending_classes,
-    GrowableArray<intptr_t>* finalized_super_classes) {
-  Class& cls = Class::Handle();
+    const Class& cls_, GrowableArray<intptr_t>* finalized_super_classes) {
+  Class& cls = Class::Handle(cls_.raw());
   AbstractType& super_type = Type::Handle();
-  for (intptr_t i = 0; i < pending_classes.Length(); i++) {
-    cls ^= pending_classes.At(i);
-    ASSERT(!cls.is_finalized());
-    super_type = cls.super_type();
-    if (!super_type.IsNull()) {
-      if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) {
-        cls ^= super_type.type_class();
-        if (cls.is_finalized()) {
-          AddSuperType(super_type, finalized_super_classes);
-        }
+  super_type = cls.super_type();
+  if (!super_type.IsNull()) {
+    if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) {
+      cls ^= super_type.type_class();
+      if (cls.is_finalized()) {
+        AddSuperType(super_type, finalized_super_classes);
       }
     }
   }
 }
 
 
-// Class finalization occurs:
+// Type hierarchy finalization occurs:
 // a) when bootstrap process completes (VerifyBootstrapClasses).
 // b) after the user classes are loaded (dart_api).
-bool ClassFinalizer::FinalizePendingClasses() {
+bool ClassFinalizer::FinalizeTypeHierarchy() {
   bool retval = true;
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
@@ -126,7 +121,6 @@
     return true;
   }
 
-  GrowableArray<intptr_t> added_subclasses_to_cids;
   LongJump* base = isolate->long_jump_base();
   LongJump jump;
   isolate->set_long_jump_base(&jump);
@@ -134,9 +128,6 @@
     GrowableObjectArray& class_array = GrowableObjectArray::Handle();
     class_array = object_store->pending_classes();
     ASSERT(!class_array.IsNull());
-    // Collect superclasses that were already finalized before this run of
-    // finalization.
-    CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids);
     Class& cls = Class::Handle();
     // First resolve all superclasses.
     for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -163,9 +154,6 @@
     retval = false;
   }
   isolate->set_long_jump_base(base);
-  if (FLAG_use_cha) {
-    RemoveOptimizedCode(added_subclasses_to_cids);
-  }
   return retval;
 }
 
@@ -237,8 +225,9 @@
     }
   }
 
-  // Finalize classes that aren't pre-finalized by Object::Init().
-  if (!FinalizePendingClasses()) {
+  // Finalize type hierarchy for types that aren't pre-finalized
+  // by Object::Init().
+  if (!FinalizeTypeHierarchy()) {
     // 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",
@@ -2055,6 +2044,8 @@
     // the class conflict with inherited methods.
     ApplyMixinMembers(cls);
   }
+  GrowableArray<intptr_t> added_subclass_to_cids;
+  CollectFinalizedSuperClasses(cls, &added_subclass_to_cids);
   // Ensure super class is finalized.
   const Class& super = Class::Handle(cls.SuperClass());
   if (!super.IsNull()) {
@@ -2082,6 +2073,9 @@
   if (cls.is_const()) {
     CheckForLegalConstClass(cls);
   }
+  if (FLAG_use_cha) {
+    RemoveOptimizedCode(added_subclass_to_cids);
+  }
 }
 
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index a61ba36..25d4861 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -78,11 +78,11 @@
   // Return false if we still have classes pending to be finalized.
   static bool AllClassesFinalized();
 
-  // Return whether class finalization failed.
+  // Return whether type hierarchy finalization failed.
   // The function returns true if the finalization was successful.
   // If finalization fails, an error message is set in the sticky error field
   // in the object store.
-  static bool FinalizePendingClasses();
+  static bool FinalizeTypeHierarchy();
 
   // Finalize the types appearing in the declaration of class 'cls', i.e. its
   // type parameters and their upper bounds, its super type and interfaces.
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index b073dd9..1f55b0f 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -40,7 +40,7 @@
   pending_classes.Add(*classes_2[1]);
   classes_2.Add(&Class::ZoneHandle(CreateTestClass("Alfa")));
   pending_classes.Add(*classes_2[2]);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   for (int i = 0; i < classes_1.length(); i++) {
     EXPECT(classes_1[i]->is_type_finalized());
   }
@@ -48,7 +48,7 @@
     EXPECT(classes_2[i]->is_type_finalized());
   }
   EXPECT(ClassFinalizer::AllClassesFinalized());
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
 }
 
 
@@ -67,7 +67,7 @@
       Type::Handle(Type::NewNonParameterizedType(*classes[1])));
   classes[1]->set_super_type(
       Type::Handle(Type::NewNonParameterizedType(*classes[0])));
-  EXPECT(!ClassFinalizer::FinalizePendingClasses());
+  EXPECT(!ClassFinalizer::FinalizeTypeHierarchy());
 }
 
 
@@ -99,7 +99,7 @@
       Type::New(Object::Handle(unresolved.raw()),
                 type_arguments,
                 Scanner::kDummyTokenIndex)));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
 }
 
 }  // namespace dart
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 8d33ebd..3d87602 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -219,7 +219,7 @@
       "}\n";
   // First setup the script and compile the script.
   TestCase::LoadTestScript(kScriptChars, native_resolver);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 5ecb9c5..686ddd1 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1536,6 +1536,7 @@
         DeoptimizeAt(optimized_code, frame->pc());
       }
     }
+    frame = iterator.NextFrame();
   }
 }
 
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index 34ac993..c7e7cdb 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -293,7 +293,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::Handle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
@@ -340,7 +340,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
@@ -532,7 +532,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 08e2285..e7c4820 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -42,7 +42,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 0435718..19d01a2 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -160,7 +160,7 @@
     // Class finalization is blocked for the isolate. Do nothing.
     return Api::Success();
   }
-  if (ClassFinalizer::FinalizePendingClasses()) {
+  if (ClassFinalizer::FinalizeTypeHierarchy()) {
     return Api::Success();
   }
   ASSERT(isolate->object_store()->sticky_error() != Object::null());
diff --git a/runtime/vm/dart_entry_test.cc b/runtime/vm/dart_entry_test.cc
index fa8cc81..576d6f3 100644
--- a/runtime/vm/dart_entry_test.cc
+++ b/runtime/vm/dart_entry_test.cc
@@ -26,7 +26,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -54,7 +54,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -81,7 +81,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index 3daccd8..599b8c9 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -55,7 +55,7 @@
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsA = lib.LookupClass(String::Handle(Symbols::New("A")));
   EXPECT(!clsA.IsNull());
-  ClassFinalizer::FinalizePendingClasses();
+  ClassFinalizer::FinalizeTypeHierarchy();
   for (int i = 0; i < kNumFunctions; i++) {
     OS::SNPrint(buffer, 256, "foo%d", i);
     function_name = String::New(buffer);
@@ -103,7 +103,7 @@
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsB = lib.LookupClass(String::Handle(Symbols::New("B")));
   EXPECT(!clsB.IsNull());
-  ClassFinalizer::FinalizePendingClasses();
+  ClassFinalizer::FinalizeTypeHierarchy();
   for (int i = 0; i < kNumFunctions; i++) {
     OS::SNPrint(buffer, 256, "moo%d", i);
     function_name = String::New(buffer);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 82a444c..c3e92fa 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -529,7 +529,7 @@
     StartIsolateScope start_scope(isolate);
     StackZone zone(isolate);
     HandleScope handle_scope(isolate);
-    if (!ClassFinalizer::FinalizePendingClasses()) {
+    if (!ClassFinalizer::FinalizeTypeHierarchy()) {
       // Error is in sticky error already.
       return false;
     }
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 23cc6bd..921976a 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3518,7 +3518,7 @@
       "  }\n"
       "}";
   TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index 2e4c4b7..567ea81 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -123,7 +123,7 @@
   script.Tokenize(String::Handle(String::New("")));
 
   Parser::ParseCompilationUnit(lib, script);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
   CheckField(lib, "A", "f1", false, false);
   CheckField(lib, "A", "f2", false, true);
   CheckField(lib, "A", "f3", false, true);
@@ -158,7 +158,7 @@
   script.Tokenize(String::Handle(String::New("")));
 
   Parser::ParseCompilationUnit(lib, script);
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
 
   DumpFunction(lib, "A", "foo");
   DumpFunction(lib, "A", "bar");
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 22c4dd5..c2997a6 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -46,7 +46,7 @@
   Library& lib = Library::Handle(Library::New(lib_name));
   lib.Register();
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizePendingClasses());
+  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
 }
 
 
diff --git a/tools/VERSION b/tools/VERSION
index 2225f83..5e01d86 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -2,4 +2,4 @@
 MAJOR 1
 MINOR 0
 BUILD 1
-PATCH 2
+PATCH 3