| 1 | // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file | 
|---|
| 2 | // for details. All rights reserved. Use of this source code is governed by a | 
|---|
| 3 | // BSD-style license that can be found in the LICENSE file. | 
|---|
| 4 |  | 
|---|
| 5 | #ifndef RUNTIME_VM_ISOLATE_RELOAD_H_ | 
|---|
| 6 | #define RUNTIME_VM_ISOLATE_RELOAD_H_ | 
|---|
| 7 |  | 
|---|
| 8 | #include <functional> | 
|---|
| 9 | #include <memory> | 
|---|
| 10 |  | 
|---|
| 11 | #include "include/dart_tools_api.h" | 
|---|
| 12 |  | 
|---|
| 13 | #include "vm/globals.h" | 
|---|
| 14 | #include "vm/growable_array.h" | 
|---|
| 15 | #include "vm/hash_map.h" | 
|---|
| 16 | #include "vm/log.h" | 
|---|
| 17 | #include "vm/object.h" | 
|---|
| 18 |  | 
|---|
| 19 | DECLARE_FLAG(bool, trace_reload); | 
|---|
| 20 | DECLARE_FLAG(bool, trace_reload_verbose); | 
|---|
| 21 |  | 
|---|
| 22 | // 'Trace Isolate Reload' TIR_Print | 
|---|
| 23 | #if defined(_MSC_VER) | 
|---|
| 24 | #define TIR_Print(format, ...)                                                 \ | 
|---|
| 25 | if (FLAG_trace_reload) Log::Current()->Print(format, __VA_ARGS__) | 
|---|
| 26 | #else | 
|---|
| 27 | #define TIR_Print(format, ...)                                                 \ | 
|---|
| 28 | if (FLAG_trace_reload) Log::Current()->Print(format, ##__VA_ARGS__) | 
|---|
| 29 | #endif | 
|---|
| 30 |  | 
|---|
| 31 | // 'Verbose Trace Isolate Reload' VTIR_Print | 
|---|
| 32 | #if defined(_MSC_VER) | 
|---|
| 33 | #define VTIR_Print(format, ...)                                                \ | 
|---|
| 34 | if (FLAG_trace_reload_verbose) Log::Current()->Print(format, __VA_ARGS__) | 
|---|
| 35 | #else | 
|---|
| 36 | #define VTIR_Print(format, ...)                                                \ | 
|---|
| 37 | if (FLAG_trace_reload_verbose) Log::Current()->Print(format, ##__VA_ARGS__) | 
|---|
| 38 | #endif | 
|---|
| 39 |  | 
|---|
| 40 | #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | 
|---|
| 41 |  | 
|---|
| 42 | namespace dart { | 
|---|
| 43 |  | 
|---|
| 44 | class BitVector; | 
|---|
| 45 | class GrowableObjectArray; | 
|---|
| 46 | class Isolate; | 
|---|
| 47 | class Library; | 
|---|
| 48 | class ObjectLocator; | 
|---|
| 49 | class ObjectPointerVisitor; | 
|---|
| 50 | class ObjectStore; | 
|---|
| 51 | class Script; | 
|---|
| 52 | class UpdateClassesVisitor; | 
|---|
| 53 |  | 
|---|
| 54 | class InstanceMorpher : public ZoneAllocated { | 
|---|
| 55 | public: | 
|---|
| 56 | // Creates a new [InstanceMorpher] based on the [from]/[to] class | 
|---|
| 57 | // descriptions. | 
|---|
| 58 | static InstanceMorpher* CreateFromClassDescriptors( | 
|---|
| 59 | Zone* zone, | 
|---|
| 60 | SharedClassTable* shared_class_table, | 
|---|
| 61 | const Class& from, | 
|---|
| 62 | const Class& to); | 
|---|
| 63 |  | 
|---|
| 64 | InstanceMorpher(Zone* zone, | 
|---|
| 65 | classid_t cid, | 
|---|
| 66 | SharedClassTable* shared_class_table, | 
|---|
| 67 | ZoneGrowableArray<intptr_t>* mapping, | 
|---|
| 68 | ZoneGrowableArray<intptr_t>* new_fields_offsets); | 
|---|
| 69 | virtual ~InstanceMorpher() {} | 
|---|
| 70 |  | 
|---|
| 71 | // Called on each instance that needs to be morphed. | 
|---|
| 72 | InstancePtr Morph(const Instance& instance) const; | 
|---|
| 73 |  | 
|---|
| 74 | // Adds an object to be morphed. | 
|---|
| 75 | void AddObject(ObjectPtr object); | 
|---|
| 76 |  | 
|---|
| 77 | // Create the morphed objects based on the before() list. | 
|---|
| 78 | void CreateMorphedCopies(); | 
|---|
| 79 |  | 
|---|
| 80 | // Append the morper info to JSON array. | 
|---|
| 81 | void AppendTo(JSONArray* array); | 
|---|
| 82 |  | 
|---|
| 83 | // Returns the list of objects that need to be morphed. | 
|---|
| 84 | const GrowableArray<const Instance*>* before() const { return &before_; } | 
|---|
| 85 |  | 
|---|
| 86 | // Returns the list of morphed objects (matches order in before()). | 
|---|
| 87 | const GrowableArray<const Instance*>* after() const { return &after_; } | 
|---|
| 88 |  | 
|---|
| 89 | // Returns the cid associated with the from_ and to_ class. | 
|---|
| 90 | intptr_t cid() const { return cid_; } | 
|---|
| 91 |  | 
|---|
| 92 | // Dumps the field mappings for the [cid()] class. | 
|---|
| 93 | void Dump() const; | 
|---|
| 94 |  | 
|---|
| 95 | private: | 
|---|
| 96 | Zone* zone_; | 
|---|
| 97 | classid_t cid_; | 
|---|
| 98 | SharedClassTable* shared_class_table_; | 
|---|
| 99 | ZoneGrowableArray<intptr_t>* mapping_; | 
|---|
| 100 | ZoneGrowableArray<intptr_t>* new_fields_offsets_; | 
|---|
| 101 |  | 
|---|
| 102 | GrowableArray<const Instance*> before_; | 
|---|
| 103 | GrowableArray<const Instance*> after_; | 
|---|
| 104 | }; | 
|---|
| 105 |  | 
|---|
| 106 | class ReasonForCancelling : public ZoneAllocated { | 
|---|
| 107 | public: | 
|---|
| 108 | explicit ReasonForCancelling(Zone* zone) {} | 
|---|
| 109 | virtual ~ReasonForCancelling() {} | 
|---|
| 110 |  | 
|---|
| 111 | // Reports a reason for cancelling reload. | 
|---|
| 112 | void Report(IsolateGroupReloadContext* context); | 
|---|
| 113 |  | 
|---|
| 114 | // Conversion to a VM error object. | 
|---|
| 115 | // Default implementation calls ToString. | 
|---|
| 116 | virtual ErrorPtr ToError(); | 
|---|
| 117 |  | 
|---|
| 118 | // Conversion to a string object. | 
|---|
| 119 | // Default implementation calls ToError. | 
|---|
| 120 | virtual StringPtr ToString(); | 
|---|
| 121 |  | 
|---|
| 122 | // Append the reason to JSON array. | 
|---|
| 123 | virtual void AppendTo(JSONArray* array); | 
|---|
| 124 |  | 
|---|
| 125 | // Concrete subclasses must override either ToError or ToString. | 
|---|
| 126 | }; | 
|---|
| 127 |  | 
|---|
| 128 | // Abstract class for also capturing the from_ and to_ class. | 
|---|
| 129 | class ClassReasonForCancelling : public ReasonForCancelling { | 
|---|
| 130 | public: | 
|---|
| 131 | ClassReasonForCancelling(Zone* zone, const Class& from, const Class& to); | 
|---|
| 132 | void AppendTo(JSONArray* array); | 
|---|
| 133 |  | 
|---|
| 134 | protected: | 
|---|
| 135 | const Class& from_; | 
|---|
| 136 | const Class& to_; | 
|---|
| 137 | }; | 
|---|
| 138 |  | 
|---|
| 139 | class IsolateGroupReloadContext { | 
|---|
| 140 | public: | 
|---|
| 141 | IsolateGroupReloadContext(IsolateGroup* isolate, | 
|---|
| 142 | SharedClassTable* shared_class_table, | 
|---|
| 143 | JSONStream* js); | 
|---|
| 144 | ~IsolateGroupReloadContext(); | 
|---|
| 145 |  | 
|---|
| 146 | // If kernel_buffer is provided, the VM takes ownership when Reload is called. | 
|---|
| 147 | bool Reload(bool force_reload, | 
|---|
| 148 | const char* root_script_url = NULL, | 
|---|
| 149 | const char* packages_url = NULL, | 
|---|
| 150 | const uint8_t* kernel_buffer = NULL, | 
|---|
| 151 | intptr_t kernel_buffer_size = 0); | 
|---|
| 152 |  | 
|---|
| 153 | // All zone allocated objects must be allocated from this zone. | 
|---|
| 154 | Zone* zone() const { return zone_; } | 
|---|
| 155 |  | 
|---|
| 156 | bool UseSavedSizeTableForGC() const { | 
|---|
| 157 | return saved_size_table_.load(std::memory_order_relaxed) != nullptr; | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | IsolateGroup* isolate_group() const { return isolate_group_; } | 
|---|
| 161 | bool reload_aborted() const { return HasReasonsForCancelling(); } | 
|---|
| 162 | bool reload_skipped() const { return reload_skipped_; } | 
|---|
| 163 | ErrorPtr error() const; | 
|---|
| 164 | int64_t start_time_micros() const { return start_time_micros_; } | 
|---|
| 165 | int64_t reload_timestamp() const { return reload_timestamp_; } | 
|---|
| 166 |  | 
|---|
| 167 | static Dart_FileModifiedCallback file_modified_callback() { | 
|---|
| 168 | return file_modified_callback_; | 
|---|
| 169 | } | 
|---|
| 170 | static void SetFileModifiedCallback(Dart_FileModifiedCallback callback) { | 
|---|
| 171 | file_modified_callback_ = callback; | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 | private: | 
|---|
| 175 | intptr_t GetClassSizeForHeapWalkAt(classid_t cid); | 
|---|
| 176 | void DiscardSavedClassTable(bool is_rollback); | 
|---|
| 177 |  | 
|---|
| 178 | // Tells whether there are reasons for cancelling the reload. | 
|---|
| 179 | bool HasReasonsForCancelling() const { | 
|---|
| 180 | return !reasons_to_cancel_reload_.is_empty(); | 
|---|
| 181 | } | 
|---|
| 182 |  | 
|---|
| 183 | // Record problem for this reload. | 
|---|
| 184 | void AddReasonForCancelling(ReasonForCancelling* reason); | 
|---|
| 185 |  | 
|---|
| 186 | // Reports all reasons for cancelling reload. | 
|---|
| 187 | void ReportReasonsForCancelling(); | 
|---|
| 188 |  | 
|---|
| 189 | // Reports the details of a reload operation. | 
|---|
| 190 | void ReportOnJSON(JSONStream* stream, intptr_t final_library_count); | 
|---|
| 191 |  | 
|---|
| 192 | // Ensures there is a instance morpher for [cid], if not it will use | 
|---|
| 193 | // [instance_morpher] | 
|---|
| 194 | void EnsureHasInstanceMorpherFor(classid_t cid, | 
|---|
| 195 | InstanceMorpher* instance_morpher); | 
|---|
| 196 |  | 
|---|
| 197 | // Tells whether instance in the heap must be morphed. | 
|---|
| 198 | bool HasInstanceMorphers() const { return !instance_morphers_.is_empty(); } | 
|---|
| 199 |  | 
|---|
| 200 | // Called by both FinalizeLoading and FinalizeFailedLoad. | 
|---|
| 201 | void CommonFinalizeTail(intptr_t final_library_count); | 
|---|
| 202 |  | 
|---|
| 203 | // Report back through the observatory channels. | 
|---|
| 204 | void ReportError(const Error& error); | 
|---|
| 205 | void ReportSuccess(); | 
|---|
| 206 |  | 
|---|
| 207 | void VisitObjectPointers(ObjectPointerVisitor* visitor); | 
|---|
| 208 |  | 
|---|
| 209 | void GetRootLibUrl(const char* root_script_url); | 
|---|
| 210 | char* CompileToKernel(bool force_reload, | 
|---|
| 211 | const char* packages_url, | 
|---|
| 212 | const uint8_t** kernel_buffer, | 
|---|
| 213 | intptr_t* kernel_buffer_size); | 
|---|
| 214 | void BuildModifiedLibrariesClosure(BitVector* modified_libs); | 
|---|
| 215 | void FindModifiedSources(bool force_reload, | 
|---|
| 216 | Dart_SourceFile** modified_sources, | 
|---|
| 217 | intptr_t* count, | 
|---|
| 218 | const char* packages_url); | 
|---|
| 219 | bool ScriptModifiedSince(const Script& script, int64_t since); | 
|---|
| 220 |  | 
|---|
| 221 | void CheckpointSharedClassTable(); | 
|---|
| 222 |  | 
|---|
| 223 | void MorphInstancesPhase1Allocate(ObjectLocator* locator, | 
|---|
| 224 | const Array& before, | 
|---|
| 225 | const Array& after); | 
|---|
| 226 | void MorphInstancesPhase2Become(const Array& before, const Array& after); | 
|---|
| 227 |  | 
|---|
| 228 | void ForEachIsolate(std::function<void(Isolate*)> callback); | 
|---|
| 229 |  | 
|---|
| 230 | // The zone used for all reload related allocations. | 
|---|
| 231 | Zone* zone_; | 
|---|
| 232 |  | 
|---|
| 233 | IsolateGroup* isolate_group_; | 
|---|
| 234 | SharedClassTable* shared_class_table_; | 
|---|
| 235 |  | 
|---|
| 236 | int64_t start_time_micros_ = -1; | 
|---|
| 237 | int64_t reload_timestamp_ = -1; | 
|---|
| 238 | Isolate* first_isolate_ = nullptr; | 
|---|
| 239 | bool reload_skipped_ = false; | 
|---|
| 240 | bool reload_finalized_ = false; | 
|---|
| 241 | JSONStream* js_; | 
|---|
| 242 | intptr_t num_old_libs_ = -1; | 
|---|
| 243 |  | 
|---|
| 244 | intptr_t saved_num_cids_ = -1; | 
|---|
| 245 | std::atomic<intptr_t*> saved_size_table_; | 
|---|
| 246 | intptr_t num_received_libs_ = -1; | 
|---|
| 247 | intptr_t bytes_received_libs_ = -1; | 
|---|
| 248 | intptr_t num_received_classes_ = -1; | 
|---|
| 249 | intptr_t num_received_procedures_ = -1; | 
|---|
| 250 | intptr_t num_saved_libs_ = -1; | 
|---|
| 251 |  | 
|---|
| 252 | // Required trait for the instance_morpher_by_cid_; | 
|---|
| 253 | struct MorpherTrait { | 
|---|
| 254 | typedef InstanceMorpher* Value; | 
|---|
| 255 | typedef intptr_t Key; | 
|---|
| 256 | typedef InstanceMorpher* Pair; | 
|---|
| 257 |  | 
|---|
| 258 | static Key KeyOf(Pair kv) { return kv->cid(); } | 
|---|
| 259 | static Value ValueOf(Pair kv) { return kv; } | 
|---|
| 260 | static intptr_t Hashcode(Key key) { return key; } | 
|---|
| 261 | static bool IsKeyEqual(Pair kv, Key key) { return kv->cid() == key; } | 
|---|
| 262 | }; | 
|---|
| 263 |  | 
|---|
| 264 | // Collect the necessary instance transformation for schema changes. | 
|---|
| 265 | GrowableArray<InstanceMorpher*> instance_morphers_; | 
|---|
| 266 |  | 
|---|
| 267 | // Collects the reasons for cancelling the reload. | 
|---|
| 268 | GrowableArray<ReasonForCancelling*> reasons_to_cancel_reload_; | 
|---|
| 269 |  | 
|---|
| 270 | // Hash map from cid to InstanceMorpher. | 
|---|
| 271 | DirectChainedHashMap<MorpherTrait> instance_morpher_by_cid_; | 
|---|
| 272 |  | 
|---|
| 273 | // A bit vector indicating which of the original libraries were modified. | 
|---|
| 274 | BitVector* modified_libs_ = nullptr; | 
|---|
| 275 |  | 
|---|
| 276 | // A bit vector indicating which of the original libraries were modified, | 
|---|
| 277 | // or where a transitive dependency was modified. | 
|---|
| 278 | BitVector* modified_libs_transitive_ = nullptr; | 
|---|
| 279 |  | 
|---|
| 280 | // A bit vector indicating which of the saved libraries that transitively | 
|---|
| 281 | // depend on a modified libary. | 
|---|
| 282 | BitVector* saved_libs_transitive_updated_ = nullptr; | 
|---|
| 283 |  | 
|---|
| 284 | String& root_lib_url_; | 
|---|
| 285 | ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&root_url_prefix_); } | 
|---|
| 286 | StringPtr root_url_prefix_; | 
|---|
| 287 | StringPtr old_root_url_prefix_; | 
|---|
| 288 | ObjectPtr* to() { | 
|---|
| 289 | return reinterpret_cast<ObjectPtr*>(&old_root_url_prefix_); | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | friend class Isolate; | 
|---|
| 293 | friend class Class;  // AddStaticFieldMapping, AddEnumBecomeMapping. | 
|---|
| 294 | friend class Library; | 
|---|
| 295 | friend class ObjectLocator; | 
|---|
| 296 | friend class MarkFunctionsForRecompilation;  // IsDirty. | 
|---|
| 297 | friend class ReasonForCancelling; | 
|---|
| 298 | friend class IsolateReloadContext; | 
|---|
| 299 | friend class IsolateGroup;  // GetClassSizeForHeapWalkAt | 
|---|
| 300 | friend class ObjectLayout;  // GetClassSizeForHeapWalkAt | 
|---|
| 301 |  | 
|---|
| 302 | static Dart_FileModifiedCallback file_modified_callback_; | 
|---|
| 303 | }; | 
|---|
| 304 |  | 
|---|
| 305 | class IsolateReloadContext { | 
|---|
| 306 | public: | 
|---|
| 307 | IsolateReloadContext( | 
|---|
| 308 | std::shared_ptr<IsolateGroupReloadContext> group_reload_context, | 
|---|
| 309 | Isolate* isolate); | 
|---|
| 310 | ~IsolateReloadContext(); | 
|---|
| 311 |  | 
|---|
| 312 | // All zone allocated objects must be allocated from this zone. | 
|---|
| 313 | Zone* zone() const { return zone_; } | 
|---|
| 314 |  | 
|---|
| 315 | IsolateGroupReloadContext* group_reload_context() { | 
|---|
| 316 | return group_reload_context_.get(); | 
|---|
| 317 | } | 
|---|
| 318 |  | 
|---|
| 319 | static bool IsSameLibrary(const Library& a_lib, const Library& b_lib); | 
|---|
| 320 | static bool IsSameClass(const Class& a, const Class& b); | 
|---|
| 321 |  | 
|---|
| 322 | private: | 
|---|
| 323 | bool IsDirty(const Library& lib); | 
|---|
| 324 |  | 
|---|
| 325 | // Prefers old classes when we are in the middle of a reload. | 
|---|
| 326 | ClassPtr GetClassForHeapWalkAt(intptr_t cid); | 
|---|
| 327 | void DiscardSavedClassTable(bool is_rollback); | 
|---|
| 328 |  | 
|---|
| 329 | void RegisterClass(const Class& new_cls); | 
|---|
| 330 |  | 
|---|
| 331 | // Finds the library private key for |replacement_or_new| or return null | 
|---|
| 332 | // if |replacement_or_new| is new. | 
|---|
| 333 | StringPtr FindLibraryPrivateKey(const Library& replacement_or_new); | 
|---|
| 334 |  | 
|---|
| 335 | void VisitObjectPointers(ObjectPointerVisitor* visitor); | 
|---|
| 336 |  | 
|---|
| 337 | Isolate* isolate() { return isolate_; } | 
|---|
| 338 | ObjectStore* object_store(); | 
|---|
| 339 |  | 
|---|
| 340 | void EnsuredUnoptimizedCodeForStack(); | 
|---|
| 341 | void DeoptimizeDependentCode(); | 
|---|
| 342 |  | 
|---|
| 343 | void ReloadPhase1AllocateStorageMapsAndCheckpoint(); | 
|---|
| 344 | void CheckpointClasses(); | 
|---|
| 345 | ObjectPtr ReloadPhase2LoadKernel(kernel::Program* program, | 
|---|
| 346 | const String& root_lib_url); | 
|---|
| 347 | void ReloadPhase3FinalizeLoading(); | 
|---|
| 348 | void ReloadPhase4CommitPrepare(); | 
|---|
| 349 | void ReloadPhase4CommitFinish(); | 
|---|
| 350 | void ReloadPhase4Rollback(); | 
|---|
| 351 |  | 
|---|
| 352 | void CheckpointLibraries(); | 
|---|
| 353 |  | 
|---|
| 354 | void RollbackClasses(); | 
|---|
| 355 | void RollbackLibraries(); | 
|---|
| 356 |  | 
|---|
| 357 | #ifdef DEBUG | 
|---|
| 358 | void VerifyMaps(); | 
|---|
| 359 | #endif | 
|---|
| 360 |  | 
|---|
| 361 | void CommitBeforeInstanceMorphing(); | 
|---|
| 362 | void CommitAfterInstanceMorphing(); | 
|---|
| 363 | void PostCommit(); | 
|---|
| 364 |  | 
|---|
| 365 | void RunInvalidationVisitors(); | 
|---|
| 366 | void InvalidateKernelInfos( | 
|---|
| 367 | Zone* zone, | 
|---|
| 368 | const GrowableArray<const KernelProgramInfo*>& kernel_infos); | 
|---|
| 369 | void InvalidateFunctions(Zone* zone, | 
|---|
| 370 | const GrowableArray<const Function*>& functions); | 
|---|
| 371 | void InvalidateFields(Zone* zone, | 
|---|
| 372 | const GrowableArray<const Field*>& fields, | 
|---|
| 373 | const GrowableArray<const Instance*>& instances); | 
|---|
| 374 | void ResetUnoptimizedICsOnStack(); | 
|---|
| 375 | void ResetMegamorphicCaches(); | 
|---|
| 376 | void InvalidateWorld(); | 
|---|
| 377 |  | 
|---|
| 378 | struct LibraryInfo { | 
|---|
| 379 | bool dirty; | 
|---|
| 380 | }; | 
|---|
| 381 |  | 
|---|
| 382 | // The zone used for all reload related allocations. | 
|---|
| 383 | Zone* zone_; | 
|---|
| 384 | std::shared_ptr<IsolateGroupReloadContext> group_reload_context_; | 
|---|
| 385 | Isolate* isolate_; | 
|---|
| 386 | intptr_t saved_num_cids_ = -1; | 
|---|
| 387 | intptr_t saved_num_tlc_cids_ = -1; | 
|---|
| 388 | std::atomic<ClassPtr*> saved_class_table_; | 
|---|
| 389 | std::atomic<ClassPtr*> saved_tlc_class_table_; | 
|---|
| 390 | MallocGrowableArray<LibraryInfo> library_infos_; | 
|---|
| 391 |  | 
|---|
| 392 | ClassPtr OldClassOrNull(const Class& replacement_or_new); | 
|---|
| 393 | LibraryPtr OldLibraryOrNull(const Library& replacement_or_new); | 
|---|
| 394 | LibraryPtr OldLibraryOrNullBaseMoved(const Library& replacement_or_new); | 
|---|
| 395 |  | 
|---|
| 396 | void BuildLibraryMapping(); | 
|---|
| 397 | void BuildRemovedClassesSet(); | 
|---|
| 398 | void ValidateReload(); | 
|---|
| 399 |  | 
|---|
| 400 | void AddClassMapping(const Class& replacement_or_new, const Class& original); | 
|---|
| 401 | void AddLibraryMapping(const Library& replacement_or_new, | 
|---|
| 402 | const Library& original); | 
|---|
| 403 | void AddStaticFieldMapping(const Field& old_field, const Field& new_field); | 
|---|
| 404 | void AddBecomeMapping(const Object& old, const Object& neu); | 
|---|
| 405 | void AddEnumBecomeMapping(const Object& old, const Object& neu); | 
|---|
| 406 | void RebuildDirectSubclasses(); | 
|---|
| 407 |  | 
|---|
| 408 | ObjectPtr* from() { | 
|---|
| 409 | return reinterpret_cast<ObjectPtr*>(&old_classes_set_storage_); | 
|---|
| 410 | } | 
|---|
| 411 | ArrayPtr old_classes_set_storage_; | 
|---|
| 412 | ArrayPtr class_map_storage_; | 
|---|
| 413 | ArrayPtr removed_class_set_storage_; | 
|---|
| 414 | ArrayPtr old_libraries_set_storage_; | 
|---|
| 415 | ArrayPtr library_map_storage_; | 
|---|
| 416 | ArrayPtr become_map_storage_; | 
|---|
| 417 | GrowableObjectArrayPtr become_enum_mappings_; | 
|---|
| 418 | LibraryPtr saved_root_library_; | 
|---|
| 419 | GrowableObjectArrayPtr saved_libraries_; | 
|---|
| 420 | ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&saved_libraries_); } | 
|---|
| 421 |  | 
|---|
| 422 | friend class Isolate; | 
|---|
| 423 | friend class Class;  // AddStaticFieldMapping, AddEnumBecomeMapping. | 
|---|
| 424 | friend class Library; | 
|---|
| 425 | friend class ObjectLocator; | 
|---|
| 426 | friend class MarkFunctionsForRecompilation;  // IsDirty. | 
|---|
| 427 | friend class ReasonForCancelling; | 
|---|
| 428 | friend class IsolateGroupReloadContext; | 
|---|
| 429 | }; | 
|---|
| 430 |  | 
|---|
| 431 | class CallSiteResetter : public ValueObject { | 
|---|
| 432 | public: | 
|---|
| 433 | explicit CallSiteResetter(Zone* zone); | 
|---|
| 434 |  | 
|---|
| 435 | void ZeroEdgeCounters(const Function& function); | 
|---|
| 436 | void ResetCaches(const Code& code); | 
|---|
| 437 | void ResetCaches(const ObjectPool& pool); | 
|---|
| 438 | void RebindStaticTargets(const Bytecode& code); | 
|---|
| 439 | void Reset(const ICData& ic); | 
|---|
| 440 | void ResetSwitchableCalls(const Code& code); | 
|---|
| 441 |  | 
|---|
| 442 | private: | 
|---|
| 443 | Zone* zone_; | 
|---|
| 444 | Instructions& instrs_; | 
|---|
| 445 | ObjectPool& pool_; | 
|---|
| 446 | Object& object_; | 
|---|
| 447 | String& name_; | 
|---|
| 448 | Class& new_cls_; | 
|---|
| 449 | Library& new_lib_; | 
|---|
| 450 | Function& new_function_; | 
|---|
| 451 | Field& new_field_; | 
|---|
| 452 | Array& entries_; | 
|---|
| 453 | Function& old_target_; | 
|---|
| 454 | Function& new_target_; | 
|---|
| 455 | Function& caller_; | 
|---|
| 456 | Array& args_desc_array_; | 
|---|
| 457 | Array& ic_data_array_; | 
|---|
| 458 | Array& edge_counters_; | 
|---|
| 459 | PcDescriptors& descriptors_; | 
|---|
| 460 | ICData& ic_data_; | 
|---|
| 461 | }; | 
|---|
| 462 |  | 
|---|
| 463 | }  // namespace dart | 
|---|
| 464 |  | 
|---|
| 465 | #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | 
|---|
| 466 |  | 
|---|
| 467 | #endif  // RUNTIME_VM_ISOLATE_RELOAD_H_ | 
|---|
| 468 |  | 
|---|