1 /* 2 * Copyright (c) 2023-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 16 #ifndef ECMASCRIPT_PGO_PROFILER_LAYOUT_H 17 #define ECMASCRIPT_PGO_PROFILER_LAYOUT_H 18 19 #include <cstdint> 20 #include <string> 21 22 #include "ecmascript/ecma_vm.h" 23 #include "ecmascript/elements.h" 24 #include "ecmascript/js_hclass.h" 25 #include "ecmascript/js_object.h" 26 #include "ecmascript/log_wrapper.h" 27 #include "ecmascript/mem/c_containers.h" 28 #include "ecmascript/mem/region.h" 29 #include "ecmascript/pgo_profiler/pgo_context.h" 30 #include "ecmascript/pgo_profiler/pgo_utils.h" 31 #include "ecmascript/pgo_profiler/types/pgo_profile_type.h" 32 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 33 #include "ecmascript/property_attributes.h" 34 35 namespace panda::ecmascript::pgo { 36 class PGOHandler { 37 public: 38 using TrackTypeField = 39 PropertyAttributes::PropertyMetaDataField::NextField<TrackType, PropertyAttributes::TRACK_TYPE_NUM>; 40 using IsSymbol = TrackTypeField::NextFlag; 41 PGOHandler()42 PGOHandler() 43 { 44 SetTrackType(TrackType::NONE); 45 SetPropertyMeta(false); 46 } 47 PGOHandler(TrackType type,int meta)48 PGOHandler(TrackType type, int meta) 49 { 50 SetTrackType(type); 51 SetPropertyMeta(meta); 52 } 53 PGOHandler(TrackType type,int meta,bool isSymbol)54 PGOHandler(TrackType type, int meta, bool isSymbol) 55 { 56 SetTrackType(type); 57 SetPropertyMeta(meta); 58 SetIsSymbol(isSymbol); 59 } 60 GetValue()61 uint32_t GetValue() const 62 { 63 return value_; 64 } 65 66 bool SetAttribute(const JSThread *thread, PropertyAttributes &attr) const; 67 SetIsSymbol(bool isSymbol)68 void SetIsSymbol(bool isSymbol) 69 { 70 IsSymbol::Set(isSymbol, &value_); 71 } 72 GetIsSymbol()73 bool GetIsSymbol() const 74 { 75 return IsSymbol::Get(value_); 76 } 77 SetTrackType(TrackType type)78 void SetTrackType(TrackType type) 79 { 80 TrackTypeField::Set(type, &value_); 81 } 82 GetTrackType()83 TrackType GetTrackType() const 84 { 85 return TrackTypeField::Get(value_); 86 } 87 SetPropertyMeta(int meta)88 void SetPropertyMeta(int meta) 89 { 90 PropertyAttributes::PropertyMetaDataField::Set(meta, &value_); 91 } 92 GetPropertyMeta()93 int GetPropertyMeta() const 94 { 95 return PropertyAttributes::PropertyMetaDataField::Get(value_); 96 } 97 IsAccessor()98 bool IsAccessor() const 99 { 100 return PropertyAttributes::IsAccessorField::Get(value_); 101 } 102 IsWritable()103 bool IsWritable() const 104 { 105 return PropertyAttributes::WritableField::Get(value_); 106 } 107 IsEnumerable()108 bool IsEnumerable() const 109 { 110 return PropertyAttributes::EnumerableField::Get(value_); 111 } 112 IsConfigurable()113 bool IsConfigurable() const 114 { 115 return PropertyAttributes::ConfigurableField::Get(value_); 116 } 117 118 bool operator!=(const PGOHandler &right) const 119 { 120 return value_ != right.value_; 121 } 122 123 bool operator==(const PGOHandler &right) const 124 { 125 return value_ == right.value_; 126 } 127 128 private: 129 uint32_t value_ { 0 }; 130 }; 131 132 using PropertyDesc = std::pair<CString, PGOHandler>; 133 using LayoutDesc = CVector<PropertyDesc>; 134 class PGOHClassTreeDesc; 135 136 class HClassLayoutDesc { 137 public: HClassLayoutDesc(ProfileType type)138 explicit HClassLayoutDesc(ProfileType type) : type_(type) {} HClassLayoutDesc(ProfileType type,const CSet<ProfileType> & childs)139 HClassLayoutDesc(ProfileType type, const CSet<ProfileType> &childs) : type_(type), childs_(childs) {} 140 virtual ~HClassLayoutDesc() = default; 141 142 virtual void Merge(const HClassLayoutDesc *from); 143 virtual void InsertKeyAndDesc(const CString &key, const PGOHandler &handler) = 0; 144 virtual bool UpdateKeyAndDesc(const CString &key, const PGOHandler &handler) = 0; 145 virtual bool IsRoot() const = 0; 146 GetProfileType()147 ProfileType GetProfileType() const 148 { 149 return type_; 150 } 151 AddChildHClassLayoutDesc(const ProfileType & type)152 void AddChildHClassLayoutDesc(const ProfileType &type) 153 { 154 if (type_.GetRaw() == type.GetRaw()) { 155 return; 156 } 157 childs_.emplace(type); 158 } 159 FindChild(const ProfileType & type)160 bool FindChild(const ProfileType &type) 161 { 162 return childs_.find(type) != childs_.end(); 163 } 164 GetChildSize()165 inline size_t GetChildSize() const 166 { 167 return childs_.size(); 168 } 169 170 template<typename Callback> IterateChilds(Callback callback)171 void IterateChilds(Callback callback) const 172 { 173 for (const auto &type : childs_) { 174 if (!callback(type)) { 175 break; 176 } 177 } 178 } 179 180 protected: 181 void InsertKeyAndDesc(const PGOHandler &handler, PropertyDesc &desc); 182 183 ProfileType type_; 184 CSet<ProfileType> childs_; 185 }; 186 187 class RootHClassLayoutDesc final : public HClassLayoutDesc { 188 public: RootHClassLayoutDesc(ProfileType type)189 explicit RootHClassLayoutDesc(ProfileType type) : HClassLayoutDesc(type) {} RootHClassLayoutDesc(ProfileType type,JSType objType,uint32_t objSize)190 RootHClassLayoutDesc(ProfileType type, JSType objType, uint32_t objSize) 191 : HClassLayoutDesc(type), objType_(objType), objSize_(objSize) {} RootHClassLayoutDesc(const RootHClassLayoutDesc & desc)192 RootHClassLayoutDesc(const RootHClassLayoutDesc &desc) 193 : HClassLayoutDesc(desc.type_, desc.childs_), objType_(desc.objType_), objSize_(desc.objSize_), 194 layoutDesc_(desc.layoutDesc_) {} 195 RootHClassLayoutDesc& operator=(const RootHClassLayoutDesc &desc) 196 { 197 this->type_ = desc.type_; 198 this->childs_ = desc.childs_; 199 this->objType_ = desc.objType_; 200 this->objSize_ = desc.objSize_; 201 this->layoutDesc_ = desc.layoutDesc_; 202 return *this; 203 } 204 205 void Merge(const HClassLayoutDesc *from) override; 206 void InsertKeyAndDesc(const CString &key, const PGOHandler &handler) override; 207 bool UpdateKeyAndDesc(const CString &key, const PGOHandler &handler) override; 208 IsRoot()209 bool IsRoot() const override 210 { 211 return true; 212 } 213 SetObjectSize(uint32_t objSize)214 void SetObjectSize(uint32_t objSize) 215 { 216 objSize_ = objSize; 217 } 218 GetObjectSize()219 uint32_t GetObjectSize() const 220 { 221 return objSize_; 222 } 223 SetObjectType(JSType objType)224 void SetObjectType(JSType objType) 225 { 226 objType_ = objType; 227 } 228 GetObjectType()229 JSType GetObjectType() const 230 { 231 return objType_; 232 } 233 NumOfProps()234 size_t NumOfProps() const 235 { 236 return layoutDesc_.size(); 237 } 238 239 template<typename Callback> IterateProps(Callback callback)240 void IterateProps(Callback callback) const 241 { 242 for (const auto &iter : layoutDesc_) { 243 callback(iter); 244 } 245 } 246 247 private: 248 JSType objType_; 249 uint32_t objSize_ {0}; 250 LayoutDesc layoutDesc_; 251 }; 252 253 class ChildHClassLayoutDesc final : public HClassLayoutDesc { 254 public: ChildHClassLayoutDesc(ProfileType type)255 explicit ChildHClassLayoutDesc(ProfileType type) : HClassLayoutDesc(type) {} ChildHClassLayoutDesc(const ChildHClassLayoutDesc & desc)256 ChildHClassLayoutDesc(const ChildHClassLayoutDesc &desc) 257 : HClassLayoutDesc(desc.type_, desc.childs_), propertyDesc_(desc.propertyDesc_) {} 258 ChildHClassLayoutDesc& operator=(const ChildHClassLayoutDesc &desc) 259 { 260 this->type_ = desc.type_; 261 this->childs_ = desc.childs_; 262 this->propertyDesc_ = desc.propertyDesc_; 263 return *this; 264 } 265 266 void Merge(const HClassLayoutDesc *from) override; 267 void InsertKeyAndDesc(const CString &key, const PGOHandler &handler) override; 268 bool UpdateKeyAndDesc(const CString &key, const PGOHandler &handler) override; 269 IsRoot()270 bool IsRoot() const override 271 { 272 return false; 273 } 274 GetPropertyDesc()275 PropertyDesc GetPropertyDesc() const 276 { 277 return propertyDesc_; 278 } 279 280 private: 281 PropertyDesc propertyDesc_; 282 }; 283 284 class PGOHClassTreeDesc { 285 public: 286 PGOHClassTreeDesc() = default; PGOHClassTreeDesc(ProfileType type)287 explicit PGOHClassTreeDesc(ProfileType type) : type_(type) {} 288 289 void Clear(); 290 GetProfileType()291 ProfileType GetProfileType() const 292 { 293 return type_; 294 } 295 SetProtoPt(ProfileType protoPt)296 void SetProtoPt(ProfileType protoPt) 297 { 298 protoPt_ = protoPt; 299 } 300 GetProtoPt()301 ProfileType GetProtoPt() const 302 { 303 return protoPt_; 304 } 305 306 void Merge(const PGOHClassTreeDesc &from); 307 308 bool operator<(const PGOHClassTreeDesc &right) const 309 { 310 return type_ < right.type_; 311 } 312 313 HClassLayoutDesc *GetHClassLayoutDesc(ProfileType type) const; 314 HClassLayoutDesc *GetOrInsertHClassLayoutDesc(ProfileType type, bool root = false); 315 316 bool DumpForRoot(const JSThread *thread, JSTaggedType root, ProfileType rootType); 317 bool DumpForChild(const JSThread *thread, JSTaggedType child, ProfileType childType); 318 bool UpdateForTransition(const JSThread *thread, JSTaggedType parent, ProfileType parentType, 319 JSTaggedType child, ProfileType childType); 320 bool UpdateLayout(const JSThread *thread, JSTaggedType curHClass, ProfileType curType); 321 bool IsDumped(ProfileType curType) const; 322 323 template<typename Callback> IterateChilds(Callback callback)324 void IterateChilds(Callback callback) const 325 { 326 IterateAll([&callback] (HClassLayoutDesc *desc) { 327 if (desc->GetProfileType().IsRootType()) { 328 return; 329 } 330 callback(reinterpret_cast<ChildHClassLayoutDesc *>(desc)); 331 }); 332 } 333 CheckHasInvalidType()334 bool CheckHasInvalidType() const 335 { 336 for (auto iter : transitionLayout_) { 337 if (iter.first.IsInvalidType()) { 338 return true; 339 } 340 } 341 return false; 342 } 343 344 private: 345 template<typename Callback> IterateAll(Callback callback)346 void IterateAll(Callback callback) const 347 { 348 for (auto iter : transitionLayout_) { 349 callback(iter.second); 350 } 351 } 352 353 ProfileType type_; 354 ProfileType protoPt_; 355 CMap<ProfileType, HClassLayoutDesc *> transitionLayout_; 356 }; 357 358 class PGOLayoutDescInfo { 359 public: 360 PGOLayoutDescInfo() = default; PGOLayoutDescInfo(const CString & key,PGOHandler handler)361 PGOLayoutDescInfo(const CString &key, PGOHandler handler) : handler_(handler) 362 { 363 size_t len = key.size(); 364 size_ = Size(len); 365 if (len > 0 && memcpy_s(&key_, len, key.c_str(), len) != EOK) { 366 LOG_ECMA(ERROR) << "SetMethodName memcpy_s failed" << key << ", len = " << len; 367 UNREACHABLE(); 368 } 369 *(&key_ + len) = '\0'; 370 } 371 Size(size_t len)372 static int32_t Size(size_t len) 373 { 374 return sizeof(PGOLayoutDescInfo) + AlignUp(len, GetAlignmentInBytes(ALIGN_SIZE)); 375 } 376 Size()377 int32_t Size() const 378 { 379 return size_; 380 } 381 GetKey()382 const char *GetKey() const 383 { 384 return &key_; 385 } 386 GetHandler()387 PGOHandler GetHandler() const 388 { 389 return handler_; 390 } 391 392 private: 393 int32_t size_ {0}; 394 PGOHandler handler_; 395 char key_ {'\0'}; 396 }; 397 398 class HClassLayoutDescInner { 399 public: 400 virtual ~HClassLayoutDescInner() = default; Size()401 int32_t Size() const 402 { 403 return size_; 404 } 405 GetProfileType()406 ProfileType GetProfileType() const 407 { 408 return type_; 409 } 410 411 protected: 412 int32_t size_ { 0 }; 413 ProfileType type_; 414 }; 415 416 class RootHClassLayoutDescInner : public HClassLayoutDescInner { 417 public: CaculateSize(const RootHClassLayoutDesc & desc)418 static size_t CaculateSize(const RootHClassLayoutDesc &desc) 419 { 420 size_t size = sizeof(RootHClassLayoutDescInner); 421 size += desc.GetChildSize() * sizeof(ProfileType); 422 desc.IterateProps([&size] (const PropertyDesc &propDesc) { 423 auto keyLen = propDesc.first.size(); 424 size += static_cast<size_t>(PGOLayoutDescInfo::Size(keyLen)); 425 }); 426 return size; 427 } 428 Merge(const RootHClassLayoutDesc & desc)429 void Merge(const RootHClassLayoutDesc &desc) 430 { 431 size_ = static_cast<int32_t>(RootHClassLayoutDescInner::CaculateSize(desc)); 432 type_ = desc.GetProfileType(); 433 childCount_ = 0; 434 desc.IterateChilds([this] (const ProfileType &childType) -> bool { 435 auto newChildType = const_cast<ProfileType *>(GetChildType(childCount_++)); 436 new (newChildType) ProfileType(childType); 437 return true; 438 }); 439 440 auto current = const_cast<PGOLayoutDescInfo *>(GetFirstProperty()); 441 desc.IterateProps([this, ¤t] (const PropertyDesc &propDesc) { 442 auto key = propDesc.first; 443 auto type = propDesc.second; 444 new (current) PGOLayoutDescInfo(key, type); 445 current = const_cast<PGOLayoutDescInfo *>(GetNextProperty(current)); 446 propCount_++; 447 }); 448 } 449 Convert(PGOContext & context,RootHClassLayoutDesc * desc)450 void Convert(PGOContext& context, RootHClassLayoutDesc *desc) const 451 { 452 auto descInfo = GetFirstProperty(); 453 for (uint32_t i = 0; i < propCount_; i++) { 454 desc->InsertKeyAndDesc(descInfo->GetKey(), descInfo->GetHandler()); 455 descInfo = GetNextProperty(descInfo); 456 } 457 for (uint32_t i = 0; i < childCount_; i++) { 458 auto profileType(*GetChildType(i)); 459 desc->AddChildHClassLayoutDesc(profileType.Remap(context)); 460 } 461 } 462 SetObjectType(JSType objType)463 void SetObjectType(JSType objType) 464 { 465 objType_ = objType; 466 } 467 GetObjectType()468 JSType GetObjectType() const 469 { 470 return objType_; 471 } 472 SetObjectSize(uint32_t size)473 void SetObjectSize(uint32_t size) 474 { 475 objSize_ = size; 476 } 477 GetObjectSize()478 uint32_t GetObjectSize() const 479 { 480 return objSize_; 481 } 482 483 private: GetChildType(uint32_t index)484 const ProfileType *GetChildType(uint32_t index) const 485 { 486 return (&childType_) + index; 487 } 488 GetFirstProperty()489 const PGOLayoutDescInfo *GetFirstProperty() const 490 { 491 return reinterpret_cast<const PGOLayoutDescInfo *>(reinterpret_cast<uintptr_t>(&childType_ + childCount_)); 492 } 493 GetNextProperty(const PGOLayoutDescInfo * current)494 const PGOLayoutDescInfo *GetNextProperty(const PGOLayoutDescInfo *current) const 495 { 496 return reinterpret_cast<const PGOLayoutDescInfo *>(reinterpret_cast<uintptr_t>(current) + current->Size()); 497 } 498 499 JSType objType_; 500 uint32_t objSize_ {0}; 501 uint32_t propCount_ {0}; 502 uint32_t childCount_ {0}; 503 ProfileType childType_; 504 }; 505 506 class ChildHClassLayoutDescInner : public HClassLayoutDescInner { 507 public: CaculateSize(const ChildHClassLayoutDesc & desc)508 static size_t CaculateSize(const ChildHClassLayoutDesc &desc) 509 { 510 size_t size = sizeof(ChildHClassLayoutDescInner); 511 size += desc.GetChildSize() * sizeof(ProfileType); 512 auto key = desc.GetPropertyDesc().first; 513 size += static_cast<size_t>(PGOLayoutDescInfo::Size(key.size())); 514 return size; 515 } 516 Merge(const ChildHClassLayoutDesc & desc)517 void Merge(const ChildHClassLayoutDesc &desc) 518 { 519 size_ = static_cast<int32_t>(ChildHClassLayoutDescInner::CaculateSize(desc)); 520 type_ = desc.GetProfileType(); 521 childCount_ = 0; 522 desc.IterateChilds([this] (const ProfileType &childType) -> bool { 523 auto newChildType = const_cast<ProfileType *>(GetChildType(childCount_++)); 524 new (newChildType) ProfileType(childType); 525 return true; 526 }); 527 528 auto current = const_cast<PGOLayoutDescInfo *>(GetProperty()); 529 auto propDesc = desc.GetPropertyDesc(); 530 auto key = propDesc.first; 531 auto type = propDesc.second; 532 new (current) PGOLayoutDescInfo(key, type); 533 } 534 Convert(PGOContext & context,ChildHClassLayoutDesc * desc)535 void Convert(PGOContext& context, ChildHClassLayoutDesc *desc) const 536 { 537 auto descInfo = GetProperty(); 538 desc->InsertKeyAndDesc(descInfo->GetKey(), descInfo->GetHandler()); 539 for (uint32_t i = 0; i < childCount_; i++) { 540 auto profileType(*GetChildType(i)); 541 desc->AddChildHClassLayoutDesc(profileType.Remap(context)); 542 } 543 } 544 545 private: GetChildType(uint32_t index)546 const ProfileType *GetChildType(uint32_t index) const 547 { 548 return (&childType_) + index; 549 } 550 GetProperty()551 const PGOLayoutDescInfo *GetProperty() const 552 { 553 return reinterpret_cast<const PGOLayoutDescInfo *>(&childType_ + childCount_); 554 } 555 556 uint32_t childCount_ { 0 }; 557 ProfileType childType_; 558 }; 559 560 template <typename SampleType> 561 class PGOHClassTreeTemplate { 562 public: PGOHClassTreeTemplate(size_t size,SampleType type,SampleType protoSt)563 PGOHClassTreeTemplate(size_t size, SampleType type, SampleType protoSt) 564 : size_(size), type_(type), protoSt_(protoSt) {} 565 CaculateSize(const PGOHClassTreeDesc & desc)566 static size_t CaculateSize(const PGOHClassTreeDesc &desc) 567 { 568 auto rootLayout = desc.GetHClassLayoutDesc(desc.GetProfileType()); 569 if (rootLayout == nullptr) { 570 return sizeof(PGOHClassTreeTemplate<SampleType>); 571 } 572 if (!rootLayout->IsRoot()) { 573 LOG_ECMA(ERROR) << "rootLayout is not RootHClassLayoutDesc!"; 574 } 575 size_t size = sizeof(PGOHClassTreeTemplate<SampleType>) - sizeof(RootHClassLayoutDescInner); 576 size += RootHClassLayoutDescInner::CaculateSize(*reinterpret_cast<const RootHClassLayoutDesc *>(rootLayout)); 577 578 desc.IterateChilds([&size](ChildHClassLayoutDesc *desc) { 579 size += ChildHClassLayoutDescInner::CaculateSize(*desc); 580 }); 581 return size; 582 } 583 GetTypeString(const PGOHClassTreeDesc & desc)584 static std::string GetTypeString(const PGOHClassTreeDesc &desc) 585 { 586 std::string text; 587 text += desc.GetProfileType().GetTypeString(); 588 text += DumpUtils::BLOCK_AND_ARRAY_START; 589 auto layoutDesc = desc.GetHClassLayoutDesc(desc.GetProfileType()); 590 if (layoutDesc != nullptr) { 591 bool isLayoutFirst = true; 592 ASSERT(layoutDesc->GetProfileType().IsRootType()); 593 auto rootLayoutDesc = reinterpret_cast<RootHClassLayoutDesc *>(layoutDesc); 594 rootLayoutDesc->IterateProps([&text, &isLayoutFirst] (const PropertyDesc &propDesc) { 595 if (!isLayoutFirst) { 596 text += DumpUtils::SPACE + DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE; 597 } 598 isLayoutFirst = false; 599 text += propDesc.first; 600 text += DumpUtils::BLOCK_START; 601 text += std::to_string(propDesc.second.GetValue()); 602 }); 603 } 604 text += (DumpUtils::SPACE + DumpUtils::ARRAY_END); 605 return text; 606 } 607 Merge(const PGOHClassTreeDesc & desc)608 void Merge(const PGOHClassTreeDesc &desc) 609 { 610 auto root = const_cast<RootHClassLayoutDescInner *>(GetRoot()); 611 auto layoutDesc = desc.GetHClassLayoutDesc(desc.GetProfileType()); 612 if (layoutDesc == nullptr) { 613 return; 614 } 615 auto rootLayoutDesc = reinterpret_cast<const RootHClassLayoutDesc *>(layoutDesc); 616 root->Merge(*rootLayoutDesc); 617 root->SetObjectType(rootLayoutDesc->GetObjectType()); 618 root->SetObjectSize(rootLayoutDesc->GetObjectSize()); 619 620 childCount_ = 0; 621 auto last = reinterpret_cast<HClassLayoutDescInner *>(root); 622 desc.IterateChilds([this, &last](ChildHClassLayoutDesc *desc) { 623 auto current = const_cast<ChildHClassLayoutDescInner *>(GetNext(last)); 624 new (current) ChildHClassLayoutDescInner(); 625 current->Merge(*desc); 626 last = current; 627 childCount_++; 628 }); 629 } 630 Convert(PGOContext & context)631 PGOHClassTreeDesc Convert(PGOContext& context) 632 { 633 PGOHClassTreeDesc desc(ProfileType(context, GetType().GetProfileType())); 634 desc.SetProtoPt(ProfileType(context, GetProtoSt().GetProfileType())); 635 auto root = GetRoot(); 636 if (root->GetProfileType().IsNone()) { 637 return desc; 638 } 639 auto layoutDesc = desc.GetOrInsertHClassLayoutDesc(root->GetProfileType().Remap(context), true); 640 auto rootLayoutDesc = reinterpret_cast<RootHClassLayoutDesc *>(layoutDesc); 641 rootLayoutDesc->SetObjectType(root->GetObjectType()); 642 rootLayoutDesc->SetObjectSize(root->GetObjectSize()); 643 root->Convert(context, rootLayoutDesc); 644 645 auto last = reinterpret_cast<const HClassLayoutDescInner *>(root); 646 for (int32_t i = 0; i < childCount_; i++) { 647 auto current = GetNext(last); 648 auto childLayoutDesc = desc.GetOrInsertHClassLayoutDesc(current->GetProfileType().Remap(context), false); 649 current->Convert(context, reinterpret_cast<ChildHClassLayoutDesc *>(childLayoutDesc)); 650 last = current; 651 } 652 return desc; 653 } 654 Size()655 int32_t Size() const 656 { 657 return size_; 658 } 659 GetType()660 SampleType GetType() const 661 { 662 return type_; 663 } 664 GetProtoSt()665 SampleType GetProtoSt() const 666 { 667 return protoSt_; 668 } 669 670 private: GetRoot()671 const RootHClassLayoutDescInner *GetRoot() const 672 { 673 return &rootHClassLayout_; 674 } 675 GetNext(const HClassLayoutDescInner * current)676 const ChildHClassLayoutDescInner *GetNext(const HClassLayoutDescInner *current) const 677 { 678 return reinterpret_cast<const ChildHClassLayoutDescInner *>( 679 reinterpret_cast<uintptr_t>(current) + current->Size()); 680 } 681 GetEnd()682 uintptr_t GetEnd() const 683 { 684 return reinterpret_cast<uintptr_t>(this) + Size(); 685 } 686 687 int32_t size_; 688 SampleType type_; 689 SampleType protoSt_; 690 int32_t childCount_ { 0 }; 691 RootHClassLayoutDescInner rootHClassLayout_; 692 }; 693 694 using PGOHClassTreeDescInner = PGOHClassTreeTemplate<PGOSampleType>; 695 using PGOHClassTreeDescInnerRef = PGOHClassTreeTemplate<PGOSampleTypeRef>; 696 } // namespace panda::ecmascript::pgo 697 #endif // ECMASCRIPT_PGO_PROFILER_LAYOUT_H 698