| Index: runtime/vm/object.cc | 
| =================================================================== | 
| --- runtime/vm/object.cc	(revision 40420) | 
| +++ runtime/vm/object.cc	(working copy) | 
| @@ -8745,19 +8745,46 @@ | 
| } | 
|  | 
|  | 
| +// Traits for looking up Libraries by url in a hash set. | 
| +class LibraryUrlTraits { | 
| + public: | 
| +  // Called when growing the table. | 
| +  static bool IsMatch(const Object& a, const Object& b) { | 
| +    ASSERT(a.IsLibrary() && b.IsLibrary()); | 
| +    // Library objects are always canonical. | 
| +    return a.raw() == b.raw(); | 
| +  } | 
| +  static uword Hash(const Object& key) { | 
| +    return Library::Cast(key).UrlHash(); | 
| +  } | 
| +}; | 
| + | 
| + | 
| +typedef UnorderedHashSet<LibraryUrlTraits> LibraryLoadErrorSet; | 
| + | 
| + | 
| RawInstance* Library::TransitiveLoadError() const { | 
| if (LoadError() != Instance::null()) { | 
| return LoadError(); | 
| } | 
| +  Isolate* isolate = Isolate::Current(); | 
| +  ObjectStore* object_store = isolate->object_store(); | 
| +  LibraryLoadErrorSet set(object_store->library_load_error_table()); | 
| +  bool present = false; | 
| +  if (set.GetOrNull(*this, &present) != Object::null()) { | 
| +    object_store->set_library_load_error_table(set.Release()); | 
| +    return Instance::null(); | 
| +  } | 
| +  // Ensure we don't repeatedly visit the same library again. | 
| +  set.Insert(*this); | 
| +  object_store->set_library_load_error_table(set.Release()); | 
| intptr_t num_imp = num_imports(); | 
| -  Library& lib = Library::Handle(); | 
| -  Instance& error = Instance::Handle(); | 
| +  Library& lib = Library::Handle(isolate); | 
| +  Instance& error = Instance::Handle(isolate); | 
| for (intptr_t i = 0; i < num_imp; i++) { | 
| +    HANDLESCOPE(isolate); | 
| lib = ImportLibraryAt(i); | 
| -    // Break potential import cycles while recursing through imports. | 
| -    set_num_imports(0); | 
| error = lib.TransitiveLoadError(); | 
| -    set_num_imports(num_imp); | 
| if (!error.IsNull()) { | 
| break; | 
| } | 
| @@ -9941,17 +9968,26 @@ | 
|  | 
|  | 
| RawInstance* LibraryPrefix::LoadError() const { | 
| -  Library& lib = Library::Handle(); | 
| -  Instance& error = Instance::Handle(); | 
| +  Isolate* isolate = Isolate::Current(); | 
| +  ObjectStore* object_store = isolate->object_store(); | 
| +  GrowableObjectArray& libs = | 
| +      GrowableObjectArray::Handle(isolate, object_store->libraries()); | 
| +  ASSERT(!libs.IsNull()); | 
| +  LibraryLoadErrorSet set(HashTables::New<LibraryLoadErrorSet>(libs.Length())); | 
| +  object_store->set_library_load_error_table(set.Release()); | 
| +  Library& lib = Library::Handle(isolate); | 
| +  Instance& error = Instance::Handle(isolate); | 
| for (int32_t i = 0; i < num_imports(); i++) { | 
| lib = GetLibrary(i); | 
| ASSERT(!lib.IsNull()); | 
| +    HANDLESCOPE(isolate); | 
| error = lib.TransitiveLoadError(); | 
| if (!error.IsNull()) { | 
| -      return error.raw(); | 
| +      break; | 
| } | 
| } | 
| -  return Instance::null(); | 
| +  object_store->set_library_load_error_table(Object::empty_array()); | 
| +  return error.raw(); | 
| } | 
|  | 
|  | 
|  |