1 /* 2 * Copyright (c) 2025 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 16 #ifndef ECMASCRIPT_DEPENDENT_INFOS_H 17 #define ECMASCRIPT_DEPENDENT_INFOS_H 18 19 #include "ecmascript/weak_vector.h" 20 21 namespace panda::ecmascript { 22 #define LAZY_DEOPT_TYPE_LIST(V) \ 23 V(PROTOTYPE_CHECK, 1ULL << 0) \ 24 V(IS_PROTOTYPE_CHECK, 1ULL << 1) \ 25 V(DETECTOR_CHECK, 1ULL << 2) \ 26 V(HOTRELOAD_PATCHMAIN, 1ULL << 3) 27 28 /* 29 * -------------- Structure of DependentInfos -------------- 30 * 31 * Index | Stored Content | Description 32 * ------|----------------------|--------------------------- 33 * 0 | function0 | Function Slot 34 * 1 | collection0 | Collection Slot 35 * 2 | function1 | Function Slot 36 * 3 | collection1 | Collection Slot 37 * 4 | function2 | Function Slot 38 * 5 | collection2 | Collection Slot 39 * 6 | ... | ... 40 */ 41 42 /* 43 * DependentInfos are stored on the HClass as (function)-(collection) pairs. 44 * 45 * When the HClass changes in a way that satisfies collection's requirement, 46 * the corresponding paired function is marked for lazy deoptimization. 47 */ 48 class DependentInfos : public WeakVector { 49 public: 50 static constexpr uint32_t SLOT_PER_ENTRY = 2; 51 static constexpr uint32_t FUNCTION_SLOT_OFFSET = 0; 52 static constexpr uint32_t COLLECTION_SLOT_OFFSET = 1; Cast(TaggedObject * object)53 static DependentInfos *Cast(TaggedObject *object) 54 { 55 return static_cast<DependentInfos *>(object); 56 } 57 enum DependentState : uint32_t { 58 #define LAZY_DEOPT_TYPE_MEMBER(name, value) name = (value), 59 LAZY_DEOPT_TYPE_LIST(LAZY_DEOPT_TYPE_MEMBER) 60 #undef LAZY_DEOPT_TYPE_MEMBER 61 }; 62 using DependentStateCollection = uint32_t; 63 64 static JSHandle<DependentInfos> AppendDependentInfos(JSThread *thread, 65 const JSHandle<JSTaggedValue> jsFunc, 66 const DependentStateCollection collection, 67 const JSHandle<DependentInfos> info); 68 // CheckCollectionEffect ensures don't trigger unnecessary lazy deopt. 69 // For example, when we need to ensure the IsStable flag of HClass remains valid, 70 // modifying the IsPrototype flag of that HClass 71 // shouldn't trigger lazy deopt. CheckCollectionEffect(DependentStateCollection depCollection,DependentStateCollection collection)72 static bool CheckCollectionEffect(DependentStateCollection depCollection, DependentStateCollection collection) 73 { 74 return (depCollection & collection) > 0; 75 } 76 static void TriggerLazyDeoptimization(JSHandle<DependentInfos> dependentInfos, 77 JSThread *thread, DependentStateCollection Collection); 78 static void TraceLazyDeoptReason(JSThread *thread, JSHandle<JSFunction> func, 79 DependentStateCollection collection); 80 }; 81 } // namespace panda::ecmascript 82 #endif // ECMASCRIPT_DEPENDENT_INFOS_H