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