Region.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "Backend.h"
  6. Region *
  7. Region::New(RegionType type, Region * parent, Func * func)
  8. {
  9. Region * region = JitAnew(func->m_alloc, Region);
  10. region->type = type;
  11. region->parent = parent;
  12. region->bailoutReturnThunkLabel = IR::LabelInstr::New(Js::OpCode::Label, func, true);
  13. if (type == RegionTypeTry)
  14. {
  15. region->selfOrFirstTryAncestor = region;
  16. }
  17. return region;
  18. }
  19. void
  20. Region::AllocateEHBailoutData(Func * func, IR::Instr * tryInstr)
  21. {
  22. if (this->GetType() == RegionTypeRoot)
  23. {
  24. this->ehBailoutData = NativeCodeDataNew(func->GetNativeCodeDataAllocator(), Js::EHBailoutData, -1 /*nestingDepth*/, 0 /*catchOffset*/, 0 /*finallyOffset*/, Js::HandlerType::HT_None, nullptr /*parent*/);
  25. }
  26. else
  27. {
  28. this->ehBailoutData = NativeCodeDataNew(func->GetNativeCodeDataAllocator(), Js::EHBailoutData, this->GetParent()->ehBailoutData->nestingDepth + 1, 0, 0, Js::HandlerType::HT_None, this->GetParent()->ehBailoutData);
  29. if (this->GetType() == RegionTypeTry)
  30. {
  31. Assert(tryInstr);
  32. if (tryInstr->m_opcode == Js::OpCode::TryCatch)
  33. {
  34. this->ehBailoutData->catchOffset = tryInstr->AsBranchInstr()->GetTarget()->GetByteCodeOffset(); // ByteCode offset of the Catch
  35. }
  36. else if (tryInstr->m_opcode == Js::OpCode::TryFinally)
  37. {
  38. this->ehBailoutData->finallyOffset = tryInstr->AsBranchInstr()->GetTarget()->GetByteCodeOffset(); // ByteCode offset of the Finally
  39. }
  40. }
  41. else if (this->GetType() == RegionTypeCatch)
  42. {
  43. this->ehBailoutData->ht = Js::HandlerType::HT_Catch;
  44. }
  45. else
  46. {
  47. this->ehBailoutData->ht = Js::HandlerType::HT_Finally;
  48. }
  49. }
  50. }
  51. Region *
  52. Region::GetSelfOrFirstTryAncestor()
  53. {
  54. if (!this->selfOrFirstTryAncestor)
  55. {
  56. Region* region = this;
  57. while (region && region->GetType() != RegionTypeTry)
  58. {
  59. region = region->GetParent();
  60. }
  61. this->selfOrFirstTryAncestor = region;
  62. }
  63. return this->selfOrFirstTryAncestor;
  64. }
  65. // Return the first ancestor of the region's parent which is not a non exception finally
  66. // Skip all non exception finally regions in the region tree
  67. // Return the parent of the first non-non-exception finally region
  68. Region *
  69. Region::GetFirstAncestorOfNonExceptingFinallyParent()
  70. {
  71. Region * ancestor = this;
  72. while (ancestor && ancestor->IsNonExceptingFinally())
  73. {
  74. ancestor = ancestor->GetParent();
  75. }
  76. // ancestor is the first ancestor which is not a non exception finally
  77. Assert(ancestor && !ancestor->IsNonExceptingFinally());
  78. // If the ancestor's parent is a non exception finally, recurse
  79. if (ancestor && ancestor->GetType() != RegionTypeRoot && ancestor->GetParent()->IsNonExceptingFinally())
  80. {
  81. return ancestor->GetParent()->GetFirstAncestorOfNonExceptingFinally();
  82. }
  83. Assert(ancestor);
  84. // Null check added to avoid prefast warning only
  85. return ancestor ? (ancestor->GetType() == RegionTypeRoot ? ancestor : ancestor->GetParent()) : nullptr;
  86. }
  87. // Return first ancestor which is not a non exception finally
  88. Region *
  89. Region::GetFirstAncestorOfNonExceptingFinally()
  90. {
  91. Region *ancestor = this->GetParent();
  92. while (ancestor->IsNonExceptingFinally())
  93. {
  94. ancestor = ancestor->GetParent();
  95. }
  96. return ancestor;
  97. }