Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 34312) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -125,7 +125,6 @@ |
| RawClass* Object::token_stream_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::script_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::library_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| -RawClass* Object::library_prefix_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| @@ -569,9 +568,6 @@ |
| cls = Class::New<Library>(); |
| library_class_ = cls.raw(); |
| - cls = Class::New<LibraryPrefix>(); |
| - library_prefix_class_ = cls.raw(); |
| - |
| cls = Class::New<Namespace>(); |
| namespace_class_ = cls.raw(); |
| @@ -770,7 +766,6 @@ |
| SET_CLASS_NAME(token_stream, TokenStream); |
| SET_CLASS_NAME(script, Script); |
| SET_CLASS_NAME(library, LibraryClass); |
| - SET_CLASS_NAME(library_prefix, LibraryPrefix); |
| SET_CLASS_NAME(namespace, Namespace); |
| SET_CLASS_NAME(code, Code); |
| SET_CLASS_NAME(instructions, Instructions); |
| @@ -945,6 +940,9 @@ |
| cls = Class::New<MixinAppType>(); |
| object_store->set_mixin_app_type_class(cls); |
| + cls = Class::New<LibraryPrefix>(); |
| + object_store->set_library_prefix_class(cls); |
| + |
| // Pre-allocate the OneByteString class needed by the symbol table. |
| cls = Class::NewStringClass(kOneByteStringCid); |
| object_store->set_one_byte_string_class(cls); |
| @@ -1063,6 +1061,11 @@ |
| RegisterClass(cls, Symbols::Null(), core_lib); |
| pending_classes.Add(cls); |
| + cls = object_store->library_prefix_class(); |
| + ASSERT(!cls.IsNull()); |
| + RegisterPrivateClass(cls, Symbols::_LibraryPrefix(), core_lib); |
| + pending_classes.Add(cls); |
| + |
| cls = object_store->type_class(); |
| RegisterPrivateClass(cls, Symbols::Type(), core_lib); |
| pending_classes.Add(cls); |
| @@ -1337,6 +1340,9 @@ |
| cls = Class::New<Instance>(kInstanceCid); |
| object_store->set_object_class(cls); |
| + cls = Class::New<LibraryPrefix>(); |
| + object_store->set_library_prefix_class(cls); |
| + |
| cls = Class::New<Type>(); |
| object_store->set_type_class(cls); |
| @@ -2443,9 +2449,12 @@ |
| function ^= code.function(); |
| // If function uses dependent code switch it to unoptimized. |
| if (function.CurrentCode() == code.raw()) { |
| - ASSERT(function.HasOptimizedCode()); |
| ReportSwitchingCode(code); |
| - function.SwitchToUnoptimizedCode(); |
| + if (code.is_optimized()) { |
|
Ivan Posva
2014/03/27 07:38:48
What if we have optimized code that needs to be en
hausner
2014/03/27 20:45:39
I think we spoke about this before i implemented i
Ivan Posva
2014/03/27 21:41:18
I worry about the ordering of code removal a bit.
|
| + function.SwitchToUnoptimizedCode(); |
| + } else { |
| + function.ClearCode(); |
| + } |
| } |
| } |
| } |
| @@ -8741,6 +8750,7 @@ |
| result.set_native_entry_resolver(NULL); |
| result.raw_ptr()->corelib_imported_ = true; |
| result.set_debuggable(false); |
| + result.raw_ptr()->deferred_load_ = false; |
| result.raw_ptr()->load_state_ = RawLibrary::kAllocated; |
| result.raw_ptr()->index_ = -1; |
| const intptr_t kInitialNameCacheSize = 64; |
| @@ -9107,6 +9117,9 @@ |
| void LibraryPrefix::AddImport(const Namespace& import) const { |
| intptr_t num_current_imports = num_imports(); |
| + // Prefixes with deferred libraries can only contain one library. |
| + ASSERT((num_current_imports == 0) || !is_deferred_load()); |
| + |
| // The library needs to be added to the list. |
| Array& imports = Array::Handle(this->imports()); |
| const intptr_t length = (imports.IsNull()) ? 0 : imports.Length(); |
| @@ -9122,6 +9135,9 @@ |
| RawObject* LibraryPrefix::LookupObject(const String& name) const { |
| + if (!is_loaded()) { |
| + return Object::null(); |
| + } |
| Array& imports = Array::Handle(this->imports()); |
| Object& obj = Object::Handle(); |
| Namespace& import = Namespace::Handle(); |
| @@ -9168,8 +9184,82 @@ |
| } |
| +void LibraryPrefix::set_is_loaded() const { |
| + raw_ptr()->is_loaded_ = true; |
| +} |
| + |
| + |
| +void LibraryPrefix::LoadLibrary() const { |
| + if (!is_deferred_load()) { |
| + return; |
| + } |
| + if (is_loaded()) { |
|
Ivan Posva
2014/03/27 07:38:48
What is the value of loaded for an eagerly loaded
hausner
2014/03/27 20:45:39
That is true. I'll change this to an assert to ens
|
| + return; |
| + } |
| + NukeDependentCode(); |
| + set_is_loaded(); |
| +} |
| + |
| + |
| +RawArray* LibraryPrefix::dependent_code() const { |
| + return raw_ptr()->dependent_code_; |
| +} |
| + |
| + |
| +void LibraryPrefix::set_dependent_code(const Array& array) const { |
| + StorePointer(&raw_ptr()->dependent_code_, array.raw()); |
| +} |
| + |
| + |
| +class PrefixDependentArray : public WeakCodeReferences { |
| + public: |
| + explicit PrefixDependentArray(const LibraryPrefix& prefix) |
| + : WeakCodeReferences(Array::Handle(prefix.dependent_code())), |
| + prefix_(prefix) {} |
| + |
| + virtual void UpdateArrayTo(const Array& value) { |
| + prefix_.set_dependent_code(value); |
| + } |
| + |
| + virtual void ReportDeoptimization(const Code& code) { |
| + // This gets called when the code object is on the stack |
| + // while nuking code that depends on a prefix. We don't expect |
| + // this to happen, so make sure we die loudly if we find |
| + // ourselves here. |
| + UNIMPLEMENTED(); |
| + } |
| + |
| + virtual void ReportSwitchingCode(const Code& code) { |
| + if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { |
| + OS::PrintErr("Prefix '%s': deleting code for function '%s'\n", |
| + String::Handle(prefix_.name()).ToCString(), |
| + Function::Handle(code.function()).ToCString()); |
| + } |
| + } |
| + |
| + private: |
| + const LibraryPrefix& prefix_; |
| + DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray); |
| +}; |
| + |
| + |
| +void LibraryPrefix::RegisterDependentCode(const Code& code) const { |
| + ASSERT(is_deferred_load()); |
| + ASSERT(!is_loaded()); |
| + PrefixDependentArray a(*this); |
| + a.Register(code); |
| +} |
| + |
| + |
| +void LibraryPrefix::NukeDependentCode() const { |
| + PrefixDependentArray a(*this); |
| + a.DisableCode(); |
| +} |
| + |
| + |
| RawLibraryPrefix* LibraryPrefix::New() { |
| - ASSERT(Object::library_prefix_class() != Class::null()); |
| + ASSERT(Isolate::Current()->object_store()->library_prefix_class() != |
| + Class::null()); |
| RawObject* raw = Object::Allocate(LibraryPrefix::kClassId, |
| LibraryPrefix::InstanceSize(), |
| Heap::kOld); |
| @@ -9178,12 +9268,16 @@ |
| RawLibraryPrefix* LibraryPrefix::New(const String& name, |
| - const Namespace& import) { |
| + const Namespace& import, |
| + bool deferred_load) { |
| const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); |
| result.set_name(name); |
| result.set_num_imports(0); |
| + result.raw_ptr()->is_deferred_load_ = deferred_load; |
| + result.raw_ptr()->is_loaded_ = !deferred_load; |
| result.set_imports(Array::Handle(Array::New(kInitialSize))); |
| result.AddImport(import); |
| + result.set_dependent_code(Object::null_array()); |
| return result.raw(); |
| } |