Skip to content

Commit c1b4ef2

Browse files
authored
Merge branch 'main' into browser_ep_sampling
2 parents 55d55f5 + 97a8af9 commit c1b4ef2

File tree

20 files changed

+52
-265
lines changed

20 files changed

+52
-265
lines changed

src/coreclr/jit/codegen.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,6 @@ class CodeGen final : public CodeGenInterface
425425
void genOSRSaveRemainingCalleeSavedRegisters();
426426
#endif // TARGET_AMD64
427427

428-
#if defined(TARGET_RISCV64)
429-
void genStackProbe(ssize_t frameSize, regNumber rOffset, regNumber rLimit, regNumber rPageSize);
430-
#endif
431-
432428
void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn);
433429

434430
void genPoisonFrame(regMaskTP bbRegLiveIn);

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 21 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,7 +1627,7 @@ void CodeGen::genLclHeap(GenTree* tree)
16271627
// The SP might already be in the guard page, so we must touch it BEFORE
16281628
// the alloc, not after.
16291629

1630-
// ld_w r0, 0(SP)
1630+
// tickle the page - this triggers a page fault when on the guard page
16311631
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, REG_SP, 0);
16321632

16331633
lastTouchDelta = amount;
@@ -1672,8 +1672,7 @@ void CodeGen::genLclHeap(GenTree* tree)
16721672
// and localloc size is a multiple of STACK_ALIGN.
16731673

16741674
// Loop:
1675-
ssize_t imm = -16;
1676-
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, imm);
1675+
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -16);
16771676

16781677
emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, REG_SPBASE, 8);
16791678
emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, REG_SPBASE, 0);
@@ -1685,8 +1684,8 @@ void CodeGen::genLclHeap(GenTree* tree)
16851684

16861685
emit->emitIns_R_R_I(INS_addi, emitActualTypeSize(type), regCnt, regCnt, -16);
16871686

1688-
assert(imm == (-4 << 2)); // goto loop.
1689-
emit->emitIns_R_R_I(INS_bne, EA_PTRSIZE, regCnt, REG_R0, (-4 << 2));
1687+
// goto Loop
1688+
emit->emitIns_R_R_I(INS_bne, EA_PTRSIZE, regCnt, REG_R0, -4 << 2);
16901689

16911690
lastTouchDelta = 0;
16921691
}
@@ -1700,7 +1699,6 @@ void CodeGen::genLclHeap(GenTree* tree)
17001699
// case SP is on the last byte of the guard page. Thus you must
17011700
// touch SP-0 first not SP-0x1000.
17021701
//
1703-
// This is similar to the prolog code in CodeGen::genAllocLclFrame().
17041702
//
17051703
// Note that we go through a few hoops so that SP never points to
17061704
// illegal pages at any time during the tickling process.
@@ -1711,23 +1709,20 @@ void CodeGen::genLclHeap(GenTree* tree)
17111709
// addi regCnt, REG_R0, 0
17121710
//
17131711
// Skip:
1714-
// lui regTmp, eeGetPageSize()>>12
1712+
// lui regPageSize, eeGetPageSize()>>12
1713+
// addi regTmp, SP, 0
17151714
// Loop:
1716-
// lw r0, 0(SP) // tickle the page - read from the page
1717-
// sub RA, SP, regTmp // decrement SP by eeGetPageSize()
1718-
// bltu RA, regCnt, Done
1719-
// sub SP, SP,regTmp
1720-
// j Loop
1715+
// lw r0, 0(regTmp) // tickle the page - read from the page
1716+
// sub regTmp, regTmp, regPageSize
1717+
// bgeu regTmp, regCnt, Loop
17211718
//
17221719
// Done:
1723-
// mov SP, regCnt
1720+
// addi SP, regCnt, 0
17241721
//
17251722

17261723
if (tempReg == REG_NA)
17271724
tempReg = internalRegisters.Extract(tree);
17281725

1729-
regNumber rPageSize = internalRegisters.GetSingle(tree);
1730-
17311726
assert(regCnt != tempReg);
17321727
emit->emitIns_R_R_R(INS_sltu, EA_PTRSIZE, tempReg, REG_SPBASE, regCnt);
17331728

@@ -1738,35 +1733,24 @@ void CodeGen::genLclHeap(GenTree* tree)
17381733
emit->emitIns_R_R_I(INS_beq, EA_PTRSIZE, tempReg, REG_R0, 2 << 2);
17391734
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, regCnt, REG_R0, 0);
17401735

1741-
emit->emitIns_R_I(INS_lui, EA_PTRSIZE, rPageSize, pageSize >> 12);
1742-
1743-
// genDefineTempLabel(loop);
1744-
1745-
// tickle the page - Read from the updated SP - this triggers a page fault when on the guard page
1746-
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, REG_SPBASE, 0);
1747-
1748-
// decrement SP by eeGetPageSize()
1749-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, tempReg, REG_SPBASE, rPageSize);
1750-
1751-
assert(rPageSize != tempReg);
1752-
1753-
ssize_t imm = 3 << 2; // goto done.
1754-
emit->emitIns_R_R_I(INS_bltu, EA_PTRSIZE, tempReg, regCnt, imm);
1736+
regNumber rPageSize = internalRegisters.GetSingle(tree);
17551737

1756-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, rPageSize);
1738+
noway_assert(rPageSize != tempReg);
17571739

1758-
imm = -4 << 2;
1759-
// Jump to loop and tickle new stack address
1760-
emit->emitIns_I(INS_j, EA_PTRSIZE, imm);
1740+
emit->emitIns_R_I(INS_lui, EA_PTRSIZE, rPageSize, pageSize >> 12);
1741+
regSet.verifyRegUsed(rPageSize);
1742+
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, tempReg, REG_SPBASE, 0);
17611743

1762-
// Done with stack tickle loop
1763-
// genDefineTempLabel(done);
1744+
// tickle the page - this triggers a page fault when on the guard page
1745+
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, tempReg, 0);
1746+
emit->emitIns_R_R_R(INS_sub, EA_4BYTE, tempReg, tempReg, rPageSize);
17641747

1765-
// Now just move the final value to SP
1766-
emit->emitIns_R_R_I(INS_ori, EA_PTRSIZE, REG_SPBASE, regCnt, 0);
1748+
emit->emitIns_R_R_I(INS_bgeu, EA_PTRSIZE, tempReg, regCnt, -2 << 2);
17671749

17681750
// lastTouchDelta is dynamic, and can be up to a page. So if we have outgoing arg space,
17691751
// we're going to assume the worst and probe.
1752+
// Move the final value to SP
1753+
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, regCnt, 0);
17701754
}
17711755

17721756
ALLOC_DONE:
@@ -6672,175 +6656,6 @@ void CodeGen::genEstablishFramePointer(int delta, bool reportUnwindData)
66726656
};
66736657
}
66746658

6675-
//------------------------------------------------------------------------
6676-
// genStackProbe: Probe the stack without changing it
6677-
//
6678-
// Notes:
6679-
// This function is using loop to probe each memory page.
6680-
//
6681-
// Arguments:
6682-
// frameSize - total frame size
6683-
// rOffset - usually initial register number
6684-
// rLimit - an extra register for comparison
6685-
// rPageSize - register for storing page size
6686-
//
6687-
void CodeGen::genStackProbe(ssize_t frameSize, regNumber rOffset, regNumber rLimit, regNumber rPageSize)
6688-
{
6689-
// make sure frameSize safely fits within 4 bytes
6690-
noway_assert((ssize_t)(int)frameSize == (ssize_t)frameSize);
6691-
6692-
const target_size_t pageSize = compiler->eeGetPageSize();
6693-
6694-
// According to RISC-V Privileged ISA page size should be equal 4KiB
6695-
noway_assert(pageSize == 0x1000);
6696-
6697-
emitter* emit = GetEmitter();
6698-
6699-
emit->emitLoadImmediate(EA_PTRSIZE, rLimit, -frameSize);
6700-
regSet.verifyRegUsed(rLimit);
6701-
6702-
emit->emitIns_R_R_R(INS_add, EA_PTRSIZE, rLimit, rLimit, REG_SPBASE);
6703-
6704-
emit->emitIns_R_I(INS_lui, EA_PTRSIZE, rPageSize, pageSize >> 12);
6705-
regSet.verifyRegUsed(rPageSize);
6706-
6707-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, rOffset, REG_SPBASE, rPageSize);
6708-
6709-
// Loop:
6710-
// tickle the page - Read from the updated SP - this triggers a page fault when on the guard page
6711-
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, rOffset, 0);
6712-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, rOffset, rOffset, rPageSize);
6713-
6714-
// each instr is 4 bytes
6715-
// if (rOffset >= rLimit) goto Loop;
6716-
emit->emitIns_R_R_I(INS_bge, EA_PTRSIZE, rOffset, rLimit, -2 << 2);
6717-
}
6718-
6719-
//------------------------------------------------------------------------
6720-
// genAllocLclFrame: Probe the stack.
6721-
//
6722-
// Notes:
6723-
// This only does the probing; allocating the frame is done when callee-saved registers are saved.
6724-
// This is done before anything has been pushed. The previous frame might have a large outgoing argument
6725-
// space that has been allocated, but the lowest addresses have not been touched. Our frame setup might
6726-
// not touch up to the first 504 bytes. This means we could miss a guard page. On Windows, however,
6727-
// there are always three guard pages, so we will not miss them all. On Linux, there is only one guard
6728-
// page by default, so we need to be more careful. We do an extra probe if we might not have probed
6729-
// recently enough. That is, if a call and prolog establishment might lead to missing a page. We do this
6730-
// on Windows as well just to be consistent, even though it should not be necessary.
6731-
//
6732-
// Arguments:
6733-
// frameSize - the size of the stack frame being allocated.
6734-
// initReg - register to use as a scratch register.
6735-
// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
6736-
// this call sets 'initReg' to a non-zero value. Otherwise, it is unchanged.
6737-
// maskArgRegsLiveIn - incoming argument registers that are currently live.
6738-
//
6739-
// Return value:
6740-
// None
6741-
//
6742-
void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn)
6743-
{
6744-
assert(compiler->compGeneratingProlog);
6745-
6746-
if (frameSize == 0)
6747-
{
6748-
return;
6749-
}
6750-
6751-
// According to RISC-V Privileged ISA page size should be equal 4KiB
6752-
const target_size_t pageSize = compiler->eeGetPageSize();
6753-
6754-
assert(!compiler->info.compPublishStubParam || (REG_SECRET_STUB_PARAM != initReg));
6755-
6756-
target_size_t lastTouchDelta = 0;
6757-
6758-
emitter* emit = GetEmitter();
6759-
6760-
// Emit the following sequence to 'tickle' the pages.
6761-
// Note it is important that stack pointer not change until this is complete since the tickles
6762-
// could cause a stack overflow, and we need to be able to crawl the stack afterward
6763-
// (which means the stack pointer needs to be known).
6764-
6765-
if (frameSize < pageSize)
6766-
{
6767-
// no probe needed
6768-
lastTouchDelta = frameSize;
6769-
}
6770-
else if (frameSize < 3 * pageSize)
6771-
{
6772-
// between 1 and 3 pages we will probe each page without a loop,
6773-
// because it is faster that way and doesn't cost us much
6774-
lastTouchDelta = frameSize;
6775-
6776-
for (target_size_t probeOffset = pageSize; probeOffset <= frameSize; probeOffset += pageSize)
6777-
{
6778-
emit->emitIns_R_I(INS_lui, EA_PTRSIZE, initReg, probeOffset >> 12);
6779-
regSet.verifyRegUsed(initReg);
6780-
6781-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, initReg, REG_SPBASE, initReg);
6782-
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, initReg, 0);
6783-
6784-
lastTouchDelta -= pageSize;
6785-
}
6786-
6787-
assert(pInitRegZeroed != nullptr);
6788-
*pInitRegZeroed = false; // The initReg does not contain zero
6789-
6790-
assert(lastTouchDelta == frameSize % pageSize);
6791-
compiler->unwindPadding();
6792-
}
6793-
else
6794-
{
6795-
// probe each page, that we need to allocate large stack frame
6796-
assert(frameSize >= 3 * pageSize);
6797-
6798-
regMaskTP availMask = RBM_ALLINT & (regSet.rsGetModifiedRegsMask() | ~RBM_INT_CALLEE_SAVED);
6799-
availMask &= ~maskArgRegsLiveIn; // Remove all of the incoming argument registers
6800-
// as they are currently live
6801-
availMask &= ~genRegMask(initReg); // Remove the pre-calculated initReg
6802-
6803-
noway_assert(availMask != RBM_NONE);
6804-
6805-
regMaskTP regMask = genFindLowestBit(availMask);
6806-
regNumber rLimit = genRegNumFromMask(regMask);
6807-
6808-
availMask &= ~regMask; // Remove rLimit register
6809-
6810-
noway_assert(availMask != RBM_NONE);
6811-
6812-
regMask = genFindLowestBit(availMask);
6813-
regNumber rPageSize = genRegNumFromMask(regMask);
6814-
6815-
genStackProbe((ssize_t)frameSize, initReg, rLimit, rPageSize);
6816-
6817-
assert(pInitRegZeroed != nullptr);
6818-
*pInitRegZeroed = false; // The initReg does not contain zero
6819-
6820-
lastTouchDelta = frameSize % pageSize;
6821-
compiler->unwindPadding();
6822-
}
6823-
6824-
#if STACK_PROBE_BOUNDARY_THRESHOLD_BYTES != 0
6825-
// if the last page was too far, we will make an extra probe at the bottom
6826-
if (lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > pageSize)
6827-
{
6828-
assert(lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES < pageSize << 1);
6829-
6830-
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, initReg, REG_R0, frameSize);
6831-
regSet.verifyRegUsed(initReg);
6832-
6833-
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, initReg, REG_SPBASE, initReg);
6834-
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, initReg, 0);
6835-
6836-
assert(pInitRegZeroed != nullptr);
6837-
*pInitRegZeroed = false; // The initReg does not contain zero
6838-
6839-
compiler->unwindPadding();
6840-
}
6841-
#endif
6842-
}
6843-
68446659
void CodeGen::genJumpToThrowHlpBlk_la(
68456660
SpecialCodeKind codeKind, instruction ins, regNumber reg1, BasicBlock* failBlk, regNumber reg2)
68466661
{

src/coreclr/jit/emitriscv64.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,31 +3310,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
33103310
if (vt == TYP_REF || vt == TYP_BYREF)
33113311
emitGCvarDeadUpd(adr + ofs, dst2 DEBUG_ARG(varNum));
33123312
}
3313-
// if (emitInsWritesToLclVarStackLocPair(id))
3314-
//{
3315-
// unsigned ofs2 = ofs + TARGET_POINTER_SIZE;
3316-
// if (id->idGCrefReg2() != GCT_NONE)
3317-
// {
3318-
// emitGCvarLiveUpd(adr + ofs2, varNum, id->idGCrefReg2(), *dp);
3319-
// }
3320-
// else
3321-
// {
3322-
// // If the type of the local is a gc ref type, update the liveness.
3323-
// var_types vt;
3324-
// if (varNum >= 0)
3325-
// {
3326-
// // "Regular" (non-spill-temp) local.
3327-
// vt = var_types(emitComp->lvaTable[varNum].lvType);
3328-
// }
3329-
// else
3330-
// {
3331-
// TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum);
3332-
// vt = tmpDsc->tdTempType();
3333-
// }
3334-
// if (vt == TYP_REF || vt == TYP_BYREF)
3335-
// emitGCvarDeadUpd(adr + ofs2, *dp);
3336-
// }
3337-
//}
33383313
}
33393314

33403315
#ifdef DEBUG

src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayRecord.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ private protected ArrayRecord(ArrayInfo arrayInfo)
2525
}
2626

2727
/// <summary>
28-
/// When overridden in a derived class, gets a buffer of integers that represent the number of elements in every dimension.
28+
/// When overridden in a derived class, gets a buffer of integers that represent the number of elements in each dimension.
2929
/// </summary>
30-
/// <value>A buffer of integers that represent the number of elements in every dimension.</value>
30+
/// <value>A buffer of integers that represent the number of elements in each dimension.</value>
3131
public abstract ReadOnlySpan<int> Lengths { get; }
3232

3333
/// <summary>
@@ -65,9 +65,8 @@ internal bool IsJagged
6565
/// <returns>An array filled with the data provided in the serialized records.</returns>
6666
/// <exception cref="InvalidOperationException"><paramref name="expectedArrayType" /> does not match the data from the payload.</exception>
6767
/// <remarks>
68-
/// Check the total length of the array by using <see cref="Lengths"/> property before calling this method,
69-
/// as an attacker could have sent you a small payload that will require to allocate a very large array
70-
/// and potentially cause <see cref="OutOfMemoryException"/> and Denial of Service.
68+
/// Before calling this method, check the total length of the array by using the <see cref="Lengths"/> property.
69+
/// An attacker could have sent a small payload that requires allocation of a very large array, which could cause <see cref="OutOfMemoryException"/> and denial of service.
7170
/// </remarks>
7271
[RequiresDynamicCode("The code for an array of the specified type might not be available.")]
7372
public Array GetArray(Type expectedArrayType, bool allowNulls = true)

src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleObjectRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace System.Formats.Nrbf;
1111

1212
/// <summary>
13-
/// Represents a single dimensional array of <see cref="object" />.
13+
/// Represents a single-dimensional array of <see cref="object" />.
1414
/// </summary>
1515
/// <remarks>
1616
/// ArraySingleObject records are described in <see href="https://learn.microsoft.com/openspecs/windows_protocols/ms-nrbf/982b2f50-6367-402a-aaf2-44ee96e2a5e0">[MS-NRBF] 2.4.3.2</see>.

src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace System.Formats.Nrbf;
1111

1212
/// <summary>
13-
/// Represents a single dimensional array of <see langword="string" />.
13+
/// Represents a single-dimensional array of <see langword="string" />.
1414
/// </summary>
1515
/// <remarks>
1616
/// ArraySingleString records are described in <see href="https://learn.microsoft.com/openspecs/windows_protocols/ms-nrbf/3d98fd60-d2b4-448a-ac0b-3cd8dea41f9d">[MS-NRBF] 2.4.3.4</see>.

src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ClassRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private protected ClassRecord(ClassInfo classInfo, MemberTypeInfo memberTypeInfo
4343
/// Checks if the member with the given name was present in the payload.
4444
/// </summary>
4545
/// <param name="memberName">The name of the member.</param>
46-
/// <returns><see langword="true" /> if it was present, otherwise <see langword="false" />.</returns>
46+
/// <returns><see langword="true" /> if the member was present, otherwise <see langword="false" />.</returns>
4747
/// <remarks>
4848
/// It's recommended to use this method when dealing with payload that might contain
4949
/// different versions of the same type.

src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ClassTypeInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace System.Formats.Nrbf;
1010

1111
/// <summary>
12-
/// Identifies a class by its name and library id.
12+
/// Identifies a class by its name and library ID.
1313
/// </summary>
1414
/// <remarks>
1515
/// ClassTypeInfo structures are described in <see href="https://learn.microsoft.com/openspecs/windows_protocols/ms-nrbf/844b24dd-9f82-426e-9b98-05334307a239">[MS-NRBF] 2.1.1.8</see>.

0 commit comments

Comments
 (0)