| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- Region *
- Region::New(RegionType type, Region * parent, Func * func)
- {
- Region * region = JitAnew(func->m_alloc, Region);
- region->type = type;
- region->parent = parent;
- region->bailoutReturnThunkLabel = IR::LabelInstr::New(Js::OpCode::Label, func, true);
- if (type == RegionTypeTry)
- {
- region->selfOrFirstTryAncestor = region;
- }
- return region;
- }
- void
- Region::AllocateEHBailoutData(Func * func, IR::Instr * tryInstr)
- {
- if (this->GetType() == RegionTypeRoot)
- {
- this->ehBailoutData = NativeCodeDataNew(func->GetNativeCodeDataAllocator(), Js::EHBailoutData, -1 /*nestingDepth*/, 0 /*catchOffset*/, 0 /*finallyOffset*/, Js::HandlerType::HT_None, nullptr /*parent*/);
- }
- else
- {
- this->ehBailoutData = NativeCodeDataNew(func->GetNativeCodeDataAllocator(), Js::EHBailoutData, this->GetParent()->ehBailoutData->nestingDepth + 1, 0, 0, Js::HandlerType::HT_None, this->GetParent()->ehBailoutData);
- if (this->GetType() == RegionTypeTry)
- {
- Assert(tryInstr);
- if (tryInstr->m_opcode == Js::OpCode::TryCatch)
- {
- this->ehBailoutData->catchOffset = tryInstr->AsBranchInstr()->GetTarget()->GetByteCodeOffset(); // ByteCode offset of the Catch
- }
- else if (tryInstr->m_opcode == Js::OpCode::TryFinally)
- {
- this->ehBailoutData->finallyOffset = tryInstr->AsBranchInstr()->GetTarget()->GetByteCodeOffset(); // ByteCode offset of the Finally
- }
- }
- else if (this->GetType() == RegionTypeCatch)
- {
- this->ehBailoutData->ht = Js::HandlerType::HT_Catch;
- }
- else
- {
- this->ehBailoutData->ht = Js::HandlerType::HT_Finally;
- }
- }
- }
- Region *
- Region::GetSelfOrFirstTryAncestor()
- {
- if (!this->selfOrFirstTryAncestor)
- {
- Region* region = this;
- while (region && region->GetType() != RegionTypeTry)
- {
- region = region->GetParent();
- }
- this->selfOrFirstTryAncestor = region;
- }
- return this->selfOrFirstTryAncestor;
- }
- // Return the first ancestor of the region's parent which is not a non exception finally
- // Skip all non exception finally regions in the region tree
- // Return the parent of the first non-non-exception finally region
- Region *
- Region::GetFirstAncestorOfNonExceptingFinallyParent()
- {
- Region * ancestor = this;
- while (ancestor && ancestor->IsNonExceptingFinally())
- {
- ancestor = ancestor->GetParent();
- }
- // ancestor is the first ancestor which is not a non exception finally
- Assert(ancestor && !ancestor->IsNonExceptingFinally());
- // If the ancestor's parent is a non exception finally, recurse
- if (ancestor && ancestor->GetType() != RegionTypeRoot && ancestor->GetParent()->IsNonExceptingFinally())
- {
- return ancestor->GetParent()->GetFirstAncestorOfNonExceptingFinally();
- }
- Assert(ancestor);
- // Null check added to avoid prefast warning only
- return ancestor ? (ancestor->GetType() == RegionTypeRoot ? ancestor : ancestor->GetParent()) : nullptr;
- }
- // Return first ancestor which is not a non exception finally
- Region *
- Region::GetFirstAncestorOfNonExceptingFinally()
- {
- Region *ancestor = this->GetParent();
- while (ancestor->IsNonExceptingFinally())
- {
- ancestor = ancestor->GetParent();
- }
- return ancestor;
- }
- bool
- Region::CheckWriteThroughSym(StackSym * sym)
- {
- if (this->GetType() == RegionTypeRoot)
- {
- return false;
- }
- // if the current region is a try region, check in its write-through set,
- // otherwise (current = catch region) look in the first try ancestor's write-through set
- Region * selfOrFirstTryAncestor = this->GetSelfOrFirstTryAncestor();
- if (!selfOrFirstTryAncestor)
- {
- return false;
- }
- Assert(selfOrFirstTryAncestor->GetType() == RegionTypeTry);
- return selfOrFirstTryAncestor->writeThroughSymbolsSet && selfOrFirstTryAncestor->writeThroughSymbolsSet->Test(sym->m_id);
- }
|