Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -8215,7 +8215,7 @@ class Compiler
CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list);
CORINFO_CLASS_HANDLE eeGetClassFromContext(CORINFO_CONTEXT_HANDLE context);
unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
static unsigned eeGetArgAlignment(var_types type, bool isFloatHfa);
static unsigned eeGetArgSizeAlignment(var_types type, bool isFloatHfa);

// VOM info, method sigs

Expand Down
24 changes: 15 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -456,30 +456,36 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO*
{
argSize = genTypeSize(argType);
}
const unsigned argAlignment = eeGetArgAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned argSizeWithPadding = roundUp(argSize, argAlignment);
return argSizeWithPadding;

const unsigned argSizeAlignment = eeGetArgSizeAlignment(argType, (hfaType == TYP_FLOAT));
const unsigned alignedArgSize = roundUp(argSize, argSizeAlignment);
return alignedArgSize;

#endif
}

//------------------------------------------------------------------------
// eeGetArgAlignment: Return arg passing alignment for the given type.
// eeGetArgSizeAlignment: Return alignment for an argument size.
//
// Arguments:
// type - the argument type
// isFloatHfa - is it an HFA<float> type
//
// Return value:
// the required alignment in bytes.
// the required argument size alignment in bytes.
//
// Notes:
// It currently doesn't return smaller than required alignment for arm32 (4 bytes for double and int64)
// but it does not lead to issues because its alignment requirements are satisfied in other code parts.
// TODO: fix this function and delete the other code that is handling this.
// Usually values passed on the stack are aligned to stack slot (i.e. pointer size), except for
// on macOS ARM ABI that allows packing multiple args into a single stack slot.
//
// The arg size alignment can be different from the normal alignment. One
// example is on arm32 where a struct containing a double and float can
// explicitly have size 12 but with alignment 8, in which case the size is
// aligned to 4 (the stack slot size) while frame layout must still handle
// aligning the argument to 8.
//
// static
unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa)
unsigned Compiler::eeGetArgSizeAlignment(var_types type, bool isFloatHfa)
{
if (compMacOsArm64Abi())
{
Expand Down
44 changes: 32 additions & 12 deletions src/coreclr/jit/lclvars.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -955,6 +955,23 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT));
}

#if FEATURE_FASTTAILCALL
// Check if arg was split between registers and stack.
if (!varTypeUsesFloatReg(argType))
{
unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg());
unsigned lastRegArgNum = firstRegArgNum + cSlots - 1;
if (lastRegArgNum >= varDscInfo->maxIntRegArgNum)
{
assert(varDscInfo->stackArgSize == 0);
unsigned numEnregistered = varDscInfo->maxIntRegArgNum - firstRegArgNum;
varDsc->SetStackOffset(-(int)numEnregistered * REGSIZE_BYTES);
varDscInfo->stackArgSize += (cSlots - numEnregistered) * REGSIZE_BYTES;
JITDUMP("set user arg V%02u offset to %d\n", varDscInfo->varNum, varDsc->GetStackOffset());
}
}
#endif
#endif // TARGET_ARM

#ifdef DEBUG
Expand DownExpand Up@@ -1057,14 +1074,17 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
#endif // TARGET_XXX

#if FEATURE_FASTTAILCALL
const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT));
if (compMacOsArm64Abi())
{
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);
}

assert((argSize % argAlignment) == 0);
assert((varDscInfo->stackArgSize % argAlignment) == 0);
#ifdef TARGET_ARM
unsigned argAlignment = cAlign * TARGET_POINTER_SIZE;
#else
unsigned argAlignment = eeGetArgSizeAlignment(origArgType, (hfaType == TYP_FLOAT));
// We expect the following rounding operation to be a noop on all
// ABIs except ARM (where we have 8-byte aligned args) and macOS
// ARM64 (that allows to pack multiple smaller parameters in a
// single stack slot).
assert(compMacOsArm64Abi() || ((varDscInfo->stackArgSize % argAlignment) == 0));
#endif
varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment);

JITDUMP("set user arg V%02u offset to %u\n", varDscInfo->varNum, varDscInfo->stackArgSize);
varDsc->SetStackOffset(varDscInfo->stackArgSize);
Expand DownExpand Up@@ -3659,9 +3679,9 @@ unsigned LclVarDsc::lvSize() const // Size needed for storage representation. On
if (lvIsParam)
{
assert(varTypeIsStruct(lvType));
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = Compiler::eeGetArgAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argAlignment);
const bool isFloatHfa = (lvIsHfa() && (GetHfaType() == TYP_FLOAT));
const unsigned argSizeAlignment = Compiler::eeGetArgSizeAlignment(lvType, isFloatHfa);
return roundUp(lvExactSize, argSizeAlignment);
}

#if defined(FEATURE_SIMD) && !defined(TARGET_64BIT)
Expand DownExpand Up@@ -5949,7 +5969,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
#endif // TARGET_ARM
const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa);
const unsigned argAlignment = eeGetArgSizeAlignment(varDsc->lvType, isFloatHfa);
if (compMacOsArm64Abi())
{
argOffs = roundUp(argOffs, argAlignment);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3076,7 +3076,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
// Arm64 Apple has a special ABI for passing small size arguments on stack,
// bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc.
// It means passing 8 1-byte arguments on stack can take as small as 8 bytes.
argAlignBytes = eeGetArgAlignment(argType, isFloatHfa);
argAlignBytes = eeGetArgSizeAlignment(argType, isFloatHfa);
}

//
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/register_arg_convention.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,6 @@ struct InitVarDscInfo
#if FEATURE_FASTTAILCALL
// It is used to calculate argument stack size information in byte
unsigned stackArgSize;
bool hasMultiSlotStruct;
#endif // FEATURE_FASTTAILCALL

public:
Expand All@@ -49,8 +48,7 @@ struct InitVarDscInfo
#endif // TARGET_ARM

#if FEATURE_FASTTAILCALL
stackArgSize = 0;
hasMultiSlotStruct = false;
stackArgSize = 0;
#endif // FEATURE_FASTTAILCALL
}

Expand Down