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(JSTaggedType root, ProfileType rootType); 317 bool DumpForChild(JSTaggedType child, ProfileType childType); 318 bool UpdateForTransition(JSTaggedType parent, ProfileType parentType, JSTaggedType child, ProfileType childType); 319 bool UpdateLayout(JSTaggedType curHClass, ProfileType curType); 320 bool IsDumped(ProfileType curType) const; 321 322 template<typename Callback> IterateChilds(Callback callback)323 void IterateChilds(Callback callback) const 324 { 325 IterateAll([&callback] (HClassLayoutDesc *desc) { 326 if (desc->GetProfileType().IsRootType()) { 327 return; 328 } 329 callback(reinterpret_cast<ChildHClassLayoutDesc *>(desc)); 330 }); 331 } 332 333 private: 334 template<typename Callback> IterateAll(Callback callback)335 void IterateAll(Callback callback) const 336 { 337 for (auto iter : transitionLayout_) { 338 callback(iter.second); 339 } 340 } 341 342 ProfileType type_; 343 ProfileType protoPt_; 344 CMap<ProfileType, HClassLayoutDesc *> transitionLayout_; 345 }; 346 347 class PGOLayoutDescInfo { 348 public: 349 PGOLayoutDescInfo() = default; PGOLayoutDescInfo(const CString & key,PGOHandler handler)350 PGOLayoutDescInfo(const CString &key, PGOHandler handler) : handler_(handler) 351 { 352 size_t len = key.size(); 353 size_ = Size(len); 354 if (len > 0 && memcpy_s(&key_, len, key.c_str(), len) != EOK) { 355 LOG_ECMA(ERROR) << "SetMethodName memcpy_s failed" << key << ", len = " << len; 356 UNREACHABLE(); 357 } 358 *(&key_ + len) = '\0'; 359 } 360 Size(size_t len)361 static int32_t Size(size_t len) 362 { 363 return sizeof(PGOLayoutDescInfo) + AlignUp(len, GetAlignmentInBytes(ALIGN_SIZE)); 364 } 365 Size()366 int32_t Size() const 367 { 368 return size_; 369 } 370 GetKey()371 const char *GetKey() const 372 { 373 return &key_; 374 } 375 GetHandler()376 PGOHandler GetHandler() const 377 { 378 return handler_; 379 } 380 381 private: 382 int32_t size_ {0}; 383 PGOHandler handler_; 384 char key_ {'\0'}; 385 }; 386 387 class HClassLayoutDescInner { 388 public: 389 virtual ~HClassLayoutDescInner() = default; Size()390 int32_t Size() const 391 { 392 return size_; 393 } 394 GetProfileType()395 ProfileType GetProfileType() const 396 { 397 return type_; 398 } 399 400 protected: 401 int32_t size_ { 0 }; 402 ProfileType type_; 403 }; 404 405 class RootHClassLayoutDescInner : public HClassLayoutDescInner { 406 public: CaculateSize(const RootHClassLayoutDesc & desc)407 static size_t CaculateSize(const RootHClassLayoutDesc &desc) 408 { 409 size_t size = sizeof(RootHClassLayoutDescInner); 410 size += desc.GetChildSize() * sizeof(ProfileType); 411 desc.IterateProps([&size] (const PropertyDesc &propDesc) { 412 auto keyLen = propDesc.first.size(); 413 size += static_cast<size_t>(PGOLayoutDescInfo::Size(keyLen)); 414 }); 415 return size; 416 } 417 Merge(const RootHClassLayoutDesc & desc)418 void Merge(const RootHClassLayoutDesc &desc) 419 { 420 size_ = static_cast<int32_t>(RootHClassLayoutDescInner::CaculateSize(desc)); 421 type_ = desc.GetProfileType(); 422 childCount_ = 0; 423 desc.IterateChilds([this] (const ProfileType &childType) -> bool { 424 auto newChildType = const_cast<ProfileType *>(GetChildType(childCount_++)); 425 new (newChildType) ProfileType(childType); 426 return true; 427 }); 428 429 auto current = const_cast<PGOLayoutDescInfo *>(GetFirstProperty()); 430 desc.IterateProps([this, ¤t] (const PropertyDesc &propDesc) { 431 auto key = propDesc.first; 432 auto type = propDesc.second; 433 new (current) PGOLayoutDescInfo(key, type); 434 current = const_cast<PGOLayoutDescInfo *>(GetNextProperty(current)); 435 propCount_++; 436 }); 437 } 438 Convert(PGOContext & context,RootHClassLayoutDesc * desc)439 void Convert(PGOContext& context, RootHClassLayoutDesc *desc) const 440 { 441 auto descInfo = GetFirstProperty(); 442 for (uint32_t i = 0; i < propCount_; i++) { 443 desc->InsertKeyAndDesc(descInfo->GetKey(), descInfo->GetHandler()); 444 descInfo = GetNextProperty(descInfo); 445 } 446 for (uint32_t i = 0; i < childCount_; i++) { 447 auto profileType(*GetChildType(i)); 448 desc->AddChildHClassLayoutDesc(profileType.Remap(context)); 449 } 450 } 451 SetObjectType(JSType objType)452 void SetObjectType(JSType objType) 453 { 454 objType_ = objType; 455 } 456 GetObjectType()457 JSType GetObjectType() const 458 { 459 return objType_; 460 } 461 SetObjectSize(uint32_t size)462 void SetObjectSize(uint32_t size) 463 { 464 objSize_ = size; 465 } 466 GetObjectSize()467 uint32_t GetObjectSize() const 468 { 469 return objSize_; 470 } 471 472 private: GetChildType(uint32_t index)473 const ProfileType *GetChildType(uint32_t index) const 474 { 475 return (&childType_) + index; 476 } 477 GetFirstProperty()478 const PGOLayoutDescInfo *GetFirstProperty() const 479 { 480 return reinterpret_cast<const PGOLayoutDescInfo *>(reinterpret_cast<uintptr_t>(&childType_ + childCount_)); 481 } 482 GetNextProperty(const PGOLayoutDescInfo * current)483 const PGOLayoutDescInfo *GetNextProperty(const PGOLayoutDescInfo *current) const 484 { 485 return reinterpret_cast<const PGOLayoutDescInfo *>(reinterpret_cast<uintptr_t>(current) + current->Size()); 486 } 487 488 JSType objType_; 489 uint32_t objSize_ {0}; 490 uint32_t propCount_ {0}; 491 uint32_t childCount_ {0}; 492 ProfileType childType_; 493 }; 494 495 class ChildHClassLayoutDescInner : public HClassLayoutDescInner { 496 public: CaculateSize(const ChildHClassLayoutDesc & desc)497 static size_t CaculateSize(const ChildHClassLayoutDesc &desc) 498 { 499 size_t size = sizeof(ChildHClassLayoutDescInner); 500 size += desc.GetChildSize() * sizeof(ProfileType); 501 auto key = desc.GetPropertyDesc().first; 502 size += static_cast<size_t>(PGOLayoutDescInfo::Size(key.size())); 503 return size; 504 } 505 Merge(const ChildHClassLayoutDesc & desc)506 void Merge(const ChildHClassLayoutDesc &desc) 507 { 508 size_ = static_cast<int32_t>(ChildHClassLayoutDescInner::CaculateSize(desc)); 509 type_ = desc.GetProfileType(); 510 childCount_ = 0; 511 desc.IterateChilds([this] (const ProfileType &childType) -> bool { 512 auto newChildType = const_cast<ProfileType *>(GetChildType(childCount_++)); 513 new (newChildType) ProfileType(childType); 514 return true; 515 }); 516 517 auto current = const_cast<PGOLayoutDescInfo *>(GetProperty()); 518 auto propDesc = desc.GetPropertyDesc(); 519 auto key = propDesc.first; 520 auto type = propDesc.second; 521 new (current) PGOLayoutDescInfo(key, type); 522 } 523 Convert(PGOContext & context,ChildHClassLayoutDesc * desc)524 void Convert(PGOContext& context, ChildHClassLayoutDesc *desc) const 525 { 526 auto descInfo = GetProperty(); 527 desc->InsertKeyAndDesc(descInfo->GetKey(), descInfo->GetHandler()); 528 for (uint32_t i = 0; i < childCount_; i++) { 529 auto profileType(*GetChildType(i)); 530 desc->AddChildHClassLayoutDesc(profileType.Remap(context)); 531 } 532 } 533 534 private: GetChildType(uint32_t index)535 const ProfileType *GetChildType(uint32_t index) const 536 { 537 return (&childType_) + index; 538 } 539 GetProperty()540 const PGOLayoutDescInfo *GetProperty() const 541 { 542 return reinterpret_cast<const PGOLayoutDescInfo *>(&childType_ + childCount_); 543 } 544 545 uint32_t childCount_ { 0 }; 546 ProfileType childType_; 547 }; 548 549 template <typename SampleType> 550 class PGOHClassTreeTemplate { 551 public: PGOHClassTreeTemplate(size_t size,SampleType type,SampleType protoSt)552 PGOHClassTreeTemplate(size_t size, SampleType type, SampleType protoSt) 553 : size_(size), type_(type), protoSt_(protoSt) {} 554 CaculateSize(const PGOHClassTreeDesc & desc)555 static size_t CaculateSize(const PGOHClassTreeDesc &desc) 556 { 557 auto rootLayout = desc.GetHClassLayoutDesc(desc.GetProfileType()); 558 if (rootLayout == nullptr) { 559 return sizeof(PGOHClassTreeTemplate<SampleType>); 560 } 561 if (!rootLayout->IsRoot()) { 562 LOG_ECMA(ERROR) << "rootLayout is not RootHClassLayoutDesc!"; 563 } 564 size_t size = sizeof(PGOHClassTreeTemplate<SampleType>) - sizeof(RootHClassLayoutDescInner); 565 size += RootHClassLayoutDescInner::CaculateSize(*reinterpret_cast<const RootHClassLayoutDesc *>(rootLayout)); 566 567 desc.IterateChilds([&size](ChildHClassLayoutDesc *desc) { 568 size += ChildHClassLayoutDescInner::CaculateSize(*desc); 569 }); 570 return size; 571 } 572 GetTypeString(const PGOHClassTreeDesc & desc)573 static std::string GetTypeString(const PGOHClassTreeDesc &desc) 574 { 575 std::string text; 576 text += desc.GetProfileType().GetTypeString(); 577 text += DumpUtils::BLOCK_AND_ARRAY_START; 578 auto layoutDesc = desc.GetHClassLayoutDesc(desc.GetProfileType()); 579 if (layoutDesc != nullptr) { 580 bool isLayoutFirst = true; 581 ASSERT(layoutDesc->GetProfileType().IsRootType()); 582 auto rootLayoutDesc = reinterpret_cast<RootHClassLayoutDesc *>(layoutDesc); 583 rootLayoutDesc->IterateProps([&text, &isLayoutFirst] (const PropertyDesc &propDesc) { 584 if (!isLayoutFirst) { 585 text += DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE; 586 } else { 587 text += DumpUtils::ARRAY_START; 588 } 589 isLayoutFirst = false; 590 text += propDesc.first; 591 text += DumpUtils::BLOCK_START; 592 text += std::to_string(propDesc.second.GetValue()); 593 }); 594 } 595 text += (DumpUtils::SPACE + DumpUtils::ARRAY_END); 596 return text; 597 } 598 Merge(const PGOHClassTreeDesc & desc)599 void Merge(const PGOHClassTreeDesc &desc) 600 { 601 auto root = const_cast<RootHClassLayoutDescInner *>(GetRoot()); 602 auto layoutDesc = desc.GetHClassLayoutDesc(desc.GetProfileType()); 603 if (layoutDesc == nullptr) { 604 return; 605 } 606 auto rootLayoutDesc = reinterpret_cast<const RootHClassLayoutDesc *>(layoutDesc); 607 root->Merge(*rootLayoutDesc); 608 root->SetObjectType(rootLayoutDesc->GetObjectType()); 609 root->SetObjectSize(rootLayoutDesc->GetObjectSize()); 610 611 childCount_ = 0; 612 auto last = reinterpret_cast<HClassLayoutDescInner *>(root); 613 desc.IterateChilds([this, &last](ChildHClassLayoutDesc *desc) { 614 auto current = const_cast<ChildHClassLayoutDescInner *>(GetNext(last)); 615 new (current) ChildHClassLayoutDescInner(); 616 current->Merge(*desc); 617 last = current; 618 childCount_++; 619 }); 620 } 621 Convert(PGOContext & context)622 PGOHClassTreeDesc Convert(PGOContext& context) 623 { 624 PGOHClassTreeDesc desc(ProfileType(context, GetType().GetProfileType())); 625 desc.SetProtoPt(ProfileType(context, GetProtoSt().GetProfileType())); 626 auto root = GetRoot(); 627 if (root->GetProfileType().IsNone()) { 628 return desc; 629 } 630 auto layoutDesc = desc.GetOrInsertHClassLayoutDesc(root->GetProfileType().Remap(context), true); 631 auto rootLayoutDesc = reinterpret_cast<RootHClassLayoutDesc *>(layoutDesc); 632 rootLayoutDesc->SetObjectType(root->GetObjectType()); 633 rootLayoutDesc->SetObjectSize(root->GetObjectSize()); 634 root->Convert(context, rootLayoutDesc); 635 636 auto last = reinterpret_cast<const HClassLayoutDescInner *>(root); 637 for (int32_t i = 0; i < childCount_; i++) { 638 auto current = GetNext(last); 639 auto childLayoutDesc = desc.GetOrInsertHClassLayoutDesc(current->GetProfileType().Remap(context), false); 640 current->Convert(context, reinterpret_cast<ChildHClassLayoutDesc *>(childLayoutDesc)); 641 last = current; 642 } 643 return desc; 644 } 645 Size()646 int32_t Size() const 647 { 648 return size_; 649 } 650 GetType()651 SampleType GetType() const 652 { 653 return type_; 654 } 655 GetProtoSt()656 SampleType GetProtoSt() const 657 { 658 return protoSt_; 659 } 660 661 private: GetRoot()662 const RootHClassLayoutDescInner *GetRoot() const 663 { 664 return &rootHClassLayout_; 665 } 666 GetNext(const HClassLayoutDescInner * current)667 const ChildHClassLayoutDescInner *GetNext(const HClassLayoutDescInner *current) const 668 { 669 return reinterpret_cast<const ChildHClassLayoutDescInner *>( 670 reinterpret_cast<uintptr_t>(current) + current->Size()); 671 } 672 GetEnd()673 uintptr_t GetEnd() const 674 { 675 return reinterpret_cast<uintptr_t>(this) + Size(); 676 } 677 678 int32_t size_; 679 SampleType type_; 680 SampleType protoSt_; 681 int32_t childCount_ { 0 }; 682 RootHClassLayoutDescInner rootHClassLayout_; 683 }; 684 685 using PGOHClassTreeDescInner = PGOHClassTreeTemplate<PGOSampleType>; 686 using PGOHClassTreeDescInnerRef = PGOHClassTreeTemplate<PGOSampleTypeRef>; 687 } // namespace panda::ecmascript::pgo 688 #endif // ECMASCRIPT_PGO_PROFILER_LAYOUT_H 689