ronantakizawa/codereview-bench huggingface dataset:
Repository: dotnet/runtime
File: src/coreclr/jit/codegenwasm.cpp (C++)

Code before:
    // TODO-WASM-CQ: do not emit "return" in case this is the last block
    instGen(INS_return);
    // TODO-WASM: this condition will not be sufficient if we have funclet to determine if we're at the end of
    // codegen for a method. Revisit later.
    if (block->IsLast()) 
    {
        instGen(INS_end);
    }
}

void CodeGen::genCaptureFuncletPrologEpilogInfo()
{
}

void CodeGen::genFuncletProlog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFuncletProlog()\n");
    }
#endif

    NYI_WASM("genFuncletProlog");
}

void CodeGen::genFuncletEpilog()
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFuncletEpilog()\n");
    }
#endif

    NYI_WASM("genFuncletEpilog");
}

//------------------------------------------------------------------------
// getBlockIndex: return the index of this block in the linear block
//   order
//
// Arguments:
//   block - block in question
//
// Returns:
//   index of block
//
static unsigned getBlockIndex(BasicBlock* block)
{
    return block->bbPreorderNum;

Review comment (bug):
```suggestion
    if (block->IsLast() || bbIsFuncletBeg(block->Next()))
    {
        instGen(INS_end);
    }
    else
    {
        instGen(INS_return);
    }
```
(And remove the TODO above).

Notably, this is still not quite enough because the method can end up on a non-epilogue-generating basic block (e. g. an infinite loop, or an always-throw call). To handle those cases we will need to add the logical equivalent of:
```
if (isEndOfFunctionOrFunclet(block) && !inspiredEpilogue(block))
   instGen(INS_end);
```
To `genEmitEndBlock`. But no need to do this in this change.

Code after:
    {
        printf("*************** In genFnEpilog()\n");
    }
#endif // DEBUG

    ScopedSetVariable<bool> _setGeneratingEpilog(&compiler->compGeneratingEpilog, true);

#ifdef DEBUG
    if (compiler->opts.dspCode)
        printf("\n__epilog:\n");
#endif // DEBUG

    bool jmpEpilog = block->HasFlag(BBF_HAS_JMP);

    if (jmpEpilog)
    {
        NYI_WASM("genFnEpilog: jmpEpilog");
    }

    // TODO-WASM: shadow stack maintenance
    // TODO-WASM: we need to handle the end-of-function case if we reach the end of a codegen for a function
    // and do NOT have an epilog. In those cases we currently will not emit an end instruction.
    if (block->IsLast() || compiler->bbIsFuncletBeg(block->Next()))
    {
        instGen(INS_end);
    }
    else
    {
        instGen(INS_return);
    }
}

void CodeGen::genCaptureFuncletPrologEpilogInfo()
{
}

void CodeGen::genFuncletProlog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFuncletProlog()\n");
    }
#endif

    NYI_WASM("genFuncletProlog");
}

void CodeGen::genFuncletEpilog()
{
#ifdef DEBUG
Repository: dotnet/runtime
File: src/coreclr/jit/emitfmtswasm.h (C/C++)

Code before:
};
#undef DEFINE_ID_OPS

#else // !DEFINE_ID_OPS

#ifndef IF_DEF
#error Must define IF_DEF macro before including this file
#endif

//////////////////////////////////////////////////////////////////////////////
//
// enum insFormat   instruction            enum ID_OPS
//                  scheduling
//                  (unused)
//////////////////////////////////////////////////////////////////////////////

IF_DEF(NONE,       IS_NONE, NONE)
IF_DEF(OPCODE,     IS_NONE, NONE) // <opcode>
IF_DEF(BLOCK,      IS_NONE, NONE) // <opcode> <0x40>
IF_DEF(LABEL,      IS_NONE, NONE) // <ULEB128 immediate>
IF_DEF(ULEB128,    IS_NONE, NONE) // <opcode> <ULEB128 immediate>
IF_DEF(SLEB128,    IS_NONE, NONE) // <opcode> <LEB128 immediate (signed)>
IF_DEF(F32,        IS_NONE, NONE) // <opcode> <f32 immediate (stored as 64-bit integer constant)>
IF_DEF(F64,        IS_NONE, NONE) // <opcode> <f64 immediate (stored as 64-bit integer constant)>
IF_DEF(MEMARG,     IS_NONE, NONE) // <opcode> <memarg> (<align> <offset>)
IF_DEF(LOCAL_CNT,  IS_NONE, NONE) // <ULEB128 immediate>
IF_DEF(LOCAL_DECL, IS_NONE, NONE) // <ULEB128 immediate> <byte>

#undef IF_DEF
#endif // !DEFINE_ID_OPS
// clang-format on


Review comment (suggestion):
This should be folded into the same format as `IF_LABEL` (say rename it to `IF_RAW_ULEB128`). It's best for throughput to limit the number of formats.

Code after:
};
#undef DEFINE_ID_OPS

#else // !DEFINE_ID_OPS

#ifndef IF_DEF
#error Must define IF_DEF macro before including this file
#endif

//////////////////////////////////////////////////////////////////////////////
//
// enum insFormat   instruction            enum ID_OPS
//                  scheduling
//                  (unused)
//////////////////////////////////////////////////////////////////////////////

IF_DEF(NONE,        IS_NONE, NONE)
IF_DEF(OPCODE,      IS_NONE, NONE) // <opcode>
IF_DEF(BLOCK,       IS_NONE, NONE) // <opcode> <0x40>
IF_DEF(RAW_ULEB128, IS_NONE, NONE) // <ULEB128 immediate>
IF_DEF(ULEB128,     IS_NONE, NONE) // <opcode> <ULEB128 immediate>
IF_DEF(SLEB128,     IS_NONE, NONE) // <opcode> <LEB128 immediate (signed)>
IF_DEF(F32,         IS_NONE, NONE) // <opcode> <f32 immediate (stored as 64-bit integer constant)>
IF_DEF(F64,         IS_NONE, NONE) // <opcode> <f64 immediate (stored as 64-bit integer constant)>
IF_DEF(MEMARG,      IS_NONE, NONE) // <opcode> <memarg> (<align> <offset>)
IF_DEF(LOCAL_DECL,  IS_NONE, NONE) // <ULEB128 immediate> <byte>

#undef IF_DEF
#endif // !DEFINE_ID_OPS
// clang-format on
Repository: dotnet/runtime
File: src/coreclr/jit/registeropswasm.h (C/C++)

Code before:

enum class WasmValueType : unsigned
{
    Invalid, // This effectively reserves the "0"th type for various sentinels like REG_NA.
    I32,
    I64,
    F32,
    F64,
    Count,
#ifdef TARGET_64BIT
    I = I64,
#else
    I = I32,
#endif
};

static const char *const WasmValueTypeNames[] = {
    "Invalid",
    "i32",
    "i64",
    "f32",
    "f64",
    "Count",
};

inline const char* WasmValueTypeName(WasmValueType type)
{
    static_assert(ArrLen(WasmValueTypeNames) == static_cast<unsigned>(WasmValueType::Count) + 1);
    return WasmValueTypeNames[static_cast<unsigned>(type)];
}

regNumber MakeWasmReg(unsigned index, var_types type);
unsigned  UnpackWasmReg(regNumber reg, WasmValueType* pType = nullptr);
unsigned  WasmRegToIndex(regNumber reg);
bool      genIsValidReg(regNumber reg);
bool      genIsValidIntReg(regNumber reg);
bool      genIsValidIntOrFakeReg(regNumber reg);
bool      genIsValidFloatReg(regNumber reg);


Review comment (refactor):
This (implementation) should be moved to `registeropswasm.cpp` (and `WasmValueTypeNames` can be made a static array local to the function). In general it is an anti-pattern to have arrays of data in headers (since they get duplicated into each object file and may even get duplicated in the binary depending on how careful are you with linkage).

Code after:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

enum class WasmValueType : unsigned
{
    Invalid, // This effectively reserves the "0"th type for various sentinels like REG_NA.
    I32,
    I64,
    F32,
    F64,
    Count,
#ifdef TARGET_64BIT
    I = I64,
#else
    I = I32,
#endif
};

const char* WasmValueTypeName(WasmValueType type);
regNumber   MakeWasmReg(unsigned index, var_types type);
unsigned    UnpackWasmReg(regNumber reg, WasmValueType* pType = nullptr);
unsigned    WasmRegToIndex(regNumber reg);
bool        genIsValidReg(regNumber reg);
bool        genIsValidIntReg(regNumber reg);
bool        genIsValidIntOrFakeReg(regNumber reg);
bool        genIsValidFloatReg(regNumber reg);
Repository: dotnet/runtime
File: src/coreclr/jit/registeropswasm.h (C/C++)

Code before:
{
    Invalid, // This effectively reserves the "0"th type for various sentinels like REG_NA.
    I32,
    I64,
    F32,
    F64,
    Count,
#ifdef TARGET_64BIT
    I = I64,
#else
    I = I32,
#endif
};

static const char *const WasmValueTypeNames[] = {
    "Invalid",
    "i32",
    "i64",
    "f32",
    "f64",
    "Count",
};

inline const char* WasmValueTypeName(WasmValueType type)
{
    static_assert(ArrLen(WasmValueTypeNames) == static_cast<unsigned>(WasmValueType::Count) + 1);
    return WasmValueTypeNames[static_cast<unsigned>(type)];
}

regNumber MakeWasmReg(unsigned index, var_types type);
unsigned  UnpackWasmReg(regNumber reg, WasmValueType* pType = nullptr);
unsigned  WasmRegToIndex(regNumber reg);
bool      genIsValidReg(regNumber reg);
bool      genIsValidIntReg(regNumber reg);
bool      genIsValidIntOrFakeReg(regNumber reg);
bool      genIsValidFloatReg(regNumber reg);


Review comment (suggestion):
We should never see a `WasmValueType type` equal to `WasmValueType::Count`. You can exclude that from printing (e. g. have an assert that `type < WasmValueType::Count`.

Code after:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

enum class WasmValueType : unsigned
{
    Invalid, // This effectively reserves the "0"th type for various sentinels like REG_NA.
    I32,
    I64,
    F32,
    F64,
    Count,
#ifdef TARGET_64BIT
    I = I64,
#else
    I = I32,
#endif
};

const char* WasmValueTypeName(WasmValueType type);
regNumber   MakeWasmReg(unsigned index, var_types type);
unsigned    UnpackWasmReg(regNumber reg, WasmValueType* pType = nullptr);
unsigned    WasmRegToIndex(regNumber reg);
bool        genIsValidReg(regNumber reg);
bool        genIsValidIntReg(regNumber reg);
bool        genIsValidIntOrFakeReg(regNumber reg);
bool        genIsValidFloatReg(regNumber reg);
Repository: dotnet/runtime
File: src/coreclr/jit/codegenwasm.cpp (C++)

Code before:
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFnEpilog()\n");
    }
#endif // DEBUG

    ScopedSetVariable<bool> _setGeneratingEpilog(&compiler->compGeneratingEpilog, true);

#ifdef DEBUG
    if (compiler->opts.dspCode)
        printf("\n__epilog:\n");
#endif // DEBUG

    bool jmpEpilog = block->HasFlag(BBF_HAS_JMP);

    if (jmpEpilog)
    {
        NYI_WASM("genFnEpilog: jmpEpilog");
    }

    // TODO-WASM: shadow stack maintenance
    // TODO-WASM: we need to handle the end-of-function case if we reach the end of a codegen for a function
    // and do NOT have an epilog. In those cases we currently will not emit an end instruction.
    if (block->IsLast() || compiler->bbIsFuncletBeg(block))
    {
        instGen(INS_end);
    }
    else
    {
        instGen(INS_return);
    }
}

void CodeGen::genCaptureFuncletPrologEpilogInfo()
{
}

void CodeGen::genFuncletProlog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFuncletProlog()\n");
    }
#endif

    NYI_WASM("genFuncletProlog");
}


Review comment (suggestion):
```suggestion
    if (block->IsLast() || compiler->bbIsFuncletBeg(block->Next()))
```

Code after:
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFnEpilog()\n");
    }
#endif // DEBUG

    ScopedSetVariable<bool> _setGeneratingEpilog(&compiler->compGeneratingEpilog, true);

#ifdef DEBUG
    if (compiler->opts.dspCode)
        printf("\n__epilog:\n");
#endif // DEBUG

    bool jmpEpilog = block->HasFlag(BBF_HAS_JMP);

    if (jmpEpilog)
    {
        NYI_WASM("genFnEpilog: jmpEpilog");
    }

    // TODO-WASM: shadow stack maintenance
    // TODO-WASM: we need to handle the end-of-function case if we reach the end of a codegen for a function
    // and do NOT have an epilog. In those cases we currently will not emit an end instruction.
    if (block->IsLast() || compiler->bbIsFuncletBeg(block->Next()))
    {
        instGen(INS_end);
    }
    else
    {
        instGen(INS_return);
    }
}

void CodeGen::genCaptureFuncletPrologEpilogInfo()
{
}

void CodeGen::genFuncletProlog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFuncletProlog()\n");
    }
#endif

    NYI_WASM("genFuncletProlog");
}
Repository: dotnet/runtime
File: src/coreclr/jit/codegenwasm.cpp (C++)

Code before:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "jitpch.h"
#ifdef _MSC_VER
#pragma hdrstop
#endif

#include "codegen.h"
#include "fgwasm.h"

void CodeGen::genMarkLabelsForCodegen()
{
    // No work needed here for now.
    // We mark labels as needed in genEmitStartBlock.
}

//------------------------------------------------------------------------
// genWasmLocals: generate wasm locals for all locals
//
// TODO-WASM: pre-declare all "register" locals
void CodeGen::genWasmLocals()
{
    // TODO-WASM: proper local count, local declarations, and shadow stack maintenance
    GetEmitter()->emitIns_I(INS_local_cnt, EA_8BYTE, (unsigned)WasmValueType::Count - 1);
    // Emit 1 local of each supported value type to ensure
    // the declarations can be encoded.
    // TODO-WASM: remove and declare locals based on RA assignments once this is supported.
    int localOffset  = 0;
    int countPerType = 1;
    for (unsigned i = (uint8_t)WasmValueType::Invalid + 1; i < (unsigned)WasmValueType::Count; i++)
    {
        GetEmitter()->emitIns_I_Ty(INS_local_decl, countPerType, static_cast<WasmValueType>(i), localOffset);
        localOffset += countPerType;
    }
}

void CodeGen::genFnEpilog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFnEpilog()\n");
    }

Review comment (suggestion):
```suggestion
// genWasmLocals: generate wasm local declarations
```

Code after:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "jitpch.h"
#ifdef _MSC_VER
#pragma hdrstop
#endif

#include "codegen.h"
#include "fgwasm.h"

void CodeGen::genMarkLabelsForCodegen()
{
    // No work needed here for now.
    // We mark labels as needed in genEmitStartBlock.
}

//------------------------------------------------------------------------
// genWasmLocals: generate wasm local declarations
//
// TODO-WASM: pre-declare all "register" locals
void CodeGen::genWasmLocals()
{
    // TODO-WASM: proper local count, local declarations, and shadow stack maintenance
    GetEmitter()->emitIns_I(INS_local_cnt, EA_8BYTE, (unsigned)WasmValueType::Count - 1);
    // Emit 1 local of each supported value type to ensure
    // the declarations can be encoded.
    // TODO-WASM: remove and declare locals based on RA assignments once this is supported.
    int localOffset  = 0;
    int countPerType = 1;
    for (unsigned i = (uint8_t)WasmValueType::Invalid + 1; i < (unsigned)WasmValueType::Count; i++)
    {
        GetEmitter()->emitIns_I_Ty(INS_local_decl, countPerType, static_cast<WasmValueType>(i), localOffset);
        localOffset += countPerType;
    }
}

void CodeGen::genFnEpilog(BasicBlock* block)
{
#ifdef DEBUG
    if (verbose)
    {
        printf("*************** In genFnEpilog()\n");
    }
Repository: dotnet/runtime
File: src/coreclr/jit/emit.h (C/C++)

Code before:
        ssize_t idacAmdVal;
    };

#endif // TARGET_XARCH

#ifdef TARGET_ARM64
    struct instrDescLclVarPair : instrDesc // contains 2 gc vars to be tracked
    {
        instrDescLclVarPair() = delete;

        emitLclVarAddr iiaLclVar2;
    };

    struct instrDescLclVarPairCns : instrDescCns // contains 2 gc vars to be tracked, with large cons
    {
        instrDescLclVarPairCns() = delete;

        emitLclVarAddr iiaLclVar2;
    };
#endif

#if defined(TARGET_WASM)
    struct instrDescLclVarDecl : instrDesc
    {
        instrDescLclVarDecl() = delete;
        cnsval_ssize_t lclCnt;
        WasmValueType  lclType;

        void idLclType(WasmValueType type)
        {
            lclType = type;
        }

        void idLclCnt(cnsval_ssize_t cnt)
        {
            lclCnt = cnt;
        }
    };
#endif // TARGET_WASM

#ifdef TARGET_RISCV64
    struct instrDescLoadImm : instrDescCns
    {
        instrDescLoadImm() = delete;

        static const int absMaxInsCount = 8;

        instruction ins[absMaxInsCount];
        int32_t     values[absMaxInsCount];
    };
#endif // TARGET_RISCV64

Review comment (suggestion):
This is technically larger than necessary since the local count can't really exceed 32 bits (and `cnsval_ssize_t` is a signed 64 bit number). Base `instrDesc` is 16 bytes, this desc is going to be 32 bytes (due to alignment), but if this field is made to be 32 bits, it can fit into 24 bytes.

(Using an unsigned integer might also get rid of some casts)

Code after:
        ssize_t idacAmdVal;
    };

#endif // TARGET_XARCH

#ifdef TARGET_ARM64
    struct instrDescLclVarPair : instrDesc // contains 2 gc vars to be tracked
    {
        instrDescLclVarPair() = delete;

        emitLclVarAddr iiaLclVar2;
    };

    struct instrDescLclVarPairCns : instrDescCns // contains 2 gc vars to be tracked, with large cons
    {
        instrDescLclVarPairCns() = delete;

        emitLclVarAddr iiaLclVar2;
    };
#endif

#if defined(TARGET_WASM)
    struct instrDescLclVarDecl : instrDesc
    {
        instrDescLclVarDecl() = delete;
        unsigned int  lclCnt;
        WasmValueType lclType;

        void idLclType(WasmValueType type)
        {
            lclType = type;
        }

        void idLclCnt(unsigned int cnt)
        {
            lclCnt = cnt;
        }
    };
#endif // TARGET_WASM

#ifdef TARGET_RISCV64
    struct instrDescLoadImm : instrDescCns
    {
        instrDescLoadImm() = delete;

        static const int absMaxInsCount = 8;

        instruction ins[absMaxInsCount];
        int32_t     values[absMaxInsCount];
    };
#endif // TARGET_RISCV64
Repository: dotnet/runtime
File: src/coreclr/jit/emitriscv64.cpp (C++)

Code before:
static ssize_t DoubleWordSignExtend(ssize_t doubleWord)
{
    static constexpr size_t kLowerSignExtend = static_cast<size_t>(1) << (63 - LowerMaskSize);
    static constexpr size_t kUpperSignExtend = static_cast<size_t>(1) << (63 - UpperMaskSize);

    return doubleWord + (kLowerSignExtend | kUpperSignExtend);
}

template <uint8_t UpperMaskSize>
static ssize_t UpperWordOfDoubleWordSingleSignExtend(ssize_t doubleWord)
{
    static constexpr size_t kUpperSignExtend = static_cast<size_t>(1) << (31 - UpperMaskSize);

    return UpperWordOfDoubleWord(doubleWord + kUpperSignExtend);
}

template <uint8_t UpperMaskSize, uint8_t LowerMaskSize>
static ssize_t UpperWordOfDoubleWordDoubleSignExtend(ssize_t doubleWord)
{
    return UpperWordOfDoubleWord(DoubleWordSignExtend<UpperMaskSize, LowerMaskSize>(doubleWord));
}

/*static*/ unsigned emitter::TrimSignedToImm12(ssize_t imm12)
{
    assert(isValidSimm12(imm12));

    return static_cast<unsigned>(LowerNBitsOfWord<12>(imm12));
}

/*static*/ unsigned emitter::TrimSignedToImm13(ssize_t imm13)
{
    assert(isValidSimm13(imm13));

    return static_cast<unsigned>(LowerNBitsOfWord<13>(imm13));
}

/*static*/ unsigned emitter::TrimSignedToImm20(ssize_t imm20)
{
    assert(isValidSimm20(imm20));

    return static_cast<unsigned>(LowerNBitsOfWord<20>(imm20));
}

/*static*/ unsigned emitter::TrimSignedToImm21(ssize_t imm21)
{
    assert(isValidSimm21(imm21));

    return static_cast<unsigned>(LowerNBitsOfWord<21>(imm21));
}

BYTE* emitter::emitOutputInstr_OptsReloc(BYTE* dst, const instrDesc* id, instruction* ins)

Review comment (suggestion):
```suggestion
    return ~0ull >> (64 - bits);
```
Nit

Code after:
        emitFwdJumps = true;

        // The target offset will be closer by at least 'emitOffsAdj', but only if this
        // jump doesn't cross the hot-cold boundary.
        if (!emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
        {
            distVal -= emitOffsAdj;
            dstOffs -= emitOffsAdj;
        }
        jmp->idjOffs = dstOffs;
        if (jmp->idjOffs != dstOffs)
        {
            IMPL_LIMITATION("Method is too large");
        }
    }
    return distVal;
}

static inline constexpr unsigned WordMask(uint8_t bits)
{
    return static_cast<unsigned>((1ull << bits) - 1);
}

static inline constexpr uint64_t BitMask64(uint8_t bits)
{
    return (bits == 64) ? ~0ull : ((1ull << bits) - 1);
}

template <uint8_t MaskSize>
static unsigned LowerNBitsOfWord(ssize_t word)
{
    static_assert(MaskSize < 32, "Given mask size is bigger than the word itself");
    static_assert(MaskSize > 0, "Given mask size cannot be zero");

    static constexpr unsigned kMask = WordMask(MaskSize);

    return static_cast<unsigned>(word & kMask);
}

template <uint8_t MaskSize>
static unsigned UpperNBitsOfWord(ssize_t word)
{
    static constexpr unsigned kShift = 32 - MaskSize;

    return LowerNBitsOfWord<MaskSize>(word >> kShift);
}

template <uint8_t MaskSize>
static unsigned UpperNBitsOfWordSignExtend(ssize_t word)
{
    static constexpr unsigned kSignExtend = 1 << (31 - MaskSize);
Repository: dotnet/runtime
File: src/coreclr/runtime/asyncsafethreadmap.h (C/C++)

Code before:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#ifndef __ASYNCSAFETHREADMAP_H__
#define __ASYNCSAFETHREADMAP_H__

#if defined(TARGET_UNIX) && !defined(TARGET_WASM)

//  Insert a thread into the async-safe map.
//  * osThread - The OS thread ID to insert.
//  * pThread - A pointer to the thread object to associate with the OS thread ID.
//  * return true if the insertion was successful, false otherwise (OOM).
bool InsertThreadIntoAsyncSafeMap(size_t osThread, void* pThread);

// Remove a thread from the async-safe map.
// * osThread - The OS thread ID to remove.
// * pThread - A pointer to the thread object associated with the OS thread ID.
void RemoveThreadFromAsyncSafeMap(size_t osThread, void* pThread);

// Find a thread in the async-safe map.
// * osThread = The OS thread ID to search for.
// * return - A pointer to the thread object associated with the OS thread ID, or NULL if not found.
void* FindThreadInAsyncSafeMap(size_t osThread);

#endif // TARGET_UNIX && !TARGET_WASM

#endif // __ASYNCSAFETHREADMAP_H__


Review comment (suggestion):
The comment has a typo. It should say "The OS thread ID to search for" (with a period) instead of "The OS thread ID to search for" (with an equals sign). The equals sign appears to be a typo for a period or dash.
```suggestion
// * osThread - The OS thread ID to search for.
```

Code after:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#ifndef __ASYNCSAFETHREADMAP_H__
#define __ASYNCSAFETHREADMAP_H__

#if defined(TARGET_UNIX) && !defined(TARGET_WASM)

//  Insert a thread into the async-safe map.
//  * osThread - The OS thread ID to insert.
//  * pThread - A pointer to the thread object to associate with the OS thread ID.
//  * return true if the insertion was successful, false otherwise (OOM).
bool InsertThreadIntoAsyncSafeMap(size_t osThread, void* pThread);

// Remove a thread from the async-safe map.
// * osThread - The OS thread ID to remove.
// * pThread - A pointer to the thread object associated with the OS thread ID.
void RemoveThreadFromAsyncSafeMap(size_t osThread, void* pThread);

// Find a thread in the async-safe map.
// * osThread - The OS thread ID to search for.
// * return - A pointer to the thread object associated with the OS thread ID, or NULL if not found.
void* FindThreadInAsyncSafeMap(size_t osThread);

#endif // TARGET_UNIX && !TARGET_WASM

#endif // __ASYNCSAFETHREADMAP_H__