1 /** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_RUNTIME_HOTRELOAD_HOTRELOAD_H_ 16 #define PANDA_RUNTIME_HOTRELOAD_HOTRELOAD_H_ 17 18 #include "libpandabase/macros.h" 19 #include "libpandafile/file.h" 20 #include "runtime/include/class.h" 21 #include "runtime/include/managed_thread.h" 22 #include "runtime/include/mem/panda_containers.h" 23 #include "runtime/include/panda_vm.h" 24 #include "runtime/include/runtime.h" 25 #include "runtime/mem/rendezvous.h" 26 27 namespace ark::hotreload { 28 29 struct ClassContainment { 30 const panda_file::File *pf; 31 panda_file::File::EntityId classId; 32 const std::string className_; 33 Class *loadedClass; 34 Class *tmpClass; 35 uint32_t fChanges; 36 }; 37 38 enum class Error { 39 NONE, 40 INTERNAL, 41 CLASS_ALREADY_LOADED, 42 CLASS_NOT_FOUND, 43 EXTERNAL_CLASS_READ, 44 INVALID_INPUT_ARG, 45 UNSUPPORTED_CHANGES, 46 NO_DEBUGGER_ATTACHED, 47 CLASS_UNMODIFIABLE, 48 WRONG_CLASS_DESCRIPTOR, 49 INVALID_CLASS_FORMAT, 50 CIRCULAR_CLASS, 51 METHOD_ADDED, 52 METHOD_DELETED, 53 METHOD_SIGN, 54 CLASS_MODIFIERS, 55 HIERARCHY_CHANGED, 56 FIELD_CHANGED 57 }; 58 59 enum ChangesFlags : uint32_t { 60 F_NO_STRUCT_CHANGES = 0x0000U, 61 F_INHERITANCE = 0x0001U, 62 F_METHOD_SIGN = 0x0002U, 63 F_METHOD_DELETED = 0x0004U, 64 F_INTERFACES = 0x0008U, 65 F_FIELDS_TYPE = 0x0010U, 66 F_FIELDS_AMOUNT = 0x0020U, 67 F_ACCESS_FLAGS = 0x0040U, 68 F_METHOD_ADDED = 0x0080U 69 }; 70 71 enum class Type { STRUCTURAL, NORMAL, INVALID }; 72 73 class ArkHotreloadBase { 74 public: 75 /* 76 * There is no API for adding classes for hotreload 77 * 'cause its signature is language-dependent 78 * this API should be declared in superclass 79 */ 80 PANDA_PUBLIC_API Error ProcessHotreload(); 81 82 PANDA_PUBLIC_API const panda_file::File *ReadAndOwnPandaFileFromFile(const char *location); 83 PANDA_PUBLIC_API const panda_file::File *ReadAndOwnPandaFileFromMemory(const void *buffer, size_t size); 84 85 NO_COPY_SEMANTIC(ArkHotreloadBase); 86 NO_MOVE_SEMANTIC(ArkHotreloadBase); 87 88 protected: 89 explicit ArkHotreloadBase(ManagedThread *mthread, panda_file::SourceLang lang); 90 virtual ~ArkHotreloadBase(); 91 92 virtual Error LangSpecificValidateClasses() = 0; 93 virtual void LangSpecificHotreloadPart() = 0; 94 95 Error ValidateClassesHotreloadPossibility(); 96 Error ValidateClassForHotreload(const ClassContainment &hCls); 97 Type RecognizeHotreloadType(ClassContainment *hCls); 98 99 Type InheritanceChangesCheck(ClassContainment *hCls); 100 Type FlagsChangesCheck(ClassContainment *hCls); 101 Type FieldChangesCheck(ClassContainment *hCls); 102 Type MethodChangesCheck(ClassContainment *hCls); 103 104 void ReloadClassNormal(const ClassContainment *hCls); 105 void UpdateVtablesInRuntimeClasses(ClassLinker *classLinker); 106 void AddLoadedPandaFilesToRuntime(ClassLinker *classLinker); 107 void AddObsoleteClassesToRuntime(ClassLinker *classLinker); 108 109 using FieldIdTable = PandaUnorderedMap<panda_file::File::EntityId, panda_file::File::EntityId>; 110 111 panda_file::SourceLang lang_; // NOLINT(misc-non-private-member-variables-in-classes) 112 ManagedThread *thread_; // NOLINT(misc-non-private-member-variables-in-classes) 113 PandaVector<ClassContainment> classes_; // NOLINT(misc-non-private-member-variables-in-classes) 114 PandaVector<std::unique_ptr<const panda_file::File>> 115 pandaFiles_; // NOLINT(misc-non-private-member-variables-in-classes) 116 PandaUnorderedMap<Method *, Method *> methodsTable_; // NOLINT(misc-non-private-member-variables-in-classes) 117 PandaUnorderedMap<Class *, FieldIdTable> fieldsTables_; // NOLINT(misc-non-private-member-variables-in-classes) 118 PandaUnorderedSet<Class *> reloadedClasses_; // NOLINT(misc-non-private-member-variables-in-classes) 119 }; 120 121 } // namespace ark::hotreload 122 123 #endif // PANDA_RUNTIME_HOTRELOAD_HOTRELOAD_H_ 124