Skip to content

Commit 6cb3aed

Browse files
[main] Source code updates from dotnet/runtime (#1495)
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
1 parent 44bd674 commit 6cb3aed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2279
-1110
lines changed

src/runtime/docs/area-owners.md

Lines changed: 7 additions & 7 deletions
Large diffs are not rendered by default.

src/runtime/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs

Lines changed: 350 additions & 152 deletions
Large diffs are not rendered by default.

src/runtime/src/coreclr/inc/corinfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,15 @@ enum CorInfoContinuationFlags
17121712
// OSR method saved in the beginning of 'Data', or -1 if the continuation
17131713
// belongs to a tier 0 method.
17141714
CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA = 4,
1715+
// If this bit is set the continuation should continue on the thread
1716+
// pool.
1717+
CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL = 8,
1718+
// If this bit is set the continuation has a SynchronizationContext
1719+
// that we should continue on.
1720+
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT = 16,
1721+
// If this bit is set the continuation has a TaskScheduler
1722+
// that we should continue on.
1723+
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER = 32,
17151724
};
17161725

17171726
struct CORINFO_ASYNC_INFO
@@ -1737,6 +1746,7 @@ struct CORINFO_ASYNC_INFO
17371746
CORINFO_METHOD_HANDLE captureExecutionContextMethHnd;
17381747
// Method handle for AsyncHelpers.RestoreExecutionContext
17391748
CORINFO_METHOD_HANDLE restoreExecutionContextMethHnd;
1749+
CORINFO_METHOD_HANDLE captureContinuationContextMethHnd;
17401750
};
17411751

17421752
// Flags passed from JIT to runtime.

src/runtime/src/coreclr/jit/async.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,13 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
10401040
block->getTryIndex(), layout.ExceptionGCDataIndex);
10411041
}
10421042

1043+
if (call->GetAsyncInfo().ContinuationContextHandling == ContinuationContextHandling::ContinueOnCapturedContext)
1044+
{
1045+
layout.ContinuationContextGCDataIndex = layout.GCRefsCount++;
1046+
JITDUMP(" Continuation continues on captured context; context will be at GC@+%02u in GC data\n",
1047+
layout.ContinuationContextGCDataIndex);
1048+
}
1049+
10431050
if (call->GetAsyncInfo().ExecutionContextHandling == ExecutionContextHandling::AsyncSaveAndRestore)
10441051
{
10451052
layout.ExecContextGCDataIndex = layout.GCRefsCount++;
@@ -1200,13 +1207,16 @@ BasicBlock* AsyncTransformation::CreateSuspension(
12001207
LIR::AsRange(suspendBB).InsertAtEnd(LIR::SeqTree(m_comp, storeState));
12011208

12021209
// Fill in 'flags'
1203-
unsigned continuationFlags = 0;
1210+
const AsyncCallInfo& callInfo = call->GetAsyncInfo();
1211+
unsigned continuationFlags = 0;
12041212
if (layout.ReturnInGCData)
12051213
continuationFlags |= CORINFO_CONTINUATION_RESULT_IN_GCDATA;
12061214
if (block->hasTryIndex())
12071215
continuationFlags |= CORINFO_CONTINUATION_NEEDS_EXCEPTION;
12081216
if (m_comp->doesMethodHavePatchpoints() || m_comp->opts.IsOSR())
12091217
continuationFlags |= CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA;
1218+
if (callInfo.ContinuationContextHandling == ContinuationContextHandling::ContinueOnThreadPool)
1219+
continuationFlags |= CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL;
12101220

12111221
newContinuation = m_comp->gtNewLclvNode(m_newContinuationVar, TYP_REF);
12121222
unsigned flagsOffset = m_comp->info.compCompHnd->getFieldOffset(m_asyncInfo->continuationFlagsFldHnd);
@@ -1386,6 +1396,51 @@ void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout&
13861396
}
13871397
}
13881398

1399+
if (layout.ContinuationContextGCDataIndex != UINT_MAX)
1400+
{
1401+
// Insert call AsyncHelpers.CaptureContinuationContext(ref
1402+
// newContinuation.GCData[ContinuationContextGCDataIndex], ref newContinuation.Flags).
1403+
GenTree* contextElementPlaceholder = m_comp->gtNewZeroConNode(TYP_BYREF);
1404+
GenTree* flagsPlaceholder = m_comp->gtNewZeroConNode(TYP_BYREF);
1405+
GenTreeCall* captureCall =
1406+
m_comp->gtNewCallNode(CT_USER_FUNC, m_asyncInfo->captureContinuationContextMethHnd, TYP_VOID);
1407+
1408+
captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(flagsPlaceholder));
1409+
captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(contextElementPlaceholder));
1410+
1411+
m_comp->compCurBB = suspendBB;
1412+
m_comp->fgMorphTree(captureCall);
1413+
1414+
LIR::AsRange(suspendBB).InsertAtEnd(LIR::SeqTree(m_comp, captureCall));
1415+
1416+
// Now replace contextElementPlaceholder with actual address of the context element
1417+
LIR::Use use;
1418+
bool gotUse = LIR::AsRange(suspendBB).TryGetUse(contextElementPlaceholder, &use);
1419+
assert(gotUse);
1420+
1421+
GenTree* objectArr = m_comp->gtNewLclvNode(objectArrLclNum, TYP_REF);
1422+
unsigned offset = OFFSETOF__CORINFO_Array__data + (layout.ContinuationContextGCDataIndex * TARGET_POINTER_SIZE);
1423+
GenTree* contextElementOffset =
1424+
m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, objectArr, m_comp->gtNewIconNode((ssize_t)offset, TYP_I_IMPL));
1425+
1426+
LIR::AsRange(suspendBB).InsertBefore(contextElementPlaceholder, LIR::SeqTree(m_comp, contextElementOffset));
1427+
use.ReplaceWith(contextElementOffset);
1428+
LIR::AsRange(suspendBB).Remove(contextElementPlaceholder);
1429+
1430+
// And now replace flagsPlaceholder with actual address of the flags
1431+
gotUse = LIR::AsRange(suspendBB).TryGetUse(flagsPlaceholder, &use);
1432+
assert(gotUse);
1433+
1434+
newContinuation = m_comp->gtNewLclvNode(m_newContinuationVar, TYP_REF);
1435+
unsigned flagsOffset = m_comp->info.compCompHnd->getFieldOffset(m_asyncInfo->continuationFlagsFldHnd);
1436+
GenTree* flagsOffsetNode = m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, newContinuation,
1437+
m_comp->gtNewIconNode((ssize_t)flagsOffset, TYP_I_IMPL));
1438+
1439+
LIR::AsRange(suspendBB).InsertBefore(flagsPlaceholder, LIR::SeqTree(m_comp, flagsOffsetNode));
1440+
use.ReplaceWith(flagsOffsetNode);
1441+
LIR::AsRange(suspendBB).Remove(flagsPlaceholder);
1442+
}
1443+
13891444
if (layout.ExecContextGCDataIndex != UINT_MAX)
13901445
{
13911446
GenTreeCall* captureExecContext =

src/runtime/src/coreclr/jit/async.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ struct LiveLocalInfo
1818

1919
struct ContinuationLayout
2020
{
21-
unsigned DataSize = 0;
22-
unsigned GCRefsCount = 0;
23-
ClassLayout* ReturnStructLayout = nullptr;
24-
unsigned ReturnSize = 0;
25-
bool ReturnInGCData = false;
26-
unsigned ReturnValDataOffset = UINT_MAX;
27-
unsigned ExceptionGCDataIndex = UINT_MAX;
28-
unsigned ExecContextGCDataIndex = UINT_MAX;
21+
unsigned DataSize = 0;
22+
unsigned GCRefsCount = 0;
23+
ClassLayout* ReturnStructLayout = nullptr;
24+
unsigned ReturnSize = 0;
25+
bool ReturnInGCData = false;
26+
unsigned ReturnValDataOffset = UINT_MAX;
27+
unsigned ExceptionGCDataIndex = UINT_MAX;
28+
unsigned ExecContextGCDataIndex = UINT_MAX;
29+
unsigned ContinuationContextGCDataIndex = UINT_MAX;
2930
const jitstd::vector<LiveLocalInfo>& Locals;
3031

3132
explicit ContinuationLayout(const jitstd::vector<LiveLocalInfo>& locals)

src/runtime/src/coreclr/jit/block.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,8 @@ void BasicBlock::dspFlags() const
502502
{BBF_HAS_CALL, "hascall"},
503503
{BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY, "xentry"},
504504
{BBF_GC_SAFE_POINT, "gcsafe"},
505-
{BBF_HAS_IDX_LEN, "idxlen"},
506-
{BBF_HAS_MD_IDX_LEN, "mdidxlen"},
507505
{BBF_HAS_NEWOBJ, "newobj"},
508506
{BBF_HAS_NEWARR, "newarr"},
509-
{BBF_HAS_NULLCHECK, "nullcheck"},
510507
{BBF_BACKWARD_JUMP, "bwd"},
511508
{BBF_BACKWARD_JUMP_TARGET, "bwd-target"},
512509
{BBF_BACKWARD_JUMP_SOURCE, "bwd-src"},

src/runtime/src/coreclr/jit/block.h

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -428,48 +428,45 @@ enum BasicBlockFlags : uint64_t
428428
BBF_NEEDS_GCPOLL = MAKE_BBFLAG( 6), // BB may need a GC poll because it uses the slow tail call helper
429429
BBF_CLONED_FINALLY_BEGIN = MAKE_BBFLAG( 7), // First block of a cloned finally region
430430
BBF_CLONED_FINALLY_END = MAKE_BBFLAG( 8), // Last block of a cloned finally region
431-
BBF_HAS_NULLCHECK = MAKE_BBFLAG( 9), // BB contains a null check
432-
BBF_HAS_SUPPRESSGC_CALL = MAKE_BBFLAG(10), // BB contains a call to a method with SuppressGCTransitionAttribute
433-
BBF_RUN_RARELY = MAKE_BBFLAG(11), // BB is rarely run (catch clauses, blocks with throws etc)
434-
BBF_HAS_LABEL = MAKE_BBFLAG(12), // BB needs a label
435-
BBF_LOOP_ALIGN = MAKE_BBFLAG(13), // Block is lexically the first block in a loop we intend to align.
436-
BBF_HAS_ALIGN = MAKE_BBFLAG(14), // BB ends with 'align' instruction
437-
BBF_HAS_JMP = MAKE_BBFLAG(15), // BB executes a JMP instruction (instead of return)
438-
BBF_GC_SAFE_POINT = MAKE_BBFLAG(16), // BB has a GC safe point (e.g. a call)
439-
BBF_HAS_IDX_LEN = MAKE_BBFLAG(17), // BB contains simple index or length expressions on an SD array local var.
440-
BBF_HAS_MD_IDX_LEN = MAKE_BBFLAG(18), // BB contains simple index, length, or lower bound expressions on an MD array local var.
441-
BBF_HAS_MDARRAYREF = MAKE_BBFLAG(19), // Block has a multi-dimensional array reference
442-
BBF_HAS_NEWOBJ = MAKE_BBFLAG(20), // BB contains 'new' of an object type.
443-
444-
BBF_RETLESS_CALL = MAKE_BBFLAG(21), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
431+
BBF_HAS_SUPPRESSGC_CALL = MAKE_BBFLAG( 9), // BB contains a call to a method with SuppressGCTransitionAttribute
432+
BBF_RUN_RARELY = MAKE_BBFLAG(10), // BB is rarely run (catch clauses, blocks with throws etc)
433+
BBF_HAS_LABEL = MAKE_BBFLAG(11), // BB needs a label
434+
BBF_LOOP_ALIGN = MAKE_BBFLAG(12), // Block is lexically the first block in a loop we intend to align.
435+
BBF_HAS_ALIGN = MAKE_BBFLAG(13), // BB ends with 'align' instruction
436+
BBF_HAS_JMP = MAKE_BBFLAG(14), // BB executes a JMP instruction (instead of return)
437+
BBF_GC_SAFE_POINT = MAKE_BBFLAG(15), // BB has a GC safe point (e.g. a call)
438+
BBF_HAS_MDARRAYREF = MAKE_BBFLAG(16), // Block has a multi-dimensional array reference
439+
BBF_HAS_NEWOBJ = MAKE_BBFLAG(17), // BB contains 'new' of an object type.
440+
441+
BBF_RETLESS_CALL = MAKE_BBFLAG(18), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
445442
// BBJ_CALLFINALLYRET); see isBBCallFinallyPair().
446-
BBF_COLD = MAKE_BBFLAG(22), // BB is cold
447-
BBF_PROF_WEIGHT = MAKE_BBFLAG(23), // BB weight is computed from profile data
448-
BBF_KEEP_BBJ_ALWAYS = MAKE_BBFLAG(24), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
443+
BBF_COLD = MAKE_BBFLAG(19), // BB is cold
444+
BBF_PROF_WEIGHT = MAKE_BBFLAG(20), // BB weight is computed from profile data
445+
BBF_KEEP_BBJ_ALWAYS = MAKE_BBFLAG(21), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
449446
// as BBJ_ALWAYS. Used on x86 for the final step block out of a finally.
450-
BBF_HAS_CALL = MAKE_BBFLAG(25), // BB contains a call
451-
BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(26), // Block is dominated by exceptional entry.
452-
BBF_BACKWARD_JUMP = MAKE_BBFLAG(27), // BB is surrounded by a backward jump/switch arc
453-
BBF_BACKWARD_JUMP_SOURCE = MAKE_BBFLAG(28), // Block is a source of a backward jump
454-
BBF_BACKWARD_JUMP_TARGET = MAKE_BBFLAG(29), // Block is a target of a backward jump
455-
BBF_PATCHPOINT = MAKE_BBFLAG(30), // Block is a patchpoint
456-
BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(31), // Block is a partial compilation patchpoint
457-
BBF_HAS_HISTOGRAM_PROFILE = MAKE_BBFLAG(32), // BB contains a call needing a histogram profile
458-
BBF_TAILCALL_SUCCESSOR = MAKE_BBFLAG(33), // BB has pred that has potential tail call
459-
BBF_RECURSIVE_TAILCALL = MAKE_BBFLAG(34), // Block has recursive tailcall that may turn into a loop
460-
BBF_NO_CSE_IN = MAKE_BBFLAG(35), // Block should kill off any incoming CSE
461-
BBF_CAN_ADD_PRED = MAKE_BBFLAG(36), // Ok to add pred edge to this block, even when "safe" edge creation disabled
462-
BBF_HAS_VALUE_PROFILE = MAKE_BBFLAG(37), // Block has a node that needs a value probing
463-
BBF_HAS_NEWARR = MAKE_BBFLAG(38), // BB contains 'new' of an array type.
464-
BBF_MAY_HAVE_BOUNDS_CHECKS = MAKE_BBFLAG(39), // BB *likely* has a bounds check (after rangecheck phase).
465-
BBF_ASYNC_RESUMPTION = MAKE_BBFLAG(40), // Block is a resumption block in an async method
447+
BBF_HAS_CALL = MAKE_BBFLAG(22), // BB contains a call
448+
BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(23), // Block is dominated by exceptional entry.
449+
BBF_BACKWARD_JUMP = MAKE_BBFLAG(24), // BB is surrounded by a backward jump/switch arc
450+
BBF_BACKWARD_JUMP_SOURCE = MAKE_BBFLAG(25), // Block is a source of a backward jump
451+
BBF_BACKWARD_JUMP_TARGET = MAKE_BBFLAG(26), // Block is a target of a backward jump
452+
BBF_PATCHPOINT = MAKE_BBFLAG(27), // Block is a patchpoint
453+
BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(28), // Block is a partial compilation patchpoint
454+
BBF_HAS_HISTOGRAM_PROFILE = MAKE_BBFLAG(29), // BB contains a call needing a histogram profile
455+
BBF_TAILCALL_SUCCESSOR = MAKE_BBFLAG(30), // BB has pred that has potential tail call
456+
BBF_RECURSIVE_TAILCALL = MAKE_BBFLAG(31), // Block has recursive tailcall that may turn into a loop
457+
BBF_NO_CSE_IN = MAKE_BBFLAG(32), // Block should kill off any incoming CSE
458+
BBF_CAN_ADD_PRED = MAKE_BBFLAG(33), // Ok to add pred edge to this block, even when "safe" edge creation disabled
459+
BBF_HAS_VALUE_PROFILE = MAKE_BBFLAG(34), // Block has a node that needs a value probing
460+
BBF_HAS_NEWARR = MAKE_BBFLAG(35), // BB contains 'new' of an array type.
461+
BBF_MAY_HAVE_BOUNDS_CHECKS = MAKE_BBFLAG(36), // BB *likely* has a bounds check (after rangecheck phase).
462+
BBF_ASYNC_RESUMPTION = MAKE_BBFLAG(37), // Block is a resumption block in an async method
466463

467464
// The following are sets of flags.
468465

469466
// Flags to update when two blocks are compacted
470467

471-
BBF_COMPACT_UPD = BBF_GC_SAFE_POINT | BBF_NEEDS_GCPOLL | BBF_HAS_JMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_BACKWARD_JUMP | \
472-
BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
468+
BBF_COMPACT_UPD = BBF_GC_SAFE_POINT | BBF_NEEDS_GCPOLL | BBF_HAS_JMP | BBF_BACKWARD_JUMP | \
469+
BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
473470

474471
// Flags a block should not have had before it is split.
475472

@@ -484,18 +481,18 @@ enum BasicBlockFlags : uint64_t
484481

485482
// Flags gained by the bottom block when a block is split.
486483
// Note, this is a conservative guess.
487-
// For example, the bottom block might or might not have BBF_HAS_NULLCHECK, but we assume it has BBF_HAS_NULLCHECK.
484+
// For example, the bottom block might or might not have BBF_HAS_NEWARR, but we assume it has BBF_HAS_NEWARR.
488485
// TODO: Should BBF_RUN_RARELY be added to BBF_SPLIT_GAINED ?
489486

490-
BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_PROF_WEIGHT | BBF_HAS_NEWARR | \
491-
BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END | BBF_HAS_NULLCHECK | BBF_HAS_HISTOGRAM_PROFILE | BBF_HAS_VALUE_PROFILE | BBF_HAS_MDARRAYREF | BBF_NEEDS_GCPOLL | BBF_MAY_HAVE_BOUNDS_CHECKS | BBF_ASYNC_RESUMPTION,
487+
BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_PROF_WEIGHT | BBF_HAS_NEWARR | \
488+
BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END | BBF_HAS_HISTOGRAM_PROFILE | BBF_HAS_VALUE_PROFILE | BBF_HAS_MDARRAYREF | BBF_NEEDS_GCPOLL | BBF_MAY_HAVE_BOUNDS_CHECKS | BBF_ASYNC_RESUMPTION,
492489

493490
// Flags that must be propagated to a new block if code is copied from a block to a new block. These are flags that
494491
// limit processing of a block if the code in question doesn't exist. This is conservative; we might not
495492
// have actually copied one of these type of tree nodes, but if we only copy a portion of the block's statements,
496493
// we don't know (unless we actually pay close attention during the copy).
497494

498-
BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
495+
BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
499496
};
500497

501498
FORCEINLINE

src/runtime/src/coreclr/jit/codegenarm.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ bool CodeGen::genInstrWithConstant(
6161
{
6262
case INS_add:
6363
case INS_sub:
64+
if (imm < 0)
65+
{
66+
imm = -imm;
67+
ins = (ins == INS_add) ? INS_sub : INS_add;
68+
}
6469
immFitsInIns = validImmForInstr(ins, (target_ssize_t)imm, flags);
6570
break;
6671

src/runtime/src/coreclr/jit/compiler.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10506,20 +10506,18 @@ var_types Compiler::gtTypeForNullCheck(GenTree* tree)
1050610506
//
1050710507
// Arguments:
1050810508
// tree - the node to change;
10509-
// block - basic block of the node.
1051010509
//
1051110510
// Notes:
1051210511
// the function should not be called after lowering for platforms that do not support
1051310512
// emitting NULLCHECK nodes, like arm32. Use `Lowering::TransformUnusedIndirection`
1051410513
// that handles it and calls this function when appropriate.
1051510514
//
10516-
void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block)
10515+
void Compiler::gtChangeOperToNullCheck(GenTree* tree)
1051710516
{
1051810517
assert(tree->OperIs(GT_IND, GT_BLK));
1051910518
tree->ChangeOper(GT_NULLCHECK);
1052010519
tree->ChangeType(gtTypeForNullCheck(tree));
1052110520
tree->SetIndirExceptionFlags(this);
10522-
block->SetFlags(BBF_HAS_NULLCHECK);
1052310521
optMethodFlags |= OMF_HAS_NULLCHECK;
1052410522
}
1052510523

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy