1 /* 2 * Copyright (c) 2021 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_TS_TYPES_TS_MANAGER_H 17 #define ECMASCRIPT_TS_TYPES_TS_MANAGER_H 18 19 #include "ecmascript/compiler/aot_snapshot/aot_snapshot.h" 20 #include "ecmascript/compiler/bytecode_info_collector.h" 21 #include "ecmascript/compiler/compilation_driver.h" 22 #include "ecmascript/compiler/pgo_type/pgo_type_manager.h" 23 #include "ecmascript/js_handle.h" 24 #include "ecmascript/js_tagged_value-inl.h" 25 #include "ecmascript/ts_types/builtin_type_id.h" 26 #include "ecmascript/ts_types/global_ts_type_ref.h" 27 #include "ecmascript/ts_types/global_type_info.h" 28 #include "ecmascript/ts_types/ts_obj_layout_info.h" 29 30 namespace panda::ecmascript { 31 using ProfileType = pgo::ProfileType; 32 using SnapshotGlobalData = kungfu::SnapshotGlobalData; 33 enum class PropertyType : uint8_t { 34 NORMAL = 0, 35 STATIC, 36 OTHERS, 37 }; 38 39 struct ModuleInfo { 40 const JSPandaFile *jsPandaFile {nullptr}; // there may be serval merged abc files. 41 const CString recordName {""}; // distinguish different files which are all merged to one abc file. 42 uint32_t index {0}; // bytecode "stmoudlevar index", exportVar index is unique in the same record. 43 bool operator < (const ModuleInfo &moduleInfo) const 44 { 45 if (index < moduleInfo.index) { 46 return true; 47 } 48 if (index == moduleInfo.index && recordName < moduleInfo.recordName) { 49 return true; 50 } 51 if (index == moduleInfo.index && recordName == moduleInfo.recordName && 52 jsPandaFile < moduleInfo.jsPandaFile) { 53 return true; 54 } 55 return false; 56 } 57 }; 58 59 class TSModuleTable : public TaggedArray { 60 public: 61 // Each TSTypeTable occupies three positions 62 static constexpr int ELEMENTS_LENGTH = 4; 63 static constexpr int MODULE_REQUEST_OFFSET = 1; 64 static constexpr int SORT_ID_OFFSET = 2; 65 static constexpr int TYPE_TABLE_OFFSET = 3; 66 static constexpr int ABC_ID_OFFSET = 4; 67 // Reserve a position which is used to store the number of TSTypeTables and a TSTypeTable storage space 68 static constexpr int INITIAL_CAPACITY = ELEMENTS_LENGTH + 1; 69 static constexpr int NUMBER_OF_TABLES_INDEX = 0; 70 static constexpr int INCREASE_CAPACITY_RATE = 2; 71 static constexpr int NOT_FOUND = -1; 72 Cast(TaggedObject * object)73 static TSModuleTable *Cast(TaggedObject *object) 74 { 75 ASSERT(JSTaggedValue(object).IsTaggedArray()); 76 return static_cast<TSModuleTable *>(object); 77 } 78 79 JSHandle<EcmaString> GetModuleRequestByModuleId(JSThread *thread, int entry) const; 80 81 JSHandle<EcmaString> GetAbcRequestByModuleId(JSThread *thread, int entry) const; 82 83 int GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiPath, JSHandle<EcmaString> abcPath) const; 84 GetNumberOfTSTypeTables()85 inline int GetNumberOfTSTypeTables() const 86 { 87 return Get(NUMBER_OF_TABLES_INDEX).GetInt(); 88 } 89 SetNumberOfTSTypeTables(JSThread * thread,int num)90 inline void SetNumberOfTSTypeTables(JSThread *thread, int num) 91 { 92 Set(thread, NUMBER_OF_TABLES_INDEX, JSTaggedValue(num)); 93 } 94 GetTSTypeTableOffset(int entry)95 static uint32_t GetTSTypeTableOffset(int entry) 96 { 97 return entry * ELEMENTS_LENGTH + TYPE_TABLE_OFFSET; 98 } 99 GetModuleRequestOffset(int entry)100 static int GetModuleRequestOffset(int entry) 101 { 102 return entry * ELEMENTS_LENGTH + MODULE_REQUEST_OFFSET; 103 } 104 GetSortIdOffset(int entry)105 static int GetSortIdOffset(int entry) 106 { 107 return entry * ELEMENTS_LENGTH + SORT_ID_OFFSET; 108 } 109 GetAbcRequestOffset(int entry)110 static uint32_t GetAbcRequestOffset(int entry) 111 { 112 return entry * ELEMENTS_LENGTH + ABC_ID_OFFSET; 113 } 114 }; 115 116 class TSManager { 117 public: 118 explicit TSManager(EcmaVM *vm); 119 ~TSManager() = default; 120 121 void Initialize(); 122 123 void Dump(); 124 125 void Iterate(const RootVisitor &v); 126 GetTSModuleTable()127 JSHandle<TSModuleTable> GetTSModuleTable() const 128 { 129 return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_)); 130 } 131 SetTSModuleTable(JSHandle<TSModuleTable> table)132 void SetTSModuleTable(JSHandle<TSModuleTable> table) 133 { 134 globalModuleTable_ = table.GetTaggedValue(); 135 } 136 137 JSHandle<TSTypeTable> GetTSTypeTable(int entry) const; 138 139 void SetTSTypeTable(const JSHandle<TSTypeTable> &table, int tableId) const; 140 141 void GenerateBuiltinSummary(); 142 GetBuiltinOffset(uint32_t index)143 inline uint32_t GetBuiltinOffset(uint32_t index) const 144 { 145 if (index == static_cast<uint32_t>(BuiltinTypeId::NUM_INDEX_IN_SUMMARY)) { 146 return builtinOffsets_[index]; 147 } 148 return builtinOffsets_[index - static_cast<uint32_t>(BuiltinTypeId::BUILTIN_OFFSET)]; 149 } 150 GetPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName)151 inline GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSTaggedValue propertyName) const 152 { 153 return GetPropType(gt, JSHandle<JSTaggedValue>(thread_, propertyName)); 154 } 155 156 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, const uint64_t key) const; 157 158 GlobalTSTypeRef PUBLIC_API GetIndexSignType(GlobalTSTypeRef objType, kungfu::GateType indexType) const; 159 CreateClassInstanceType(kungfu::GateType gateType)160 inline GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(kungfu::GateType gateType) 161 { 162 GlobalTSTypeRef gt = gateType.GetGTRef(); 163 return CreateClassInstanceType(gt); 164 } 165 166 GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(GlobalTSTypeRef gt); 167 GetClassType(kungfu::GateType gateType)168 inline GlobalTSTypeRef PUBLIC_API GetClassType(kungfu::GateType gateType) 169 { 170 GlobalTSTypeRef gt = gateType.GetGTRef(); 171 return GetClassType(gt); 172 } 173 174 GlobalTSTypeRef PUBLIC_API GetClassType(GlobalTSTypeRef classInstanceGT) const; 175 176 JSHandle<TSClassType> GetExtendedClassType(JSHandle<TSClassType> classType) const; 177 178 TSClassType* GetExtendedClassType(const TSClassType *classType) const; 179 180 uint32_t PUBLIC_API GetUnionTypeLength(GlobalTSTypeRef gt) const; 181 182 GlobalTSTypeRef PUBLIC_API GetUnionTypeByIndex(GlobalTSTypeRef gt, int index) const; 183 184 GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec); 185 186 uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const; 187 188 GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt); 189 190 GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const; 191 GetIteratorInstanceElementGt(kungfu::GateType gateType)192 inline GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(kungfu::GateType gateType) const 193 { 194 GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetGTRef()); 195 return GetIteratorInstanceElementGt(gt); 196 } 197 198 bool PUBLIC_API IsStaticFunc(GlobalTSTypeRef gt) const; 199 200 bool PUBLIC_API IsHotnessFunc(GlobalTSTypeRef gt) const; 201 202 void PUBLIC_API SetHotnessFunc(GlobalTSTypeRef gt, bool isHotness) const; 203 204 bool PUBLIC_API GetSuperGateType(kungfu::GateType &gateType) const; 205 206 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 207 JSHandle<JSTaggedValue> propertyName, 208 PropertyType propType) const; 209 GetSuperPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName,PropertyType propType)210 inline GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 211 JSTaggedValue propertyName, 212 PropertyType propType) const 213 { 214 return GetSuperPropType(gt, JSHandle<JSTaggedValue>(vm_->GetJSThread(), propertyName), 215 propType); 216 } 217 218 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 219 const uint64_t key, 220 PropertyType propType) const; 221 222 GlobalTSTypeRef PUBLIC_API GetFuncParameterTypeGT(GlobalTSTypeRef gt, int index) const; 223 224 GlobalTSTypeRef PUBLIC_API GetFuncThisGT(GlobalTSTypeRef gt) const; 225 226 void PUBLIC_API SetFuncMethodOffset(GlobalTSTypeRef gt, uint32_t methodOffset); 227 228 uint32_t PUBLIC_API GetFuncMethodOffset(GlobalTSTypeRef gt) const; 229 230 bool PUBLIC_API IsGetterSetterFunc(GlobalTSTypeRef gt) const; 231 232 bool IsAbstractMethod(GlobalTSTypeRef gt) const; 233 234 bool IsMethodSignature(GlobalTSTypeRef gt) const; 235 bool CanFastCall(GlobalTSTypeRef gt) const; 236 bool IsNoGC(GlobalTSTypeRef gt) const; 237 bool MethodOffsetIsVaild(GlobalTSTypeRef gt) const; 238 bool FastCallFlagIsVaild(GlobalTSTypeRef gt) const; 239 GetFuncReturnValueTypeGT(kungfu::GateType gateType)240 inline GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(kungfu::GateType gateType) const 241 { 242 GlobalTSTypeRef gt = gateType.GetGTRef(); 243 return GetFuncReturnValueTypeGT(gt); 244 } 245 246 GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(GlobalTSTypeRef gt) const; 247 248 std::string PUBLIC_API GetFuncName(kungfu::GateType gt) const; 249 250 int PUBLIC_API GetMethodIndex(GlobalTSTypeRef gt) const; 251 GetArrayParameterTypeGT(kungfu::GateType gateType)252 inline GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(kungfu::GateType gateType) const 253 { 254 GlobalTSTypeRef gt = gateType.GetGTRef(); 255 return GetArrayParameterTypeGT(gt); 256 } 257 258 GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const; 259 AssertTypes()260 bool PUBLIC_API AssertTypes() const 261 { 262 return assertTypes_; 263 } 264 GetTypeThreshold()265 double PUBLIC_API GetTypeThreshold() const 266 { 267 return typeThreshold_; 268 } 269 IsBuiltinsDTSEnabled()270 bool IsBuiltinsDTSEnabled() const 271 { 272 return vm_->GetJSOptions().WasSetBuiltinsDTS(); 273 } 274 GetBuiltinsDTS()275 CString GetBuiltinsDTS() const 276 { 277 std::string fileName = vm_->GetJSOptions().GetBuiltinsDTS(); 278 return CString(fileName); 279 } 280 281 void AddInstanceTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &ihclass); 282 283 void AddConstructorTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &constructorHClass); 284 285 JSTaggedValue GetInstanceTSHClass(const JSHandle<TSClassType> &classType) const; 286 287 bool HasTSHClass(const JSHandle<TSClassType> &classType) const; 288 289 bool HasTSHClass(const TSClassType *classType) const; 290 291 JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef >) const; 292 293 std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const; 294 295 int PUBLIC_API GetHClassIndexByObjectType(const kungfu::GateType &gateType); 296 297 int PUBLIC_API GetHClassIndexByInstanceGateType(const kungfu::GateType &gateType); 298 299 int PUBLIC_API GetConstructorHClassIndexByClassGateType(const kungfu::GateType &gateType); 300 301 int PUBLIC_API GetHClassIndexByClassGateType(const kungfu::GateType &gateType); 302 303 JSTaggedValue GetTSHClass(const kungfu::GateType &gateType) const; 304 305 JSTaggedValue PUBLIC_API GetAOTHClassInfoByIndex(uint32_t index); 306 307 GlobalTSTypeRef PUBLIC_API CreateArrayType(); 308 309 GlobalTSTypeRef PUBLIC_API CreateNamespaceType(); 310 311 bool AddNamespacePropType(kungfu::GateType objType, JSTaggedValue name, kungfu::GateType valueType); 312 IsUserDefinedClassTypeKind(const kungfu::GateType & gateType)313 inline bool IsUserDefinedClassTypeKind(const kungfu::GateType &gateType) const 314 { 315 GlobalTSTypeRef gt = gateType.GetGTRef(); 316 return IsUserDefinedClassTypeKind(gt); 317 } 318 IsUserDefinedClassTypeKind(const GlobalTSTypeRef & gt)319 inline bool IsUserDefinedClassTypeKind(const GlobalTSTypeRef >) const 320 { 321 return IsClassTypeKind(gt) && (!gt.IsBuiltinModule()); 322 } 323 StoreNamespaceType(const uint32_t methodOffset,const kungfu::GateType type)324 inline void StoreNamespaceType(const uint32_t methodOffset, const kungfu::GateType type) 325 { 326 methodOffsetToType_.insert(std::make_pair(methodOffset, type)); 327 } 328 GetNamespaceObjType(const uint32_t methodOffset)329 inline kungfu::GateType GetNamespaceObjType(const uint32_t methodOffset) const 330 { 331 ASSERT(HasInferredNamespaceType(methodOffset)); 332 return methodOffsetToType_.at(methodOffset); 333 } 334 HasInferredNamespaceType(const uint32_t methodOffset)335 inline bool HasInferredNamespaceType(const uint32_t methodOffset) const 336 { 337 return methodOffsetToType_.find(methodOffset) != methodOffsetToType_.end(); 338 } 339 GetEcmaVM()340 EcmaVM *GetEcmaVM() const 341 { 342 return vm_; 343 } 344 GetThread()345 JSThread *GetThread() const 346 { 347 return thread_; 348 } 349 350 #define IS_TSTYPEKIND_METHOD_LIST(V) \ 351 V(Primitive, TSTypeKind::PRIMITIVE) \ 352 V(Class, TSTypeKind::CLASS) \ 353 V(ClassInstance, TSTypeKind::CLASS_INSTANCE) \ 354 V(Function, TSTypeKind::FUNCTION) \ 355 V(Union, TSTypeKind::UNION) \ 356 V(Array, TSTypeKind::ARRAY) \ 357 V(Object, TSTypeKind::OBJECT) \ 358 V(Import, TSTypeKind::IMPORT) \ 359 V(Interface, TSTypeKind::INTERFACE) \ 360 V(IteratorInstance, TSTypeKind::ITERATOR_INSTANCE) \ 361 V(Namespace, TSTypeKind::NAMESPACE) 362 363 #define IS_TSTYPEKIND(NAME, TSTYPEKIND) \ 364 inline bool PUBLIC_API Is##NAME##TypeKind(const kungfu::GateType &gateType) const \ 365 { \ 366 GlobalTSTypeRef gt = gateType.GetGTRef(); \ 367 return GetTypeKind(gt) == (TSTYPEKIND); \ 368 } \ 369 \ 370 inline bool PUBLIC_API Is##NAME##TypeKind(const GlobalTSTypeRef >) const \ 371 { \ 372 return GetTypeKind(gt) == (TSTYPEKIND); \ 373 } 374 375 IS_TSTYPEKIND_METHOD_LIST(IS_TSTYPEKIND) 376 #undef IS_TSTYPEKIND 377 378 bool PUBLIC_API IsBuiltinClassType(BuiltinTypeId id, kungfu::GateType gateType) const; 379 380 bool PUBLIC_API IsBuiltinInstanceType(BuiltinTypeId id, kungfu::GateType gateType) const; 381 382 bool PUBLIC_API IsTypedArrayType(kungfu::GateType gateType) const; 383 384 bool PUBLIC_API IsValidTypedArrayType(kungfu::GateType gateType) const; 385 IsBuiltinObjectType(kungfu::GateType gateType)386 inline bool PUBLIC_API IsBuiltinObjectType(kungfu::GateType gateType) const 387 { 388 return gateType.GetGTRef().IsBuiltinModule() && IsClassTypeKind(gateType); 389 } 390 391 bool PUBLIC_API IsIntTypedArrayType(kungfu::GateType gateType) const; 392 393 bool PUBLIC_API IsDoubleTypedArrayType(kungfu::GateType gateType) const; 394 395 BuiltinTypeId PUBLIC_API GetTypedArrayBuiltinId(kungfu::GateType gateType) const; 396 397 static const std::vector<BuiltinTypeId> &GetValidTypedArrayIds(); 398 399 inline void AddElementToIdGTMap(const GlobalTypeID &id, GlobalTSTypeRef gt, 400 const CString &recordName = "", bool isImportType = false) 401 { 402 auto it = idGTMap_.find(id); 403 if (it != idGTMap_.end()) { 404 it->second = gt; 405 } else { 406 idGTMap_.emplace(id, gt); 407 } 408 if (!isImportType && !id.IsPGOType()) { 409 auto value = std::make_tuple(id.GetJSPandaFile()->GetNormalizedFileDesc(), recordName, id.GetTypeId()); 410 gtLiteralOffsetMap_.emplace(gt, value); 411 } 412 } 413 HasCreatedGT(const GlobalTypeID & id)414 inline bool HasCreatedGT(const GlobalTypeID &id) const 415 { 416 return idGTMap_.find(id) != idGTMap_.end(); 417 } 418 GetGTByGlobalTypeID(const GlobalTypeID & id)419 inline GlobalTSTypeRef GetGTByGlobalTypeID(const GlobalTypeID &id) const 420 { 421 return idGTMap_.at(id); 422 } 423 HasOffsetFromGT(GlobalTSTypeRef gt)424 inline bool HasOffsetFromGT(GlobalTSTypeRef gt) const 425 { 426 return gtLiteralOffsetMap_.find(gt) != gtLiteralOffsetMap_.end(); 427 } 428 GetOffsetFromGt(GlobalTSTypeRef gt)429 inline std::tuple<CString, CString, uint32_t> GetOffsetFromGt(GlobalTSTypeRef gt) const 430 { 431 return gtLiteralOffsetMap_.at(gt); 432 } 433 AddTypeToModuleVarGtMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index,GlobalTSTypeRef gt)434 inline void AddTypeToModuleVarGtMap(const JSPandaFile *jsPandaFile, const CString &recordName, 435 uint32_t index, GlobalTSTypeRef gt) 436 { 437 ModuleInfo key = {jsPandaFile, recordName, index}; 438 if (moduleVarGtMap_.find(key) == moduleVarGtMap_.end()) { 439 moduleVarGtMap_.emplace(key, gt); 440 } else { 441 moduleVarGtMap_[key] = gt; 442 } 443 } 444 HasExportGT(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)445 inline bool HasExportGT(const JSPandaFile *jsPandaFile, const CString &recordName, 446 uint32_t index) const 447 { 448 ModuleInfo key = {jsPandaFile, recordName, index}; 449 return moduleVarGtMap_.find(key) != moduleVarGtMap_.end(); 450 } 451 GetGTFromModuleMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)452 inline GlobalTSTypeRef GetGTFromModuleMap(const JSPandaFile *jsPandaFile, const CString &recordName, 453 uint32_t index) const 454 { 455 ModuleInfo key = {jsPandaFile, recordName, index}; 456 return moduleVarGtMap_.at(key); 457 } 458 AddResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName,JSTaggedValue exportTable)459 inline void AddResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName, 460 JSTaggedValue exportTable) 461 { 462 auto key = std::make_pair(jsPandaFile, recordName); 463 if (resolvedExportTable_.find(key) == resolvedExportTable_.end()) { 464 resolvedExportTable_.emplace(key, exportTable); 465 } else { 466 resolvedExportTable_[key] = exportTable; 467 } 468 } 469 HasResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)470 inline bool HasResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const 471 { 472 auto key = std::make_pair(jsPandaFile, recordName); 473 return resolvedExportTable_.find(key) != resolvedExportTable_.end(); 474 } 475 GetResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)476 inline JSTaggedValue GetResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const 477 { 478 auto key = std::make_pair(jsPandaFile, recordName); 479 return resolvedExportTable_.at(key); 480 } 481 IsTSIterator(GlobalTSTypeRef gt)482 bool IsTSIterator(GlobalTSTypeRef gt) const 483 { 484 uint32_t l = gt.GetLocalId(); 485 return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR)); 486 } 487 IsTSIteratorResult(GlobalTSTypeRef gt)488 bool IsTSIteratorResult(GlobalTSTypeRef gt) const 489 { 490 uint32_t l = gt.GetLocalId(); 491 return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR_RESULT)); 492 } 493 494 void PUBLIC_API SetCurConstantPool(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 495 496 int32_t PUBLIC_API GetConstantPoolIDByMethodOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 497 498 uint32_t GetConstantPoolId(uint32_t methodId) const; 499 JSTaggedValue GetConstantPool(uint32_t methodId) const; 500 GetConstantPool()501 JSHandle<JSTaggedValue> PUBLIC_API GetConstantPool() const 502 { 503 return JSHandle<JSTaggedValue>(uintptr_t(&curCP_)); 504 } 505 506 JSTaggedValue PUBLIC_API GetStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const; 507 GetStdStringFromConstantPool(uint32_t methodId,const uint16_t stringId)508 inline std::string PUBLIC_API GetStdStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const 509 { 510 JSTaggedValue str = GetStringFromConstantPool(methodId, stringId); 511 return EcmaStringAccessor(str).ToStdString(StringConvertedUsage::LOGICOPERATION); 512 } 513 514 bool PUBLIC_API IsBuiltinObjectMethod(BuiltinTypeId id, kungfu::GateType funcType) const; 515 bool PUBLIC_API IsBuiltinConstructor(BuiltinTypeId id, GlobalTSTypeRef ctorType) const; 516 GetBuiltinPandaFile()517 inline const JSPandaFile *GetBuiltinPandaFile() const 518 { 519 return builtinPandaFile_; 520 } 521 GetBuiltinRecordName()522 inline const CString &GetBuiltinRecordName() const 523 { 524 return builtinsRecordName_; 525 } 526 GetBytecodeInfoCollector()527 inline kungfu::BytecodeInfoCollector *GetBytecodeInfoCollector() const 528 { 529 return bcInfoCollector_; 530 } 531 SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector * bcInfoCollector)532 inline void SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector *bcInfoCollector) 533 { 534 bcInfoCollector_ = bcInfoCollector; 535 } 536 537 class IHClassData { 538 public: IHClassData(JSTaggedType ihc)539 explicit IHClassData(JSTaggedType ihc) : ihc_(ihc) {} 540 Iterate(const RootVisitor & v)541 void Iterate(const RootVisitor &v) 542 { 543 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&ihc_))); 544 } 545 GetCPIndexMap()546 std::unordered_map<int32_t, uint32_t>& GetCPIndexMap() 547 { 548 return cpIndexMap_; 549 } 550 GetIHC()551 JSTaggedType GetIHC() const 552 { 553 return ihc_; 554 } 555 556 private: 557 JSTaggedType ihc_ {0}; 558 std::unordered_map<int32_t, uint32_t> cpIndexMap_ {}; 559 }; 560 SetCompilationDriver(kungfu::CompilationDriver * cmpDriver)561 void SetCompilationDriver(kungfu::CompilationDriver *cmpDriver) 562 { 563 cmpDriver_ = cmpDriver; 564 } 565 GetCompilationDriver()566 kungfu::CompilationDriver *GetCompilationDriver() const 567 { 568 return cmpDriver_; 569 } 570 AddElementToClassNameMap(const JSPandaFile * jsPandaFile,uint32_t offset,std::string className)571 void AddElementToClassNameMap(const JSPandaFile *jsPandaFile, uint32_t offset, std::string className) 572 { 573 literalOffsetClassNameMap_.emplace(std::make_pair(jsPandaFile, offset), className); 574 } 575 GetClassNameByOffset(const JSPandaFile * jsPandaFile,uint32_t typeId)576 const std::string GetClassNameByOffset(const JSPandaFile *jsPandaFile, uint32_t typeId) const 577 { 578 std::pair<const JSPandaFile *, uint32_t> pair = std::make_pair(jsPandaFile, typeId); 579 std::string name = ""; 580 if (literalOffsetClassNameMap_.find(pair) != literalOffsetClassNameMap_.end()) { 581 name = literalOffsetClassNameMap_.at(pair); 582 } 583 return name; 584 } 585 CollectGT(GlobalTSTypeRef gt)586 inline void CollectGT(GlobalTSTypeRef gt) 587 { 588 if (IsClassTypeKind(gt)) { 589 collectedGT_.insert(gt); 590 } 591 } 592 GetCollectedGT()593 inline std::set<GlobalTSTypeRef>& GetCollectedGT() 594 { 595 return collectedGT_; 596 } 597 InsertLiteralGTMap(TypeLocation & loc,GlobalTSTypeRef gt)598 inline void InsertLiteralGTMap(TypeLocation &loc, GlobalTSTypeRef gt) 599 { 600 literalGTMap_[loc] = gt; 601 } 602 GetLiteralGT(TypeLocation & loc)603 inline GlobalTSTypeRef GetLiteralGT(TypeLocation &loc) 604 { 605 auto it = literalGTMap_.find(loc); 606 if (it != literalGTMap_.end()) { 607 return it->second; 608 } 609 return GlobalTSTypeRef::Default(); 610 } 611 InsertPtToGtMap(ProfileType pgoType,const kungfu::GateType & gateType)612 inline void InsertPtToGtMap(ProfileType pgoType, const kungfu::GateType &gateType) 613 { 614 ptToGtMap_.emplace(pgoType, gateType); 615 } 616 GetGateTypeByPt(ProfileType pgoType)617 inline const kungfu::GateType GetGateTypeByPt(ProfileType pgoType) 618 { 619 if (pgoType.IsBuiltinsType()) { 620 return GetBuiltinsGateTypeByPt(pgoType); 621 } 622 auto it = ptToGtMap_.find(pgoType); 623 if (it != ptToGtMap_.end()) { 624 return it->second; 625 } 626 return kungfu::GateType::AnyType(); 627 } 628 629 void PrintNumOfTypes() const; 630 631 void PrintTypeInfo(const JSPandaFile *jsPandaFile) const; 632 633 kungfu::GateType TryNarrowUnionType(kungfu::GateType gateType); 634 635 JSHandle<TaggedArray> GetExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName); 636 637 int GetHClassIndex(GlobalTSTypeRef classGT, bool isConstructor = false); 638 GetPGOGTCountByRecordName(const CString & recordName)639 uint32_t GetPGOGTCountByRecordName(const CString &recordName) const 640 { 641 if (bcInfoCollector_ == nullptr) { 642 return 0; 643 } 644 const kungfu::PGOBCInfo *bcInfo = bcInfoCollector_->GetPGOBCInfo(); 645 return bcInfo->GetPGOExtendGTCount(recordName); 646 } 647 GetBuiltinsName(GlobalTSTypeRef builtinGT)648 inline std::string GetBuiltinsName(GlobalTSTypeRef builtinGT) const 649 { 650 uint32_t index = GetBuiltinIndex(builtinGT); 651 return GetBuiltinsName(index); 652 } 653 654 TSTypeKind PUBLIC_API GetTypeKind(const GlobalTSTypeRef >) const; 655 656 #define TSTYPETABLE_ACCESSOR_LIST(V) \ 657 V(Builtin, ModuleTableIdx::BUILTIN) \ 658 V(Inferred, ModuleTableIdx::INFERRED) \ 659 V(Runtime, ModuleTableIdx::RUNTIME) \ 660 V(Generics, ModuleTableIdx::GENERICS) 661 662 #define TSTYPETABLE_ACCESSOR(NAME, MODULEID) \ 663 inline GlobalTSTypeRef AddTSTypeTo##NAME##Table(const JSHandle<TSType> &type) const \ 664 { \ 665 return AddTSTypeToTypeTable(type, static_cast<uint32_t>(MODULEID)); \ 666 } \ 667 \ 668 inline JSHandle<TSTypeTable> Get##NAME##Table() const \ 669 { \ 670 return GetTSTypeTable(static_cast<uint32_t>(MODULEID)); \ 671 } \ 672 \ 673 inline void Set##NAME##Table(const JSHandle<TSTypeTable> &table) \ 674 { \ 675 SetTSTypeTable(table, static_cast<uint32_t>(MODULEID)); \ 676 } 677 678 TSTYPETABLE_ACCESSOR_LIST(TSTYPETABLE_ACCESSOR) 679 #undef TSTYPETABLE_ACCESSOR 680 681 private: 682 NO_COPY_SEMANTIC(TSManager); 683 NO_MOVE_SEMANTIC(TSManager); 684 685 GlobalTSTypeRef AddTSTypeToTypeTable(const JSHandle<TSType> &type, int tableId) const; 686 687 JSHandle<TaggedArray> GenerateExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName); 688 689 GlobalTSTypeRef FindUnionInTypeTable(JSHandle<TSTypeTable> table, JSHandle<TSUnionType> unionType) const; 690 691 GlobalTSTypeRef FindIteratorInstanceInInferTable(GlobalTSTypeRef kindGt, GlobalTSTypeRef elementGt) const; 692 693 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSHandle<JSTaggedValue> propertyName) const; 694 695 std::string GetClassTypeStr(GlobalTSTypeRef gt) const; 696 697 std::string GetClassInstanceTypeStr(GlobalTSTypeRef gt) const; 698 699 std::string GetFunctionTypeStr(GlobalTSTypeRef gt) const; 700 701 std::string GetArrayTypeStr(GlobalTSTypeRef gt) const; 702 703 std::string GetPrimitiveStr(const GlobalTSTypeRef >) const; 704 705 uint32_t RecordIhcToVecAndIndexMap(IHClassData &ihcData); 706 707 uint32_t GetBuiltinIndex(GlobalTSTypeRef builtinGT) const; 708 709 std::string GetBuiltinsName(uint32_t index) const; 710 SetBuiltinPandaFile(JSPandaFile * jsPandaFile)711 inline void SetBuiltinPandaFile(JSPandaFile *jsPandaFile) 712 { 713 builtinPandaFile_ = jsPandaFile; 714 } 715 SetBuiltinRecordName(CString & builtinsRecordName)716 inline void SetBuiltinRecordName(CString &builtinsRecordName) 717 { 718 builtinsRecordName_ = builtinsRecordName; 719 } 720 721 // for jsarray 722 void TryGetElmsKind(panda_file::File::EntityId id, JSHandle<JSTaggedValue> &ekd); 723 724 const kungfu::GateType GetBuiltinsGateTypeByPt(ProfileType pgoType); 725 726 BuiltinTypeId GetBuiltinTypeIdByJSType(JSType jsType); 727 728 EcmaVM *vm_ {nullptr}; 729 JSThread *thread_ {nullptr}; 730 ObjectFactory *factory_ {nullptr}; 731 // kungfu::PGOTypeManager ptManager_; 732 JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()}; 733 CMap<ProfileType, const kungfu::GateType> ptToGtMap_ {}; 734 std::map<GlobalTSTypeRef, IHClassData> gtIhcMap_ {}; 735 std::map<GlobalTSTypeRef, IHClassData> gtConstructorhcMap_ {}; 736 std::unordered_map<TypeLocation, GlobalTSTypeRef, HashTypeLocation> literalGTMap_ {}; 737 std::map<JSType, GlobalTSTypeRef> pgoBuiltinGTCache_ {}; 738 bool assertTypes_ {false}; 739 double typeThreshold_ {-1}; 740 741 // when the passmanager iterates each method, the curCP_ and curCPID_ should be updated 742 // so that subsequent passes (type_infer, type_bytecode_lowering) can obtain the correct constpool. 743 JSTaggedValue curCP_ {JSTaggedValue::Hole()}; 744 int32_t curCPID_ {0}; 745 const JSPandaFile *curJSPandaFile_ {nullptr}; 746 747 std::unordered_map<GlobalTypeID, GlobalTSTypeRef, HashGlobalTypeID> idGTMap_ {}; 748 std::map<GlobalTSTypeRef, std::tuple<CString, CString, uint32_t>> gtLiteralOffsetMap_ {}; 749 std::vector<uint32_t> builtinOffsets_ {}; 750 JSPandaFile *builtinPandaFile_ {nullptr}; 751 CString builtinsRecordName_ {""}; 752 std::map<ModuleInfo, GlobalTSTypeRef> moduleVarGtMap_{}; 753 kungfu::CompilationDriver *cmpDriver_ {nullptr}; 754 std::set<GlobalTSTypeRef> collectedGT_ {}; // use for storing types that need to generate hclasses 755 756 friend class EcmaVM; 757 friend class TSTypeAccessor; 758 759 std::map<std::pair<const JSPandaFile *, uint32_t>, std::string> literalOffsetClassNameMap_ {}; 760 kungfu::BytecodeInfoCollector *bcInfoCollector_ {nullptr}; 761 // use for collect the literal of export type table. 762 CMap<std::pair<const JSPandaFile *, CString>, JSTaggedValue> resolvedExportTable_ {}; 763 CMap<uint32_t, kungfu::GateType> methodOffsetToType_ {}; 764 }; 765 } // namespace panda::ecmascript 766 767 #endif // ECMASCRIPT_TS_TYPES_TS_MANAGER_H 768