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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
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;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } 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
84 changes: 69 additions & 15 deletions src/coreclr/inc/coredistools.h
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
//===--------- coredistools.h - Disassembly tools for CoreClr ------------===//
//
// Core Disassembly Tools API Version 1.0.1-prerelease
// Core Disassembly Tools API Version 1.4.0
// Disassembly tools required by CoreCLR for utilities like
// GCStressand SuperPMI
// GCStress, SuperPMI, and R2RDump.
//===----------------------------------------------------------------------===//

#if !defined(_COREDISTOOLS_H_)
Expand DownExpand Up@@ -41,7 +41,8 @@ enum TargetArch {
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
Target_Arm64,
Target_LoongArch64
};

struct CorDisasm;
Expand All@@ -60,14 +61,28 @@ struct PrintControl {
// The type of a custom function provided by the user to determine
// if two offsets are considered equivalent wrt diffing code blocks.
// Offset1 and Offset2 are the two offsets to be compared.
// BlockOffset is the offest of the instructions (that contain Offset1
// BlockOffset is the offset of the instructions (that contain Offset1
// and Offset2) from the beginning of their respective code blocks.
// InstructionLength is the length of the current instruction being
// compared for equivalency.
typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t Offset1,
uint64_t Offset2);

// If an OffsetMunger function is defined, it is called before the OffsetComparator.
// If it returns `true` then:
// 1. the instructions are considered equivalent
// 2. the offsets have been decoded and "munged" (changed), and
// *Offset1 and *Offset2 are set to the values to use.
// 3. *SkipInstructions1 instructions in code stream 1 are skipped
// 4. *SkipInstructions2 instructions in code stream 2 are skipped
//
// This is typically used on arm32 to treat "movw/movt" as a single instruction
// generating a single constant. Similarly, for arm64 mov/movk/movk/movk sequences.
typedef bool(__cdecl *OffsetMunger)(const void *UserData, size_t BlockOffset,
size_t InstructionLength, uint64_t* Offset1, uint64_t* Offset2,
uint32_t* SkipInstructions1, uint32_t* SkipInstructions2);

// The Export/Import definitions for CoreDistools library are defined below.
// A typedef for each interface function's type is defined in order to aid
// the importer.
Expand All@@ -76,6 +91,10 @@ typedef bool(__cdecl *OffsetComparator)(const void *UserData, size_t BlockOffset
typedef CorDisasm * __cdecl InitDisasm_t(enum TargetArch Target);
DllIface InitDisasm_t InitDisasm;

// Initialize the disassembler, using buffered print controls
typedef CorDisasm * __cdecl InitBufferedDisasm_t(enum TargetArch Target);
DllIface InitBufferedDisasm_t InitBufferedDisasm;

// Initialize the disassembler using custom print controls
typedef CorDisasm * __cdecl NewDisasm_t(enum TargetArch Target,
const PrintControl *PControl);
Expand All@@ -85,6 +104,28 @@ DllIface NewDisasm_t NewDisasm;
typedef void __cdecl FinishDisasm_t(const CorDisasm *Disasm);
DllIface FinishDisasm_t FinishDisasm;

// Initialize a code differ using buffered output.
typedef CorDisasm * __cdecl InitBufferedDiffer_t(enum TargetArch Target,
const OffsetComparator Comparator);
DllIface InitBufferedDiffer_t InitBufferedDiffer;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Initialize the Code Differ, with an offset munger.
typedef CorAsmDiff * __cdecl NewDiffer2_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator,
const OffsetMunger Munger);
DllIface NewDiffer2_t NewDiffer2;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;

// DisasmInstruction -- Disassemble one instruction
// Arguments:
// Disasm -- The Disassembler
Expand All@@ -100,22 +141,27 @@ typedef size_t __cdecl DisasmInstruction_t(const CorDisasm *Disasm,
const uint8_t *Bytes, size_t Maxlength);
DllIface DisasmInstruction_t DisasmInstruction;

// Initialize the Code Differ
typedef CorAsmDiff * __cdecl NewDiffer_t(enum TargetArch Target,
const PrintControl *PControl,
const OffsetComparator Comparator);
DllIface NewDiffer_t NewDiffer;

// Delete the Code Differ
typedef void __cdecl FinishDiff_t(const CorAsmDiff *AsmDiff);
DllIface FinishDiff_t FinishDiff;
// DumpInstruction -- Disassemble one instruction and output it
// Arguments:
// Disasm -- The Disassembler
// Address -- The address at which the bytes of the instruction
// are intended to execute
// Bytes -- Pointer to the actual bytes which need to be disassembled
// MaxLength -- Number of bytes available in Bytes buffer
// Returns:
// -- The Size of the disassembled instruction
// -- Zero on failure
typedef size_t __cdecl DumpInstruction_t(const CorDisasm *Disasm,
const uint8_t *Address, const uint8_t *Bytes,
size_t Maxlength);
DllIface DumpInstruction_t DumpInstruction;

// NearDiffCodeBlocks -- Compare two code blocks for semantic
// equivalence
// Arguments:
// AsmDiff -- The Asm-differ
// UserData -- Any data the user wishes to pass through into
// the OffsetComparator
// the OffsetComparator/OffsetMunger
// Address1 -- Address at which first block will execute
// Bytes1 -- Pointer to the actual bytes of the first block
// Size1 -- The size of the first block
Expand DownExpand Up@@ -145,4 +191,12 @@ typedef void __cdecl DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
const uint8_t *Bytes2, size_t Size2);
DllIface DumpDiffBlocks_t DumpDiffBlocks;

// Get a pointer to the buffered output buffer.
typedef const char* __cdecl GetOutputBuffer_t();
DllIface GetOutputBuffer_t GetOutputBuffer;

// Clear the buffered output buffer.
typedef void __cdecl ClearOutputBuffer_t();
DllIface ClearOutputBuffer_t ClearOutputBuffer;

#endif // !defined(_COREDISTOOLS_H_)
3 changes: 0 additions & 3 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
void CodeGen::genArm64EmitterUnitTestsGeneral()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand DownExpand Up@@ -1824,7 +1823,6 @@ void CodeGen::genArm64EmitterUnitTestsGeneral()
*/
void CodeGen::genArm64EmitterUnitTestsAdvSimd()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

////////////////////////////////////////////////////////////////////////////////
Expand DownExpand Up@@ -4557,7 +4555,6 @@ void CodeGen::genArm64EmitterUnitTestsAdvSimd()
*/
void CodeGen::genArm64EmitterUnitTestsSve()
{
assert(verbose);
emitter* theEmitter = GetEmitter();

//
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2668,8 +2668,8 @@ void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
/*****************************************************************************
* Unit testing of the emitter: If JitDumpEmitUnitTests is set, generate
* a bunch of instructions, then:
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions as the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and dissassemble the output file.
* Use DOTNET_JitLateDisasm=* to see if the late disassembler thinks the instructions are the same as we do.
* Or, use DOTNET_JitRawHexCode and DOTNET_JitRawHexCodeFile and disassemble the output file.
*
* Possible values for JitDumpEmitUnitTests:
* Amd64: all, sse2
Expand All@@ -2682,7 +2682,7 @@ void CodeGen::genEmitterUnitTests()
{
const WCHAR* unitTestSection = JitConfig.JitDumpEmitUnitTests();

if ((!verbose) || (unitTestSection == nullptr))
if (unitTestSection == nullptr)
Comment thread
BruceForstall marked this conversation as resolved.
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -1994,6 +1994,12 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

void Compiler::compDone()
{
#ifdef LATE_DISASM
if (codeGen != nullptr)
{
codeGen->getDisAssembler().disDone();
}
#endif // LATE_DISASM
}

void* Compiler::compGetHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
Expand Down
Loading