mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-12 10:40:30 +09:00
Fix typos (#72709)
This commit is contained in:
parent
f0e7a686df
commit
9d6396deb0
1292 changed files with 4531 additions and 4531 deletions
|
@ -53,7 +53,7 @@ Macros generally use a `MONO_` prefix. Macros in public API headers *must* use
|
||||||
|
|
||||||
Prefer the standard C sized types `int32_t`, `intptr_t`, etc over the eglib types `gint32`, `gsize` etc.
|
Prefer the standard C sized types `int32_t`, `intptr_t`, etc over the eglib types `gint32`, `gsize` etc.
|
||||||
|
|
||||||
One exception is `gboolean` is prefered over C `bool`.
|
One exception is `gboolean` is preferred over C `bool`.
|
||||||
|
|
||||||
There are actually three boolean types to keep in mind:
|
There are actually three boolean types to keep in mind:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# CLR ABI
|
# CLR ABI
|
||||||
|
|
||||||
This document describes the .NET Common Language Runtime (CLR) software conventions (or ABI, "Application Binary Interface"). It focusses on the ABI for the x64 (aka, AMD64), ARM (aka, ARM32 or Thumb-2), and ARM64 processor architectures. Documentation for the x86 ABI is somewhat scant, but information on the basics of the calling convention is included at the bottom of this document.
|
This document describes the .NET Common Language Runtime (CLR) software conventions (or ABI, "Application Binary Interface"). It focuses on the ABI for the x64 (aka, AMD64), ARM (aka, ARM32 or Thumb-2), and ARM64 processor architectures. Documentation for the x86 ABI is somewhat scant, but information on the basics of the calling convention is included at the bottom of this document.
|
||||||
|
|
||||||
It describes requirements that the Just-In-Time (JIT) compiler imposes on the VM and vice-versa.
|
It describes requirements that the Just-In-Time (JIT) compiler imposes on the VM and vice-versa.
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ The below is performed when the GC transition is not suppressed.
|
||||||
2. For JIT64/AMD64 only: Next for non-IL stubs, the InlinedCallFrame is 'pushed' by setting `Thread->m_pFrame` to point to the InlinedCallFrame (recall that the per-frame initialization already set `InlinedCallFrame->m_pNext` to point to the previous top). For IL stubs this step is accomplished in the per-frame initialization.
|
2. For JIT64/AMD64 only: Next for non-IL stubs, the InlinedCallFrame is 'pushed' by setting `Thread->m_pFrame` to point to the InlinedCallFrame (recall that the per-frame initialization already set `InlinedCallFrame->m_pNext` to point to the previous top). For IL stubs this step is accomplished in the per-frame initialization.
|
||||||
3. The Frame is made active by setting `InlinedCallFrame->m_pCallerReturnAddress`.
|
3. The Frame is made active by setting `InlinedCallFrame->m_pCallerReturnAddress`.
|
||||||
4. The code then toggles the GC mode by setting `Thread->m_fPreemptiveGCDisabled = 0`.
|
4. The code then toggles the GC mode by setting `Thread->m_fPreemptiveGCDisabled = 0`.
|
||||||
5. Starting now, no GC pointers may be live in registers. RyuJit LSRA meets this requirement by adding special refPositon `RefTypeKillGCRefs` before unmanaged calls and special helpers.
|
5. Starting now, no GC pointers may be live in registers. RyuJit LSRA meets this requirement by adding special refPosition `RefTypeKillGCRefs` before unmanaged calls and special helpers.
|
||||||
6. Then comes the actual call/PInvoke.
|
6. Then comes the actual call/PInvoke.
|
||||||
7. The GC mode is set back by setting `Thread->m_fPreemptiveGCDisabled = 1`.
|
7. The GC mode is set back by setting `Thread->m_fPreemptiveGCDisabled = 1`.
|
||||||
8. Then we check to see if `g_TrapReturningThreads` is set (non-zero). If it is, we call `CORINFO_HELP_STOP_FOR_GC`.
|
8. Then we check to see if `g_TrapReturningThreads` is set (non-zero). If it is, we call `CORINFO_HELP_STOP_FOR_GC`.
|
||||||
|
|
|
@ -178,7 +178,7 @@ Both methodCold and methodCode are declared as `BYTE *`, but in fact hold target
|
||||||
|
|
||||||
If this code seems overly complex and confusing to you, that's good. In fact it is. Worse, it provides no protection for the separation of host and target addresses. From the declarations of `methodCold` and `methodCode`, there is no particular reason to interpret them as target addresses at all. If these pointers were dereferenced in DAC builds as if they really were host pointers, the process would probably AV. This snippet demonstrates that any arbitrary pointer type (as opposed to a `PTR` type) can be casted to a `TADDR`. Given that these two variables always hold target addresses, they should be of type `PTR_BYTE`, rather than `BYTE *`.
|
If this code seems overly complex and confusing to you, that's good. In fact it is. Worse, it provides no protection for the separation of host and target addresses. From the declarations of `methodCold` and `methodCode`, there is no particular reason to interpret them as target addresses at all. If these pointers were dereferenced in DAC builds as if they really were host pointers, the process would probably AV. This snippet demonstrates that any arbitrary pointer type (as opposed to a `PTR` type) can be casted to a `TADDR`. Given that these two variables always hold target addresses, they should be of type `PTR_BYTE`, rather than `BYTE *`.
|
||||||
|
|
||||||
There is also a disciplined means to cast between different `PTR` types: `dac_cast`. The `dac_cast` operator is the DAC-aware vesion of the C++ `static_cast` operator (which the CLR coding conventions stipulate instead of C-style casts when casting pointer types). The `dac_cast` operator will do any of the following things:
|
There is also a disciplined means to cast between different `PTR` types: `dac_cast`. The `dac_cast` operator is the DAC-aware version of the C++ `static_cast` operator (which the CLR coding conventions stipulate instead of C-style casts when casting pointer types). The `dac_cast` operator will do any of the following things:
|
||||||
|
|
||||||
1. Create a `PTR` type from a `TADDR`
|
1. Create a `PTR` type from a `TADDR`
|
||||||
2. Convert one `PTR` type to another
|
2. Convert one `PTR` type to another
|
||||||
|
|
|
@ -262,7 +262,7 @@ When a C++ exception is thrown, and there is a missing UACH, the typical failure
|
||||||
Runtime code into managed code
|
Runtime code into managed code
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
The transition from the runtime into managed code has highly platform-dependent requirements. On 32-bit Windows platforms, the CLR's managed exception code requires that "COMPlusFrameHandler" is installed just before entering managed code. These transitions are handled by highly specialized helper functions, which take care of the appropriate exception handlers. It is very unlikely that any typical new calls into managed would use any other way in. In the event that the COMPlusFrameHander were missing, the most likely effect would be that exception handling code in the target managed code simply wouldn't be executed – no finally blocks, and no catch blocks.
|
The transition from the runtime into managed code has highly platform-dependent requirements. On 32-bit Windows platforms, the CLR's managed exception code requires that "COMPlusFrameHandler" is installed just before entering managed code. These transitions are handled by highly specialized helper functions, which take care of the appropriate exception handlers. It is very unlikely that any typical new calls into managed would use any other way in. In the event that the COMPlusFrameHandler were missing, the most likely effect would be that exception handling code in the target managed code simply wouldn't be executed – no finally blocks, and no catch blocks.
|
||||||
|
|
||||||
Runtime code into external native code
|
Runtime code into external native code
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
|
@ -46,7 +46,7 @@ The process follows the following strategy
|
||||||
not maintained as generally working. It is expected that the interpreter
|
not maintained as generally working. It is expected that the interpreter
|
||||||
will take 1-2 months to enable for an engineer familiar with the CoreCLR
|
will take 1-2 months to enable for an engineer familiar with the CoreCLR
|
||||||
codebase. A functional interpreter allows the porting team to have a set of
|
codebase. A functional interpreter allows the porting team to have a set of
|
||||||
engineers which focus exclusively on the JIT and a set which focusses on the
|
engineers which focus exclusively on the JIT and a set which focuses on the
|
||||||
VM portion of the runtime.
|
VM portion of the runtime.
|
||||||
|
|
||||||
- Build up a set of scripts that will run the coreclr tests. The normal
|
- Build up a set of scripts that will run the coreclr tests. The normal
|
||||||
|
@ -311,7 +311,7 @@ must implement.
|
||||||
components. The implementation made architecture specific via a long series of
|
components. The implementation made architecture specific via a long series of
|
||||||
C preprocessor macros.
|
C preprocessor macros.
|
||||||
|
|
||||||
6. `gcinfodecoder.h` The GC info format is archictecture specific as it holds
|
6. `gcinfodecoder.h` The GC info format is architecture specific as it holds
|
||||||
information about which specific registers hold GC data. The implementation
|
information about which specific registers hold GC data. The implementation
|
||||||
is generally simplified to be defined in terms of register numbers, but if
|
is generally simplified to be defined in terms of register numbers, but if
|
||||||
the architecture has more registers available for use than existing architectures
|
the architecture has more registers available for use than existing architectures
|
||||||
|
@ -378,7 +378,7 @@ Here is an annotated list of the stubs implemented for Unix on Arm64.
|
||||||
|
|
||||||
9. `TheUMEntryPrestub`/ `UMThunkStub` - used to enter the runtime from
|
9. `TheUMEntryPrestub`/ `UMThunkStub` - used to enter the runtime from
|
||||||
non-managed code through entrypoints generated from the
|
non-managed code through entrypoints generated from the
|
||||||
Marshal.GetFunctionPointerForDelagate api.
|
Marshal.GetFunctionPointerForDelegate api.
|
||||||
|
|
||||||
10. `OnHijackTripThread` - needed for thread suspension to support GC + other
|
10. `OnHijackTripThread` - needed for thread suspension to support GC + other
|
||||||
suspension requiring events. This is typically not needed for very early
|
suspension requiring events. This is typically not needed for very early
|
||||||
|
|
|
@ -112,4 +112,4 @@ The type system implementation is found in:
|
||||||
|
|
||||||
## Notable differences from CoreCLR type system
|
## Notable differences from CoreCLR type system
|
||||||
|
|
||||||
* `MethodDesc` has exact generic instantations where possible in managed type system. The code sharing policy in managed type system is one of the pluggable algorithms and it does not affect `MethodDesc` identity. The code sharing policy in the CoreCLR type system is coupled with `MethodDesc` identity. See https://github.com/dotnet/runtime/pull/45744 for an example how this difference manifests itself.
|
* `MethodDesc` has exact generic instantiations where possible in managed type system. The code sharing policy in managed type system is one of the pluggable algorithms and it does not affect `MethodDesc` identity. The code sharing policy in the CoreCLR type system is coupled with `MethodDesc` identity. See https://github.com/dotnet/runtime/pull/45744 for an example how this difference manifests itself.
|
||||||
|
|
|
@ -702,11 +702,11 @@ To see this in action, we can take a look at the following example, with these o
|
||||||
| R | 0x1234 |
|
| R | 0x1234 |
|
||||||
| S | 0x1238 |
|
| S | 0x1238 |
|
||||||
|
|
||||||
Suppose we decided to have only two buckets, then only the least signficant digit will be used to index the table, the whole hash table will look like this:
|
Suppose we decided to have only two buckets, then only the least significant digit will be used to index the table, the whole hash table will look like this:
|
||||||
|
|
||||||
| Part | Offset | Content | Meaning |
|
| Part | Offset | Content | Meaning |
|
||||||
|:--------|:-------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:--------|:-------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Header | 0 | 0x04 | This is the header, the least signficant bit is `00`, therefore the table cell is just one byte. The most significant six bit represents 1, which means the number of buckets is 2^1 = 2. |
|
| Header | 0 | 0x04 | This is the header, the least significant bit is `00`, therefore the table cell is just one byte. The most significant six bit represents 1, which means the number of buckets is 2^1 = 2. |
|
||||||
| Table | 1 | 0x08 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
|
| Table | 1 | 0x08 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
|
||||||
| Table | 2 | 0x14 | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
|
| Table | 2 | 0x14 | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
|
||||||
| Table | 3 | 0x18 | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
|
| Table | 3 | 0x18 | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
|
||||||
|
@ -835,7 +835,7 @@ enum ReadyToRunHelper
|
||||||
READYTORUN_HELPER_FltRound = 0xE3,
|
READYTORUN_HELPER_FltRound = 0xE3,
|
||||||
|
|
||||||
#ifndef _TARGET_X86_
|
#ifndef _TARGET_X86_
|
||||||
// Personality rountines
|
// Personality routines
|
||||||
READYTORUN_HELPER_PersonalityRoutine = 0xF0,
|
READYTORUN_HELPER_PersonalityRoutine = 0xF0,
|
||||||
READYTORUN_HELPER_PersonalityRoutineFilterFunclet = 0xF1,
|
READYTORUN_HELPER_PersonalityRoutineFilterFunclet = 0xF1,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -95,7 +95,7 @@ The first N slots in an instantiation of N arguments are always going to be the
|
||||||
|
|
||||||
For instance, here is an example of the contents of the generic dictionary for our `Method<string>` example:
|
For instance, here is an example of the contents of the generic dictionary for our `Method<string>` example:
|
||||||
|
|
||||||
| `Method<string>'s dicionary` |
|
| `Method<string>'s dictionary` |
|
||||||
|--------------------------|
|
|--------------------------|
|
||||||
| slot[0]: TypeHandle(`string`) |
|
| slot[0]: TypeHandle(`string`) |
|
||||||
| slot[1]: Total dictionary size |
|
| slot[1]: Total dictionary size |
|
||||||
|
|
|
@ -103,9 +103,9 @@ Hijacking for GC suspension is done by Thread::SysSuspendForGC. This method atte
|
||||||
2. Get the current CONTEXT for the thread, via GetThreadContext. This is an OS concept; CONTEXT represents the current register state of the thread. This allows us to inspect its instruction pointer, and thus determine what type of code it is currently executing.
|
2. Get the current CONTEXT for the thread, via GetThreadContext. This is an OS concept; CONTEXT represents the current register state of the thread. This allows us to inspect its instruction pointer, and thus determine what type of code it is currently executing.
|
||||||
3. Check again if the thread is in cooperative mode, as it may have already left cooperative mode before it could be suspended. If so, the thread is in dangerous territory: the thread may be executing arbitrary native code, and must be resumed immediately to avoid deadlocks.
|
3. Check again if the thread is in cooperative mode, as it may have already left cooperative mode before it could be suspended. If so, the thread is in dangerous territory: the thread may be executing arbitrary native code, and must be resumed immediately to avoid deadlocks.
|
||||||
4. Check if the thread is running managed code. It is possible that it is executing native VM code in cooperative mode (see Synchronization, below), in which case the thread must be immediately resumed as in the previous step.
|
4. Check if the thread is running managed code. It is possible that it is executing native VM code in cooperative mode (see Synchronization, below), in which case the thread must be immediately resumed as in the previous step.
|
||||||
5. Now the thread is suspended in managed code. Depending on whether that code is fully- or partially-interruptable, one of the following is performed:
|
5. Now the thread is suspended in managed code. Depending on whether that code is fully- or partially-interruptible, one of the following is performed:
|
||||||
* If fully interruptable, it is safe to perform a GC at any point, since the thread is, by definition, at a safe point. It is reasonable to leave the thread suspended at this point (because it's safe) but various historical OS bugs prevent this from working, because the CONTEXT retrieved earlier may be corrupt). Instead, the thread's instruction pointer is overwritten, redirecting it to a stub that will capture a more complete CONTEXT, leave cooperative mode, wait for the GC to complete, reenter cooperative mode, and restore the thread to its previous state.
|
* If fully interruptible, it is safe to perform a GC at any point, since the thread is, by definition, at a safe point. It is reasonable to leave the thread suspended at this point (because it's safe) but various historical OS bugs prevent this from working, because the CONTEXT retrieved earlier may be corrupt). Instead, the thread's instruction pointer is overwritten, redirecting it to a stub that will capture a more complete CONTEXT, leave cooperative mode, wait for the GC to complete, reenter cooperative mode, and restore the thread to its previous state.
|
||||||
* If partially-interruptable, the thread is, by definition, not at a safe point. However, the caller will be at a safe point (method transition). Using that knowledge, the CLR "hijacks" the top-most stack frame's return address (physically overwrite that location on the stack) with a stub similar to the one used for fully-interruptable code. When the method returns, it will no longer return to its actual caller, but rather to the stub (the method may also perform a GC poll, inserted by the JIT, before that point, which will cause it to leave cooperative mode and undo the hijack).
|
* If partially-interruptible, the thread is, by definition, not at a safe point. However, the caller will be at a safe point (method transition). Using that knowledge, the CLR "hijacks" the top-most stack frame's return address (physically overwrite that location on the stack) with a stub similar to the one used for fully-interruptible code. When the method returns, it will no longer return to its actual caller, but rather to the stub (the method may also perform a GC poll, inserted by the JIT, before that point, which will cause it to leave cooperative mode and undo the hijack).
|
||||||
|
|
||||||
ThreadAbort / AppDomain-Unload
|
ThreadAbort / AppDomain-Unload
|
||||||
==============================
|
==============================
|
||||||
|
|
|
@ -177,7 +177,7 @@ Code will be compiled using the optimistic instruction set to drive compilation,
|
||||||
- Any use of a platform intrinsic in the codebase SHOULD be wrapped with a call to the associated IsSupported property. This wrapping may be done within the same function that uses the hardware intrinsic, but this is not required as long as the programmer can control all entrypoints to a function that uses the hardware intrinsic.
|
- Any use of a platform intrinsic in the codebase SHOULD be wrapped with a call to the associated IsSupported property. This wrapping may be done within the same function that uses the hardware intrinsic, but this is not required as long as the programmer can control all entrypoints to a function that uses the hardware intrinsic.
|
||||||
- If an application developer is highly concerned about startup performance, developers should avoid use intrinsics beyond Sse42, or should use Crossgen with an updated baseline instruction set support.
|
- If an application developer is highly concerned about startup performance, developers should avoid use intrinsics beyond Sse42, or should use Crossgen with an updated baseline instruction set support.
|
||||||
|
|
||||||
### Crossgen2 ajustment to rules for System.Private.CoreLib.dll
|
### Crossgen2 adjustment to rules for System.Private.CoreLib.dll
|
||||||
Since System.Private.CoreLib.dll is known to be code reviewed with the code review rules as written above for crossgen1 with System.Private.CoreLib.dll, it is possible to relax rule "Code which attempts to use instruction sets outside of the optimistic set will generate code that will not be used on machines with support for the instruction set." What this will do is allow the generation of non-optimal code for these situations, but through the magic of code review, the generated logic will still work correctly.
|
Since System.Private.CoreLib.dll is known to be code reviewed with the code review rules as written above for crossgen1 with System.Private.CoreLib.dll, it is possible to relax rule "Code which attempts to use instruction sets outside of the optimistic set will generate code that will not be used on machines with support for the instruction set." What this will do is allow the generation of non-optimal code for these situations, but through the magic of code review, the generated logic will still work correctly.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,8 @@ There are a number of wrinkles informing this design based on how the JIT models
|
||||||
- The jit does not model which handlers are reachable from a given protected region,
|
- The jit does not model which handlers are reachable from a given protected region,
|
||||||
so considers a variable live into a handler if it is live into any handler in the method.
|
so considers a variable live into a handler if it is live into any handler in the method.
|
||||||
|
|
||||||
It is posible to do better than the "store every definition" approach outlined
|
It is possible to do better than the "store every definition" approach outlined
|
||||||
in the design, but the expectation is that this would require posibly
|
in the design, but the expectation is that this would require possibly
|
||||||
modifying the model in the JIT and staging more throughput intensive analyses.
|
modifying the model in the JIT and staging more throughput intensive analyses.
|
||||||
With these considerations this design was selected and further improvements
|
With these considerations this design was selected and further improvements
|
||||||
left to future optimization.
|
left to future optimization.
|
||||||
|
|
|
@ -298,7 +298,7 @@ Empirical studies have shown that most finallys are small. Thus to
|
||||||
avoid excessive code growth, a crude size estimate is formed by
|
avoid excessive code growth, a crude size estimate is formed by
|
||||||
counting the number of statements in the blocks that make up the
|
counting the number of statements in the blocks that make up the
|
||||||
finally. Any finally larger that 15 statements is not cloned. In our
|
finally. Any finally larger that 15 statements is not cloned. In our
|
||||||
study this disqualifed about 0.5% of all finallys from cloning.
|
study this disqualified about 0.5% of all finallys from cloning.
|
||||||
|
|
||||||
### EH Nesting Considerations
|
### EH Nesting Considerations
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ blocks. Clear the finally target bit and any GT_END_LFIN from the
|
||||||
continuation.
|
continuation.
|
||||||
|
|
||||||
If all call finallys are converted, modify the region to be try/fault
|
If all call finallys are converted, modify the region to be try/fault
|
||||||
(interally EH_HANDLER_FAULT_WAS_FINALLY, so we can distinguish it
|
(internally EH_HANDLER_FAULT_WAS_FINALLY, so we can distinguish it
|
||||||
later from "organic" try/faults). Otherwise leave it as a
|
later from "organic" try/faults). Otherwise leave it as a
|
||||||
try/finally.
|
try/finally.
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ This would be done in multiple phases:
|
||||||
* This work item should address issue [#4323 RyuJIT properly optimizes structs with a single field
|
* This work item should address issue [#4323 RyuJIT properly optimizes structs with a single field
|
||||||
if the field type is int but not if it is double](https://github.com/dotnet/runtime/issues/4323)
|
if the field type is int but not if it is double](https://github.com/dotnet/runtime/issues/4323)
|
||||||
(test is `JIT\Regressions\JitBlue\GitHub_1161`),
|
(test is `JIT\Regressions\JitBlue\GitHub_1161`),
|
||||||
[#7200 Struct getters are generating unneccessary
|
[#7200 Struct getters are generating unnecessary
|
||||||
instructions on x64 when struct contains floats](https://github.com/dotnet/runtime/issues/7200)
|
instructions on x64 when struct contains floats](https://github.com/dotnet/runtime/issues/7200)
|
||||||
and [#11413 Inefficient codegen for casts between same size types](https://github.com/dotnet/runtime/issues/11413).
|
and [#11413 Inefficient codegen for casts between same size types](https://github.com/dotnet/runtime/issues/11413).
|
||||||
* Remove the pessimization in `LocalAddressVisitor::PostOrderVisit()` for the `GT_RETURN` case.
|
* Remove the pessimization in `LocalAddressVisitor::PostOrderVisit()` for the `GT_RETURN` case.
|
||||||
|
@ -347,7 +347,7 @@ The following issues illustrate some of the motivation for improving the handlin
|
||||||
* Unfortunately, there is not currently a scenario or test case for this issue.
|
* Unfortunately, there is not currently a scenario or test case for this issue.
|
||||||
|
|
||||||
* [\#10879 Unix: Unnecessary struct copy while passing struct of size <=16](https://github.com/dotnet/runtime/issues/10879)
|
* [\#10879 Unix: Unnecessary struct copy while passing struct of size <=16](https://github.com/dotnet/runtime/issues/10879)
|
||||||
* [\#9839 [RyuJIT] Eliminate unecessary copies when passing structs](https://github.com/dotnet/runtime/issues/9839)
|
* [\#9839 [RyuJIT] Eliminate unnecessary copies when passing structs](https://github.com/dotnet/runtime/issues/9839)
|
||||||
* These require changing both the callsite and the callee to avoid copying the parameter onto the stack.
|
* These require changing both the callsite and the callee to avoid copying the parameter onto the stack.
|
||||||
* It may be that these have been addressed by [PR #43870](https://github.com/dotnet/runtime/pull/43870).
|
* It may be that these have been addressed by [PR #43870](https://github.com/dotnet/runtime/pull/43870).
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ to be practical.
|
||||||
Second, even if we could obtain the actual size of prospective inline
|
Second, even if we could obtain the actual size of prospective inline
|
||||||
candidates, we might not want to use this data. The final code
|
candidates, we might not want to use this data. The final code
|
||||||
sequence emitted by the compiler depends intimately on details of the
|
sequence emitted by the compiler depends intimately on details of the
|
||||||
target architecture, runtime conventions (ABIs), and capabilites of the
|
target architecture, runtime conventions (ABIs), and capabilities of the
|
||||||
compiler phases that run after inlining. If we allow feedback into hey
|
compiler phases that run after inlining. If we allow feedback into hey
|
||||||
heuristics by incorporating data from these "downstream" sources, we
|
heuristics by incorporating data from these "downstream" sources, we
|
||||||
introduce various forms of coupling that have important
|
introduce various forms of coupling that have important
|
||||||
|
|
|
@ -28,4 +28,4 @@ Enabling GC Hole Stress causes GCs to always occur in specific locations and tha
|
||||||
|
|
||||||
**0x1 | 0x2** – 0x3 are "in the VM". Failures in 0x1 or 0x2 can be due to VM-related reasons, like lack of GC reporting/pinning in interop frames.
|
**0x1 | 0x2** – 0x3 are "in the VM". Failures in 0x1 or 0x2 can be due to VM-related reasons, like lack of GC reporting/pinning in interop frames.
|
||||||
|
|
||||||
**0x4 | 0x8** – 0xC runs GC stress for each JIT generated instruction (either dynamically or AOT, in R2R). Failures in 0x4 or 0x8 typically mean a failure in GC info. Only happens once for any instruction, so can miss failures that only occur on non-first GCs. This mode replaces the target instuction with a with breakpoint instruction and that affects disassembly.
|
**0x4 | 0x8** – 0xC runs GC stress for each JIT generated instruction (either dynamically or AOT, in R2R). Failures in 0x4 or 0x8 typically mean a failure in GC info. Only happens once for any instruction, so can miss failures that only occur on non-first GCs. This mode replaces the target instruction with a with breakpoint instruction and that affects disassembly.
|
||||||
|
|
|
@ -50,7 +50,7 @@ together (i.e. can’t preserve the tree traversal/linear order invariants), we
|
||||||
|
|
||||||
## Richer Liveness Model (No Decomposition)
|
## Richer Liveness Model (No Decomposition)
|
||||||
|
|
||||||
The idea here woudl be to retain `TYP_LONG` nodes in the IR, and to find a way to extend
|
The idea here would be to retain `TYP_LONG` nodes in the IR, and to find a way to extend
|
||||||
the liveness model used by Lowering, LSRA and CodeGen to ensure good register allocation.
|
the liveness model used by Lowering, LSRA and CodeGen to ensure good register allocation.
|
||||||
o
|
o
|
||||||
|
|
||||||
|
|
|
@ -511,12 +511,12 @@ node, which builds `RefPositions` according to the liveness model described abov
|
||||||
```
|
```
|
||||||
N037 t16 = ┌──▌ LCL_VAR ref V04 arg3
|
N037 t16 = ┌──▌ LCL_VAR ref V04 arg3
|
||||||
N039 t127 = ┌──▌ PUTARG_REG ref REG rcx
|
N039 t127 = ┌──▌ PUTARG_REG ref REG rcx
|
||||||
N041 t128 = │ ┌──▌ LCL_VAR ref V04 arg3 (last use)
|
N041 t128 = │ ┌──▌ LCL_VAR ref V04 arg3 (last use)
|
||||||
N043 t129 = │ ┌──▌ LEA(b+0) byref
|
N043 t129 = │ ┌──▌ LEA(b+0) byref
|
||||||
N045 t130 = │ ┌──▌ IND long
|
N045 t130 = │ ┌──▌ IND long
|
||||||
N047 t131 = │ ┌──▌ LEA(b+72) long
|
N047 t131 = │ ┌──▌ LEA(b+72) long
|
||||||
N049 t132 = │ ┌──▌ IND long
|
N049 t132 = │ ┌──▌ IND long
|
||||||
N051 t133 = │ ┌──▌ LEA(b+40) long
|
N051 t133 = │ ┌──▌ LEA(b+40) long
|
||||||
N053 t134 = ├──▌ IND long REG NA
|
N053 t134 = ├──▌ IND long REG NA
|
||||||
N055 t17 = ▌ CALLV ind int System.Globalization.CultureInfo.get_LCID $242
|
N055 t17 = ▌ CALLV ind int System.Globalization.CultureInfo.get_LCID $242
|
||||||
```
|
```
|
||||||
|
@ -1012,7 +1012,7 @@ exclusive:
|
||||||
|
|
||||||
- Always insert a `GTF_RELOAD` above a use of a spilled register (0x400).
|
- Always insert a `GTF_RELOAD` above a use of a spilled register (0x400).
|
||||||
|
|
||||||
- Alyways spill (0x800). This mode is not fully functional, as there are
|
- Always spill (0x800). This mode is not fully functional, as there are
|
||||||
cases where spill isn't actually supported (it should be possible to simply
|
cases where spill isn't actually supported (it should be possible to simply
|
||||||
not spill in such cases).
|
not spill in such cases).
|
||||||
|
|
||||||
|
@ -1211,7 +1211,7 @@ term "EH Var" means a `lclVar` marked `lvLiveInOutOfHndlr`):
|
||||||
- Adjust the heuristics:
|
- Adjust the heuristics:
|
||||||
|
|
||||||
1. For determining whether an EH var should be a candidate for register allocation,
|
1. For determining whether an EH var should be a candidate for register allocation,
|
||||||
e.g. if the defs outweight the uses.
|
e.g. if the defs outweigh the uses.
|
||||||
|
|
||||||
- An initial investigation might only consider an EH var as a register candidate if it has a single use. One complication is that we sometimes generate better code for a non-register-candidate local than one that is always spilled (we don't support `RegOptional` defs).
|
- An initial investigation might only consider an EH var as a register candidate if it has a single use. One complication is that we sometimes generate better code for a non-register-candidate local than one that is always spilled (we don't support `RegOptional` defs).
|
||||||
Thus, it would be better to identify *before* building intervals whether we should consider it a candidate, but the problem with that is that we don't necessarily know at that
|
Thus, it would be better to identify *before* building intervals whether we should consider it a candidate, but the problem with that is that we don't necessarily know at that
|
||||||
|
@ -1388,7 +1388,7 @@ Issue [\#6261](https://github.com/dotnet/runtime/issues/6261) has to do with `Re
|
||||||
I don't think such cases should arise, but there may be some cleanup needed here.
|
I don't think such cases should arise, but there may be some cleanup needed here.
|
||||||
|
|
||||||
Issue [\#5793](https://github.com/dotnet/runtime/issues/5793) suggests adding a stress mode that
|
Issue [\#5793](https://github.com/dotnet/runtime/issues/5793) suggests adding a stress mode that
|
||||||
allocates registers forr mullti-reg nodes in the reverse of the ABI requirements.
|
allocates registers for multi-reg nodes in the reverse of the ABI requirements.
|
||||||
|
|
||||||
Issue [#10691](https://github.com/dotnet/runtime/issues/10691) suggests adding a stress mode that
|
Issue [#10691](https://github.com/dotnet/runtime/issues/10691) suggests adding a stress mode that
|
||||||
deliberately trashes registers that are not currently occupied (e.g. at block boundaries).
|
deliberately trashes registers that are not currently occupied (e.g. at block boundaries).
|
||||||
|
|
|
@ -42,7 +42,7 @@ Heuristic `A` thru `M` are for selecting one of the free registers, while `N` th
|
||||||
```c#
|
```c#
|
||||||
registerCandidates = 0; // bit-mask of all registers
|
registerCandidates = 0; // bit-mask of all registers
|
||||||
|
|
||||||
LinearScan::allocateReg(RefPostion refPosition, Inteval* interval)
|
LinearScan::allocateReg(RefPosition refPosition, Interval* interval)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
registerCandidates = allFreeCandidates();
|
registerCandidates = allFreeCandidates();
|
||||||
|
@ -102,7 +102,7 @@ HashTable<char, HeuristicFn> ScoreMappingTable = {
|
||||||
{'Q', try_REG_NUM}
|
{'Q', try_REG_NUM}
|
||||||
};
|
};
|
||||||
|
|
||||||
LinearScan::allocateReg(RefPostion refPosition, Inteval* interval)
|
LinearScan::allocateReg(RefPosition refPosition, Interval* interval)
|
||||||
{
|
{
|
||||||
char *ordering = Read_COMPlus_LsraOrdering();
|
char *ordering = Read_COMPlus_LsraOrdering();
|
||||||
HeuristicFn fn;
|
HeuristicFn fn;
|
||||||
|
|
|
@ -4,7 +4,7 @@ Support for multiple destination regs, GT_CALL and GT_RETURN nodes that return a
|
||||||
The following targets allow a GT_CALL/GT_RETURN node to return a value in more than one register:
|
The following targets allow a GT_CALL/GT_RETURN node to return a value in more than one register:
|
||||||
|
|
||||||
x64 Unix:
|
x64 Unix:
|
||||||
Structs of size betwee 9-16 bytes will be returned in RAX/RDX and/or XMM0/XMM1.
|
Structs of size between 9-16 bytes will be returned in RAX/RDX and/or XMM0/XMM1.
|
||||||
|
|
||||||
Arm64:
|
Arm64:
|
||||||
HFA structs will be returned in 1-4 successive VFP registers s0-s3 or d0-d3.
|
HFA structs will be returned in 1-4 successive VFP registers s0-s3 or d0-d3.
|
||||||
|
|
|
@ -67,7 +67,7 @@ are also some restrictions on the types of nodes that may appear in an HIR or LI
|
||||||
|
|
||||||
Both HIR and LIR blocks are composed of `GenTree` nodes that define the operations performed by the block. A
|
Both HIR and LIR blocks are composed of `GenTree` nodes that define the operations performed by the block. A
|
||||||
`GenTree` node may consume some number of operands and may produce a singly-defined, at-most-singly-used value as a
|
`GenTree` node may consume some number of operands and may produce a singly-defined, at-most-singly-used value as a
|
||||||
result. These values are referred to interchangably as *SDSU* (single def, single use) temps or *tree* temps.
|
result. These values are referred to interchangeably as *SDSU* (single def, single use) temps or *tree* temps.
|
||||||
Definitions (aka, defs) of SDSU temps are represented by `GenTree` nodes themselves, and uses are represented by
|
Definitions (aka, defs) of SDSU temps are represented by `GenTree` nodes themselves, and uses are represented by
|
||||||
edges from the using node to the defining node. Furthermore, SDSU temps defined in one block may not be used in a
|
edges from the using node to the defining node. Furthermore, SDSU temps defined in one block may not be used in a
|
||||||
different block. In cases where a value must be multiply-defined, multiply-used, or defined in one block and used in
|
different block. In cases where a value must be multiply-defined, multiply-used, or defined in one block and used in
|
||||||
|
|
|
@ -55,7 +55,7 @@ Finally, while the original JIT was quite x86-oriented, we now have a broader se
|
||||||
- Inherits from ICorDynamicInfo (corinfo.h)
|
- Inherits from ICorDynamicInfo (corinfo.h)
|
||||||
|
|
||||||
#### Notes
|
#### Notes
|
||||||
In this talk and elsewhere, you will see the .NET runtime often refered to as the VM, for virtual machine, the EE, for execution engine, or the CLR, for common language runtime. They are largely used interchangeably, though some might argue the terms have subtle differences.
|
In this talk and elsewhere, you will see the .NET runtime often referred to as the VM, for virtual machine, the EE, for execution engine, or the CLR, for common language runtime. They are largely used interchangeably, though some might argue the terms have subtle differences.
|
||||||
.NET is somewhat unique in that it currently has a single-tier JIT – no interpreter, and no re-optimizing JIT. While an interpreter exists, and experimentation has been done on re-jitting, the current model remains single-tier.
|
.NET is somewhat unique in that it currently has a single-tier JIT – no interpreter, and no re-optimizing JIT. While an interpreter exists, and experimentation has been done on re-jitting, the current model remains single-tier.
|
||||||
|
|
||||||
The JIT and the VM each implement an interface that abstracts the dependencies they share. The VM invokes methods on the ICorJitCompiler interface to compile methods, and the JIT calls back on the ICorJitInfo interface to get information about types and methods.
|
The JIT and the VM each implement an interface that abstracts the dependencies they share. The VM invokes methods on the ICorJitCompiler interface to compile methods, and the JIT calls back on the ICorJitInfo interface to get information about types and methods.
|
||||||
|
@ -667,7 +667,7 @@ Recognize "Intrinsic" (SampleStep1 shelveset)
|
||||||
Add Pattern Recognition (SampleStep2 shelveset):
|
Add Pattern Recognition (SampleStep2 shelveset):
|
||||||
- ifdef out the name recognition
|
- ifdef out the name recognition
|
||||||
- Go back to jitdump1.out and look at IR just prior to optCloneLoops
|
- Go back to jitdump1.out and look at IR just prior to optCloneLoops
|
||||||
- Let's assume we're going to eventually add more than one instrinsic that implements a loop, so we'll add a method that looks for simple loops we can turn into intrinsics.
|
- Let's assume we're going to eventually add more than one intrinsic that implements a loop, so we'll add a method that looks for simple loops we can turn into intrinsics.
|
||||||
- Unshelve SampleStep2:
|
- Unshelve SampleStep2:
|
||||||
- Add optFindLoopIntrinsics() to compCompile after optOptimizeLoops()
|
- Add optFindLoopIntrinsics() to compCompile after optOptimizeLoops()
|
||||||
- compiler.h, compiler.cpp
|
- compiler.h, compiler.cpp
|
||||||
|
|
|
@ -45,7 +45,7 @@ Given a native offset, no two variables should share the same location.
|
||||||
Context
|
Context
|
||||||
--------
|
--------
|
||||||
|
|
||||||
We generate variables debug info while we generate the assembly intructions of the code. This is happening in `genCodeForBBList()` and `genFnProlog()`.
|
We generate variables debug info while we generate the assembly instruction of the code. This is happening in `genCodeForBBList()` and `genFnProlog()`.
|
||||||
|
|
||||||
If we are jitting release code, information about variable liveness will be included in `GenTree`s and `BasicBlock` when `genCodeForBBList` is reached.
|
If we are jitting release code, information about variable liveness will be included in `GenTree`s and `BasicBlock` when `genCodeForBBList` is reached.
|
||||||
For each `BasicBlock`:
|
For each `BasicBlock`:
|
||||||
|
@ -224,10 +224,10 @@ We are not reporting the cases where a variable liveness is being modified and a
|
||||||
So a `VariableLiveRange` with exactly the same native offset for both would represent an empty live range and will not been found by the debugger.
|
So a `VariableLiveRange` with exactly the same native offset for both would represent an empty live range and will not been found by the debugger.
|
||||||
|
|
||||||
- Each C# line commonly end being more than one assembly instruction, if it exist on the assembly code.
|
- Each C# line commonly end being more than one assembly instruction, if it exist on the assembly code.
|
||||||
When you put a breakpoint in one C# line, you are stoping at the first of this group of instruction.
|
When you put a breakpoint in one C# line, you are stopping at the first of this group of instruction.
|
||||||
A `VariableLiveRange` of just on assembly instruction seems unlikely to affect user debugging experience.
|
A `VariableLiveRange` of just on assembly instruction seems unlikely to affect user debugging experience.
|
||||||
|
|
||||||
- Less memory used to save VariabeLiveRanges
|
- Less memory used to save VariableLiveRanges
|
||||||
|
|
||||||
- We are just changing the variable location.
|
- We are just changing the variable location.
|
||||||
We are not changing the variable value and the "old" variable location is not being modified.
|
We are not changing the variable value and the "old" variable location is not being modified.
|
||||||
|
@ -255,7 +255,7 @@ In case only one of them is defined, that one will be sent to the debugger.
|
||||||
If both are defined, Scope info is sent to the debugger.
|
If both are defined, Scope info is sent to the debugger.
|
||||||
If none is defined, no info is sent to the debugger.
|
If none is defined, no info is sent to the debugger.
|
||||||
|
|
||||||
Both flags can be found at the beginnig of `codegeninterface.h`
|
Both flags can be found at the beginning of `codegeninterface.h`
|
||||||
|
|
||||||
Dumps and Debugging Support
|
Dumps and Debugging Support
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef enum
|
||||||
|
|
||||||
Any callers of this API must set `COR_PRF_REJIT_BLOCK_INLINING`. Although it is possible that in the future this restriction will be lifted, the current implementation blocks ReJITted methods from being inlined (ever).
|
Any callers of this API must set `COR_PRF_REJIT_BLOCK_INLINING`. Although it is possible that in the future this restriction will be lifted, the current implementation blocks ReJITted methods from being inlined (ever).
|
||||||
|
|
||||||
The other value `COR_PRF_REJIT_INLINING_CALLBACKS` controls whether you get a `ICorProfilerCallback4::GetReJITParameters` callback for any methods that are ReJITted as inliners of the requested method. The default is to not receive callbacks for these methods. You will always receive a `GetReJITParameters` callback for any methods that are explictly requested.
|
The other value `COR_PRF_REJIT_INLINING_CALLBACKS` controls whether you get a `ICorProfilerCallback4::GetReJITParameters` callback for any methods that are ReJITted as inliners of the requested method. The default is to not receive callbacks for these methods. You will always receive a `GetReJITParameters` callback for any methods that are explicitly requested.
|
||||||
|
|
||||||
|
|
||||||
## Inner workings/Limitations
|
## Inner workings/Limitations
|
||||||
|
|
|
@ -366,7 +366,7 @@ protected:
|
||||||
virtual void NotifyCustomMod(sig_elem_type cmod, sig_index_type indexType, sig_index index)
|
virtual void NotifyCustomMod(sig_elem_type cmod, sig_index_type indexType, sig_index index)
|
||||||
{
|
{
|
||||||
Print(
|
Print(
|
||||||
"Custom modifers: '%s', index type: '%s', index: '0x%x'\n",
|
"Custom modifiers: '%s', index type: '%s', index: '0x%x'\n",
|
||||||
SigElementTypeToString(cmod),
|
SigElementTypeToString(cmod),
|
||||||
SigIndexTypeToString(indexType),
|
SigIndexTypeToString(indexType),
|
||||||
index);
|
index);
|
||||||
|
|
|
@ -59,7 +59,7 @@ The current .NET Core hosting solutions are described in detail at [Documentatio
|
||||||
|
|
||||||
>[`HRESULT DllUnregisterServer();`](https://msdn.microsoft.com/library/windows/desktop/ms691457(v=vs.85).aspx)
|
>[`HRESULT DllUnregisterServer();`](https://msdn.microsoft.com/library/windows/desktop/ms691457(v=vs.85).aspx)
|
||||||
|
|
||||||
When `DllGetClassObject()` is called in a COM activation scenario, the following steps will occur. The calling of `DllGetClassObject()` is usually accomplished through an implicit or explcit call to `CoCreateInstance()`.
|
When `DllGetClassObject()` is called in a COM activation scenario, the following steps will occur. The calling of `DllGetClassObject()` is usually accomplished through an implicit or explicit call to `CoCreateInstance()`.
|
||||||
|
|
||||||
1) Determine additional registration information needed for activation.
|
1) Determine additional registration information needed for activation.
|
||||||
* The shim will check for an embedded manifest. If the shim does not contain an embedded manifest, the shim will check if a file with the `<shim_name>.clsidmap` naming format exists adjacent to it. Build tooling handles shim customization, including renaming the shim to be based on the managed assembly's name (e.g. `NetComServer.dll` will have a custom shim called `NetComServer.comhost.dll`). If the shim is signed the shim will **not** attempt to discover the manifest on disk.
|
* The shim will check for an embedded manifest. If the shim does not contain an embedded manifest, the shim will check if a file with the `<shim_name>.clsidmap` naming format exists adjacent to it. Build tooling handles shim customization, including renaming the shim to be based on the managed assembly's name (e.g. `NetComServer.dll` will have a custom shim called `NetComServer.comhost.dll`). If the shim is signed the shim will **not** attempt to discover the manifest on disk.
|
||||||
|
|
|
@ -9,7 +9,7 @@ https://github.com/dotnet/core-setup/issues/3884
|
||||||
|
|
||||||
The `deps.json` file format specifies assets including managed assemblies, resource assemblies and native libraries to load.
|
The `deps.json` file format specifies assets including managed assemblies, resource assemblies and native libraries to load.
|
||||||
|
|
||||||
Every applicaton has its own `<app>.deps.json` file which is automatically processed. If an application needs additional deps files, typically for "lightup" extensions, it can specify that by:
|
Every application has its own `<app>.deps.json` file which is automatically processed. If an application needs additional deps files, typically for "lightup" extensions, it can specify that by:
|
||||||
- The `--additional-deps` command line option
|
- The `--additional-deps` command line option
|
||||||
- If this is not set, the `DOTNET_ADDITIONAL_DEPS` environment variable is used
|
- If this is not set, the `DOTNET_ADDITIONAL_DEPS` environment variable is used
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ The proposal for this is to change the ordering of the processing of additional-
|
||||||
Finally, a lower-priority issue is there is no way to turn off the global deps lightup (via `%DOTNET_ADDITIONAL_DEPS%`) for a single application if they run into issues with pulling in the additional deps. If the environment variable is set, and an application can't load because of the additional lightup deps, and the lightup isn't needed, there should be a way to turn it off so the app can load. One (poor) workaround would be to specify `--additional-deps` in the command-line to point to any empty file, but that would only work if the command line can be used in this way to launch the application.
|
Finally, a lower-priority issue is there is no way to turn off the global deps lightup (via `%DOTNET_ADDITIONAL_DEPS%`) for a single application if they run into issues with pulling in the additional deps. If the environment variable is set, and an application can't load because of the additional lightup deps, and the lightup isn't needed, there should be a way to turn it off so the app can load. One (poor) workaround would be to specify `--additional-deps` in the command-line to point to any empty file, but that would only work if the command line can be used in this way to launch the application.
|
||||||
|
|
||||||
## 2.1 proposal (roll-backwards)
|
## 2.1 proposal (roll-backwards)
|
||||||
In order to prevent having to co-release for roll-forward cases, and deploy all past versions, the followng rules are proposed:
|
In order to prevent having to co-release for roll-forward cases, and deploy all past versions, the following rules are proposed:
|
||||||
1) Instead of `requested_framework_version`, use `found_framework_version`
|
1) Instead of `requested_framework_version`, use `found_framework_version`
|
||||||
|
|
||||||
Where "found" means the version that is being used at run time including roll-forward. For example, if an app requests `2.1.0` of `Microsoft.NETCore.App` in its runtimeconfig.json, but we actually found and are using `2.2.1` (because there were no "compatible" versions installed from 2.1.0 to 2.2.0), then look for the deps folder `shared/Microsoft.NETCore.App/2.2.1` first.
|
Where "found" means the version that is being used at run time including roll-forward. For example, if an app requests `2.1.0` of `Microsoft.NETCore.App` in its runtimeconfig.json, but we actually found and are using `2.2.1` (because there were no "compatible" versions installed from 2.1.0 to 2.2.0), then look for the deps folder `shared/Microsoft.NETCore.App/2.2.1` first.
|
||||||
|
@ -117,6 +117,6 @@ A lightup "extension" could be considered an application, and have its own `runt
|
||||||
|
|
||||||
It could be supported by entending the concept of "multi-layered frameworks" like we have with Microsoft.AspNetCore.App, Microsoft.AspNetCore.All, Microsoft.NETCore.App, where they each have their own runtimeconfig.json and deps.json files.
|
It could be supported by entending the concept of "multi-layered frameworks" like we have with Microsoft.AspNetCore.App, Microsoft.AspNetCore.All, Microsoft.NETCore.App, where they each have their own runtimeconfig.json and deps.json files.
|
||||||
|
|
||||||
Adding support for app-to-app dependencies would imply adding a "horizontal" hierarchy, and introducing a "graph reconcilation" phase that would need to be able to collapse several references to the same app or framework when they have different versions.
|
Adding support for app-to-app dependencies would imply adding a "horizontal" hierarchy, and introducing a "graph reconciliation" phase that would need to be able to collapse several references to the same app or framework when they have different versions.
|
||||||
|
|
||||||
Similar to additional-deps, the extension apps could "light up" by (for example) an "additional-apps" host option or environment variable.
|
Similar to additional-deps, the extension apps could "light up" by (for example) an "additional-apps" host option or environment variable.
|
||||||
|
|
|
@ -215,7 +215,7 @@ arguments are not constant.
|
||||||
+ Review of existing documentation shows `ARM64` intrinsics are mostly absent or undocumented so
|
+ Review of existing documentation shows `ARM64` intrinsics are mostly absent or undocumented so
|
||||||
initially this will not be necessary for `ARM64`
|
initially this will not be necessary for `ARM64`
|
||||||
+ See gcc manual "AArch64 Built-in Functions"
|
+ See gcc manual "AArch64 Built-in Functions"
|
||||||
+ MSVC ARM64 documentation has not been publically released
|
+ MSVC ARM64 documentation has not been publicly released
|
||||||
|
|
||||||
## Phased Implementation
|
## Phased Implementation
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ Code versions are embodied by the configuration in NativeCodeVersion structure a
|
||||||
|
|
||||||
ILCodeVersion objects are always partial code versions, containing only the portion of versioning information that doesn't vary by generic instantiation.
|
ILCodeVersion objects are always partial code versions, containing only the portion of versioning information that doesn't vary by generic instantiation.
|
||||||
|
|
||||||
The NativeCodeVersion and ILCodeVersion don't directly store any of the configuration data but rather serve as facades that use one of two different storage strategies. For the default version (or in the case of ILCodeVersion, default partial code version), the structures only store sufficient information to identify which version is being refered to. Then they delegate all storage to the pre-existing runtime data structures which already store this data. For non-default versions the structure stores a pointer block of memory that does store the configuration. For example:
|
The NativeCodeVersion and ILCodeVersion don't directly store any of the configuration data but rather serve as facades that use one of two different storage strategies. For the default version (or in the case of ILCodeVersion, default partial code version), the structures only store sufficient information to identify which version is being referred to. Then they delegate all storage to the pre-existing runtime data structures which already store this data. For non-default versions the structure stores a pointer block of memory that does store the configuration. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
PCODE NativeCodeVersion::GetNativeCode() const
|
PCODE NativeCodeVersion::GetNativeCode() const
|
||||||
|
@ -343,7 +343,7 @@ APIs that require the lock is held/not held should ASSERT the lock state in debu
|
||||||
|
|
||||||
The example build pipeline in the design section has many stages, but the implemented versioning tree only tracks a few specific chunks of configuration information:
|
The example build pipeline in the design section has many stages, but the implemented versioning tree only tracks a few specific chunks of configuration information:
|
||||||
|
|
||||||
1. Profiler ReJIT can specify an IL body, IL remaping table, and a few jit flags.
|
1. Profiler ReJIT can specify an IL body, IL remapping table, and a few jit flags.
|
||||||
2. The runtime can specify any number of generic instantiations
|
2. The runtime can specify any number of generic instantiations
|
||||||
3. Tiered compilation can specify an optimization level
|
3. Tiered compilation can specify an optimization level
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md) C# language features posed for C# 9.0.
|
Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md) C# language features posed for C# 9.0.
|
||||||
|
|
||||||
This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compability rules are defined in ECMA I.8.7.1. Example: using a more derived return type.
|
This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compatibility rules are defined in ECMA I.8.7.1. Example: using a more derived return type.
|
||||||
|
|
||||||
Covariant return methods can only be described through MethodImpl records, and as an initial implementation will only be applicable to methods on reference types. Methods on interfaces and value types will not be supported (may be supported later in the future).
|
Covariant return methods can only be described through MethodImpl records, and as an initial implementation will only be applicable to methods on reference types. Methods on interfaces and value types will not be supported (may be supported later in the future).
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ A new `PreserveBaseOverridesAttribute` shall be added. The presence of this attr
|
||||||
|
|
||||||
During enumeration of MethodImpls on a type (`MethodTableBuilder::EnumerateMethodImpls()`), if the signatures of the MethodImpl and the MethodDecl do not match:
|
During enumeration of MethodImpls on a type (`MethodTableBuilder::EnumerateMethodImpls()`), if the signatures of the MethodImpl and the MethodDecl do not match:
|
||||||
1. We repeat the signature comparison a second time, but skip the comparison of the return type signatures. If the signatures for the rest of the method arguments match, we will conditionally treat that MethodImpl as a valid one, but flag it for a closer examination of the return type compatibility at a later stage of type loading (end of `CLASS_LOAD_EXACTPARENTS` stage).
|
1. We repeat the signature comparison a second time, but skip the comparison of the return type signatures. If the signatures for the rest of the method arguments match, we will conditionally treat that MethodImpl as a valid one, but flag it for a closer examination of the return type compatibility at a later stage of type loading (end of `CLASS_LOAD_EXACTPARENTS` stage).
|
||||||
2. At the end of the `CLASS_LOAD_EXACTPARENTS` type loading stage, examing each virtual method on the type, and if it has been flagged for further return type checking:
|
2. At the end of the `CLASS_LOAD_EXACTPARENTS` type loading stage, examine each virtual method on the type, and if it has been flagged for further return type checking:
|
||||||
+ Load the `TypeHandle` of the return type of the method on base type.
|
+ Load the `TypeHandle` of the return type of the method on base type.
|
||||||
+ Load the `TypeHandle` of the return type of the method on the current type being validated.
|
+ Load the `TypeHandle` of the return type of the method on the current type being validated.
|
||||||
+ Verify that the second `TypeHandle` is compatible with the first `TypeHandle` using the `MethodTable::CanCastTo()` API. If they are not compatible, a TypeLoadException is thrown.
|
+ Verify that the second `TypeHandle` is compatible with the first `TypeHandle` using the `MethodTable::CanCastTo()` API. If they are not compatible, a TypeLoadException is thrown.
|
||||||
|
|
||||||
The only exception where `CanCastTo()` will return true for an incompatible type according to the ECMA rules is for structs implementing interfaces, so we explicitly check for that case and throw a TypeLoadException if we hit it.
|
The only exception where `CanCastTo()` will return true for an incompatible type according to the ECMA rules is for structs implementing interfaces, so we explicitly check for that case and throw a TypeLoadException if we hit it.
|
||||||
|
|
||||||
Once a method is flagged for return type checking, every time the vtable slot containing that method gets overridden on a derived type, the new override will also be checked for compatiblity. This is to ensure that no derived type can implicitly override some virtual method that has already been overridden by some MethodImpl with a covariant return type.
|
Once a method is flagged for return type checking, every time the vtable slot containing that method gets overridden on a derived type, the new override will also be checked for compatibility. This is to ensure that no derived type can implicitly override some virtual method that has already been overridden by some MethodImpl with a covariant return type.
|
||||||
|
|
||||||
### VTable Slot Unification
|
### VTable Slot Unification
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ Consider this case:
|
||||||
}
|
}
|
||||||
class B : A {
|
class B : A {
|
||||||
[PreserveBaseOverrides]
|
[PreserveBaseOverrides]
|
||||||
DerivedRetType VirtualFunction() { .override A.VirtualFuncion }
|
DerivedRetType VirtualFunction() { .override A.VirtualFunction }
|
||||||
}
|
}
|
||||||
class C : B {
|
class C : B {
|
||||||
[PreserveBaseOverrides]
|
[PreserveBaseOverrides]
|
||||||
|
|
|
@ -85,7 +85,7 @@ I use the term `DAC` in this document to refer to both the `DAC` and the `DBI` d
|
||||||
|
|
||||||
### Build entry point
|
### Build entry point
|
||||||
|
|
||||||
The main build systme change is adding the ability to set the Target OS on a Windows build.
|
The main build system change is adding the ability to set the Target OS on a Windows build.
|
||||||
|
|
||||||
- See [build-runtime.cmd changes](https://github.com/dotnet/runtime/blob/0049c629381c5a18e4dadd1038c2bd6b3ae6e3e6/src/coreclr/build-runtime.cmd#L133-L134)
|
- See [build-runtime.cmd changes](https://github.com/dotnet/runtime/blob/0049c629381c5a18e4dadd1038c2bd6b3ae6e3e6/src/coreclr/build-runtime.cmd#L133-L134)
|
||||||
- See [Subsets.props](https://github.com/dotnet/runtime/blob/0049c629381c5a18e4dadd1038c2bd6b3ae6e3e6/eng/Subsets.props#L191-L197)
|
- See [Subsets.props](https://github.com/dotnet/runtime/blob/0049c629381c5a18e4dadd1038c2bd6b3ae6e3e6/eng/Subsets.props#L191-L197)
|
||||||
|
@ -94,4 +94,4 @@ There are also changes to the official build to set these flags package the resu
|
||||||
|
|
||||||
### Client changes
|
### Client changes
|
||||||
|
|
||||||
Various changes were required in the DAC clients to consume the new crossdac. These are really out of the scope of this document.
|
Various changes were required in the DAC clients to consume the new crossdac. These are really out of the scope of this document.
|
||||||
|
|
|
@ -38,6 +38,6 @@ This feature certainly provides a somewhat duplicate functionality to the existi
|
||||||
* Review the list of settings which are reused from the app (see above)
|
* Review the list of settings which are reused from the app (see above)
|
||||||
* Review the list of environment variables - if we should use the same as the app or not
|
* Review the list of environment variables - if we should use the same as the app or not
|
||||||
* Currently we don't consider frameworks for the app when computing probing paths for resolving assets from the component's `.deps.json`. This is a different behavior from the app startup where these are considered. Is it important - needed?
|
* Currently we don't consider frameworks for the app when computing probing paths for resolving assets from the component's `.deps.json`. This is a different behavior from the app startup where these are considered. Is it important - needed?
|
||||||
* Add ability to corelate tracing with the runtime - probably some kind of activity ID
|
* Add ability to correlate tracing with the runtime - probably some kind of activity ID
|
||||||
* Handling of native assets - currently returning just probing paths. Would be cleaner to return full resolved paths. But we would have to keep some probing paths. In the case of missing `.deps.json` the native library should be looked for in the component directory - thus requires probing - we can't figure out which of the files in the folder are native libraries in the hosts.
|
* Handling of native assets - currently returning just probing paths. Would be cleaner to return full resolved paths. But we would have to keep some probing paths. In the case of missing `.deps.json` the native library should be looked for in the component directory - thus requires probing - we can't figure out which of the files in the folder are native libraries in the hosts.
|
||||||
* Handling of satellite assemblies (resource assets) - currently returning just probing paths which exclude the culture. So from a resolved asset `./foo/en-us/resource.dll` we only take `./foo` as the probing path. Consider using full paths instead - probably would require more parsing as we would have to be able to figure out the culture ID somewhere to build the true map AssemblyName->path in the managed class. Just like for native assets, if there's no `.deps.json` the only possible solution is to use probing, so the probing semantics would have to be supported anyway.
|
* Handling of satellite assemblies (resource assets) - currently returning just probing paths which exclude the culture. So from a resolved asset `./foo/en-us/resource.dll` we only take `./foo` as the probing path. Consider using full paths instead - probably would require more parsing as we would have to be able to figure out the culture ID somewhere to build the true map AssemblyName->path in the managed class. Just like for native assets, if there's no `.deps.json` the only possible solution is to use probing, so the probing semantics would have to be supported anyway.
|
||||||
|
|
|
@ -221,7 +221,7 @@ Each startup hook will run on the same managed thread as the `Main`
|
||||||
method, so thread state will persist between startup hooks. The
|
method, so thread state will persist between startup hooks. The
|
||||||
threading apartment state will be set based on any attributes present
|
threading apartment state will be set based on any attributes present
|
||||||
in the `Main` method of the app, before startup hooks execute. As a
|
in the `Main` method of the app, before startup hooks execute. As a
|
||||||
result, attemps to explicitly set the thread apartment state in a
|
result, attempts to explicitly set the thread apartment state in a
|
||||||
startup hook will fail if the requested state is incompatible with the
|
startup hook will fail if the requested state is incompatible with the
|
||||||
app's threading state.
|
app's threading state.
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ corehost_error_writer_fn corehost_set_error_writer(corehost_error_writer_fn erro
|
||||||
Set a callback which will be used to report error messages. By default no callback is registered and the errors are written to standard error.
|
Set a callback which will be used to report error messages. By default no callback is registered and the errors are written to standard error.
|
||||||
* `error_writer` - callback function which will be invoked every time an error is reported. When set to `nullptr`, this function unregisters any previously registered callback and the default behaviour is restored.
|
* `error_writer` - callback function which will be invoked every time an error is reported. When set to `nullptr`, this function unregisters any previously registered callback and the default behaviour is restored.
|
||||||
|
|
||||||
The return value is the previouly registered callback (which is now unregistered) or `nullptr` if there was no previously registered callback.
|
The return value is the previously registered callback (which is now unregistered) or `nullptr` if there was no previously registered callback.
|
||||||
|
|
||||||
The error writer is registered per-thread. On each thread, only one callback can be registered. Subsequent registrations overwrite the previous ones.
|
The error writer is registered per-thread. On each thread, only one callback can be registered. Subsequent registrations overwrite the previous ones.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
The .NET Core host and runtime contain messages that can be displayed to both end-users and developers. Currently, all such messages are displayed in English.
|
The .NET Core host and runtime contain messages that can be displayed to both end-users and developers. Currently, all such messages are displayed in English.
|
||||||
|
|
||||||
Other managed components built on top of .NET Runtime (e.g. SDK, WinForms, WPF) have already been localized, so a process already exists for handling translation and localizing assets, while the runtime handles satellite assembly loading. The host and runtime are different in that they have messages that originate from native components and must continue to do so. While the runtime does contain some managed resources, this document focusses on localization of native resources.
|
Other managed components built on top of .NET Runtime (e.g. SDK, WinForms, WPF) have already been localized, so a process already exists for handling translation and localizing assets, while the runtime handles satellite assembly loading. The host and runtime are different in that they have messages that originate from native components and must continue to do so. While the runtime does contain some managed resources, this document focuses on localization of native resources.
|
||||||
|
|
||||||
The goal is to support:
|
The goal is to support:
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ At run time, the .NET Core host/runtime will find and load the resource DLL from
|
||||||
|
|
||||||
#### Linux-specific
|
#### Linux-specific
|
||||||
|
|
||||||
The development language (English) strings will be compiled into the host and runtime directly. The langage-specific .xlf files will be converted into .po files and then .mo files. Those binary .mo files will be laid out in a language-specific subfolder. For example:
|
The development language (English) strings will be compiled into the host and runtime directly. The language-specific .xlf files will be converted into .po files and then .mo files. Those binary .mo files will be laid out in a language-specific subfolder. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
host/fxr/<version>
|
host/fxr/<version>
|
||||||
|
@ -239,7 +239,7 @@ The `CFCopyLocalizedStringFromTableInBundle` API will be used to retrieve the ap
|
||||||
|
|
||||||
#### Custom solution
|
#### Custom solution
|
||||||
|
|
||||||
The development language (English) strings will be compiled into the host and runtime directly. The langage-specific `.xlf` files will be converted into a chosen storage format. Those files will be laid out in a language-specific subfolder. For example:
|
The development language (English) strings will be compiled into the host and runtime directly. The language-specific `.xlf` files will be converted into a chosen storage format. Those files will be laid out in a language-specific subfolder. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
host/fxr/<version>
|
host/fxr/<version>
|
||||||
|
@ -297,7 +297,7 @@ Since localization would not be needed by all applications, localized resources
|
||||||
|
|
||||||
### Packaging and deployment
|
### Packaging and deployment
|
||||||
|
|
||||||
WPF and WinForms always include all languanges in an install. Does the host/runtime do the same or have separate language packs? How are they delivered (e.g. single installer with runtime and options for different languages, separate installer for languages with options for different languanges, separate installer per language)?
|
WPF and WinForms always include all languages in an install. Does the host/runtime do the same or have separate language packs? How are they delivered (e.g. single installer with runtime and options for different languages, separate installer for languages with options for different languages, separate installer per language)?
|
||||||
|
|
||||||
### SDK
|
### SDK
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ From the framework's `name` and `version` the appropriate framework location is
|
||||||
|
|
||||||
In order for other frameworks (or platforms such as ASP.NET) to get the same benefits of roll-forward and self-containment for serviceability, 2.1 will support multiple frameworks.
|
In order for other frameworks (or platforms such as ASP.NET) to get the same benefits of roll-forward and self-containment for serviceability, 2.1 will support multiple frameworks.
|
||||||
|
|
||||||
For 2.1, a given framework can only depend upon another single framework. An app can still only depend upon a single framework as well. Thus it repesents a "vertical" hierarchy. It is possible to allow additional frameworks in a "horizontal" manner, but that is out of scope for 2.1.
|
For 2.1, a given framework can only depend upon another single framework. An app can still only depend upon a single framework as well. Thus it represents a "vertical" hierarchy. It is possible to allow additional frameworks in a "horizontal" manner, but that is out of scope for 2.1.
|
||||||
|
|
||||||
Each framework has its own roll-forward semantics. This means ASP.NET can roll-forward independently of NETCore.App even though ASP.NET depends upon the NETCore.App framework.
|
Each framework has its own roll-forward semantics. This means ASP.NET can roll-forward independently of NETCore.App even though ASP.NET depends upon the NETCore.App framework.
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ Using the specified version from the `--fx-version` argument or from the runtime
|
||||||
- For 2.1+, if the apphost (e.g. myapp.exe) use the environment variable %DOTNET_ROOT% (empty by default)
|
- For 2.1+, if the apphost (e.g. myapp.exe) use the environment variable %DOTNET_ROOT% (empty by default)
|
||||||
- For 2.1+, if the apphost and %DOTNET_ROOT% is empty, use the `Default installation location`.
|
- For 2.1+, if the apphost and %DOTNET_ROOT% is empty, use the `Default installation location`.
|
||||||
|
|
||||||
2. Obtain the most appropriate version from the `Global .NET location` and compare it agaist the most appropriate version from the first step. Select the most appropriate version from the two locations. If a compatible framework cannot be found, then an error will be displayed.
|
2. Obtain the most appropriate version from the `Global .NET location` and compare it against the most appropriate version from the first step. Select the most appropriate version from the two locations. If a compatible framework cannot be found, then an error will be displayed.
|
||||||
|
|
||||||
Determine the most appropriate version varies for release (production) and pre-release versions.
|
Determine the most appropriate version varies for release (production) and pre-release versions.
|
||||||
- For releases:
|
- For releases:
|
||||||
|
|
|
@ -39,7 +39,7 @@ Alternatively, the generator that reads C++ could generate its own implementatio
|
||||||
|
|
||||||
#### Win32Metadata winmd
|
#### Win32Metadata winmd
|
||||||
|
|
||||||
The Win32Metadata project provides a richly typed surface area for interop scenarios with Win32 APIs, but it has some serious limitations that make it undesireable for us to use as our source of truth:
|
The Win32Metadata project provides a richly typed surface area for interop scenarios with Win32 APIs, but it has some serious limitations that make it undesirable for us to use as our source of truth:
|
||||||
|
|
||||||
- The tooling only runs on Windows
|
- The tooling only runs on Windows
|
||||||
- The tooling is extremely focused on the Win32 API
|
- The tooling is extremely focused on the Win32 API
|
||||||
|
|
|
@ -6,7 +6,7 @@ This document aims to provide a specification for how a standalone GC fires
|
||||||
events that can be collected by trace collectors. Such a feature is highly desirable
|
events that can be collected by trace collectors. Such a feature is highly desirable
|
||||||
for a standalone GC since it is the primary way that is used to reason about
|
for a standalone GC since it is the primary way that is used to reason about
|
||||||
GC performance. Since a standalone GC is not permitted to link against the rest of the runtime, all
|
GC performance. Since a standalone GC is not permitted to link against the rest of the runtime, all
|
||||||
communication betwene the runtime and the GC most pass through dynamically-dispatched interfaces.
|
communication between the runtime and the GC most pass through dynamically-dispatched interfaces.
|
||||||
|
|
||||||
## Definitions
|
## Definitions
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ From the API surface perspective, there are only couple of new functions added:
|
||||||
* `AssemblyLoadContext.IsCollectible` property to query whether the `AssemblyLoadContext` is unloadable or not.
|
* `AssemblyLoadContext.IsCollectible` property to query whether the `AssemblyLoadContext` is unloadable or not.
|
||||||
* `MemberInfo.IsCollectible` and `Assembly.IsCollectible` properties to enable developers to do the right thing for collectible assemblies (e.g. avoid caching them for a long time, etc.)
|
* `MemberInfo.IsCollectible` and `Assembly.IsCollectible` properties to enable developers to do the right thing for collectible assemblies (e.g. avoid caching them for a long time, etc.)
|
||||||
|
|
||||||
The design of the feature builds on top of the existing collectible types. The isolation containter for this feature is provided by `AssemblyLoadContext`. All assemblies loaded into an unloadable `AssemblyLoadContext` are marked as collectible.
|
The design of the feature builds on top of the existing collectible types. The isolation container for this feature is provided by `AssemblyLoadContext`. All assemblies loaded into an unloadable `AssemblyLoadContext` are marked as collectible.
|
||||||
|
|
||||||
For each unloadable `AssemblyLoadContext`, an `AssemblyLoaderAllocator` is created. It is used to allocate all context specific memory related to the assemblies loaded into the context. The existing collectible types support ensures this behavior.
|
For each unloadable `AssemblyLoadContext`, an `AssemblyLoaderAllocator` is created. It is used to allocate all context specific memory related to the assemblies loaded into the context. The existing collectible types support ensures this behavior.
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ As part of this design, we would also want to include some in-box marshallers th
|
||||||
- A marshaller that marshals out a pointer to the native memory as a Span instead of copying the data into a managed array.
|
- A marshaller that marshals out a pointer to the native memory as a Span instead of copying the data into a managed array.
|
||||||
- This marshaller would only support blittable spans by design.
|
- This marshaller would only support blittable spans by design.
|
||||||
- This marshaller will require the user to manually release the memory. Since this will be an opt-in marshaller, this scenario is already advanced and that additional requirement should be understandable to users who use this marshaller.
|
- This marshaller will require the user to manually release the memory. Since this will be an opt-in marshaller, this scenario is already advanced and that additional requirement should be understandable to users who use this marshaller.
|
||||||
- Since there is no mechansim to provide a collection length, the question of how to provide the span's length in this case is still unresolved. One option would be to always provide a length 1 span and require the user to create a new span with the correct size, but that feels like a bad design.
|
- Since there is no mechanism to provide a collection length, the question of how to provide the span's length in this case is still unresolved. One option would be to always provide a length 1 span and require the user to create a new span with the correct size, but that feels like a bad design.
|
||||||
|
|
||||||
### Pros/Cons of Design 1
|
### Pros/Cons of Design 1
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ Cons:
|
||||||
- Defining custom marshallers for non-empty spans of non-blittable types generically is impossible since the marshalling rules of the element's type cannot be known.
|
- Defining custom marshallers for non-empty spans of non-blittable types generically is impossible since the marshalling rules of the element's type cannot be known.
|
||||||
- Custom non-default marshalling of the span element types is impossible for non-built-in types.
|
- Custom non-default marshalling of the span element types is impossible for non-built-in types.
|
||||||
- Inlining the span marshalling fully into the stub increases on-disk IL size.
|
- Inlining the span marshalling fully into the stub increases on-disk IL size.
|
||||||
- This design does not enable developers to easily define custom marshalling support for their own collection types, which may be desireable.
|
- This design does not enable developers to easily define custom marshalling support for their own collection types, which may be desirable.
|
||||||
- The MarshalAs attributes will continue to fail to work on spans used in non-source-generated DllImports, so this would be the first instance of enabling the "old" MarshalAs model on a new type in the generated DllImports, which may or may not be undesirable.
|
- The MarshalAs attributes will continue to fail to work on spans used in non-source-generated DllImports, so this would be the first instance of enabling the "old" MarshalAs model on a new type in the generated DllImports, which may or may not be undesirable.
|
||||||
- The existing "native type marshalling" support cannot support marshalling collections of an unknown (at marshaller authoring time) non-blittable element type and cannot specify an element count for collections during unmarshalling.
|
- The existing "native type marshalling" support cannot support marshalling collections of an unknown (at marshaller authoring time) non-blittable element type and cannot specify an element count for collections during unmarshalling.
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ There are 2 usage mechanisms of these attributes.
|
||||||
|
|
||||||
#### Usage 1, Source-generated interop
|
#### Usage 1, Source-generated interop
|
||||||
|
|
||||||
The user can apply the `GeneratedMarshallingAttribute` to their structure `S`. The source generator will determine if the type requires marshalling. If it does, it will generate a representation of the struct that does not require marshalling with the aformentioned required shape and apply the `NativeMarshallingAttribute` and point it to that new type. This generated representation can either be generated as a separate top-level type or as a nested type on `S`.
|
The user can apply the `GeneratedMarshallingAttribute` to their structure `S`. The source generator will determine if the type requires marshalling. If it does, it will generate a representation of the struct that does not require marshalling with the aforementioned required shape and apply the `NativeMarshallingAttribute` and point it to that new type. This generated representation can either be generated as a separate top-level type or as a nested type on `S`.
|
||||||
|
|
||||||
#### Usage 2, Manual interop
|
#### Usage 2, Manual interop
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ public struct TMarshaller
|
||||||
|
|
||||||
In this case, the underlying native type would actually be an `int`, but the user could use the strongly-typed `HResult` type as the public surface area.
|
In this case, the underlying native type would actually be an `int`, but the user could use the strongly-typed `HResult` type as the public surface area.
|
||||||
|
|
||||||
If a type `TMarshaller` with the `CustomTypeMarshaller` attribute specifies the `TwoStageMarshalling` feature, then it must provide the `ToNativeValue` feature if it supports the `In` direction, and the `FromNativeValue` method if it supports the `Out` direction. The return value of the `ToNativeValue` method will be passed to native code instead of the `TMarshaller` value itself. As a result, the type `TMarshaller` will be allowed to require marshalling and the return type of the `ToNativeValue` method, will be required be passable to native code without any additional marshalling. When marshalling in the native-to-managed direction, a default value of `TMarshaller` will have the `FromNativeValu` method called with the native value. If we are marshalling a scenario where a single frame covers the whole native call and we are marshalling in and out, then the same instance of the marshller will be reused.
|
If a type `TMarshaller` with the `CustomTypeMarshaller` attribute specifies the `TwoStageMarshalling` feature, then it must provide the `ToNativeValue` feature if it supports the `In` direction, and the `FromNativeValue` method if it supports the `Out` direction. The return value of the `ToNativeValue` method will be passed to native code instead of the `TMarshaller` value itself. As a result, the type `TMarshaller` will be allowed to require marshalling and the return type of the `ToNativeValue` method, will be required be passable to native code without any additional marshalling. When marshalling in the native-to-managed direction, a default value of `TMarshaller` will have the `FromNativeValue` method called with the native value. If we are marshalling a scenario where a single frame covers the whole native call and we are marshalling in and out, then the same instance of the marshller will be reused.
|
||||||
|
|
||||||
If the `TwoStageMarshalling` feature is specified, the developer may also provide a ref-returning or readonly-ref-returning `GetPinnableReference` method. The `GetPinnableReference` method will be called before the `ToNativeValue` method is called. The ref returned by `GetPinnableReference` will be pinned with a `fixed` statement, but the pinned value will not be used (it acts exclusively as a side-effect). As a result, `GetPinnableReference` can return a `ref` to any `T` that can be used in a fixed statement (a C# `unmanaged` type).
|
If the `TwoStageMarshalling` feature is specified, the developer may also provide a ref-returning or readonly-ref-returning `GetPinnableReference` method. The `GetPinnableReference` method will be called before the `ToNativeValue` method is called. The ref returned by `GetPinnableReference` will be pinned with a `fixed` statement, but the pinned value will not be used (it acts exclusively as a side-effect). As a result, `GetPinnableReference` can return a `ref` to any `T` that can be used in a fixed statement (a C# `unmanaged` type).
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# User Defined Type Marshalling for Source-Generated Interop
|
# User Defined Type Marshalling for Source-Generated Interop
|
||||||
|
|
||||||
For the V1 of our source-generator, we designed support for marshalling collection types and user-defined structure types based on the designs in [StructMarshalling.md](StructMarshalling.md) and [SpanMarshallers.md](SpanMarshallers.md). As the model was adopted throughout dotnet/runtime, ASP.NET Core, WinForms, and early adopters, we recieved substantial feedback that led us to reconsider some components of the design.
|
For the V1 of our source-generator, we designed support for marshalling collection types and user-defined structure types based on the designs in [StructMarshalling.md](StructMarshalling.md) and [SpanMarshallers.md](SpanMarshallers.md). As the model was adopted throughout dotnet/runtime, ASP.NET Core, WinForms, and early adopters, we received substantial feedback that led us to reconsider some components of the design.
|
||||||
|
|
||||||
Here are some of the main feedback points on the previous design:
|
Here are some of the main feedback points on the previous design:
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ When running towards iOS device (connected over usb):
|
||||||
dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS
|
dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS
|
||||||
```
|
```
|
||||||
|
|
||||||
Run diagnostic tooling like this, regardless of `suspend|nosuspend`, `Android|iOS` or `simulator|emultor|device` scenarios are being used:
|
Run diagnostic tooling like this, regardless of `suspend|nosuspend`, `Android|iOS` or `simulator|emulator|device` scenarios are being used:
|
||||||
|
|
||||||
```
|
```
|
||||||
dotnet-trace collect --diagnostic-port ~/myport,connect
|
dotnet-trace collect --diagnostic-port ~/myport,connect
|
||||||
|
|
|
@ -31,7 +31,7 @@ direction TB
|
||||||
[*] --> Starting
|
[*] --> Starting
|
||||||
|
|
||||||
Starting --> GC_Unsafe : attach
|
Starting --> GC_Unsafe : attach
|
||||||
|
|
||||||
state GC_Unsafe_out <<choice>>
|
state GC_Unsafe_out <<choice>>
|
||||||
|
|
||||||
state GC_Unsafe {
|
state GC_Unsafe {
|
||||||
|
@ -73,7 +73,7 @@ direction TB
|
||||||
}
|
}
|
||||||
|
|
||||||
state GC_Safe_out <<choice>>
|
state GC_Safe_out <<choice>>
|
||||||
|
|
||||||
GC_Safe --> GC_Safe_out
|
GC_Safe --> GC_Safe_out
|
||||||
GC_Safe_out --> GC_Unsafe : done_Blocking
|
GC_Safe_out --> GC_Unsafe : done_Blocking
|
||||||
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
||||||
|
@ -92,7 +92,7 @@ direction TB
|
||||||
[*] --> Starting
|
[*] --> Starting
|
||||||
|
|
||||||
Starting --> Running : attach
|
Starting --> Running : attach
|
||||||
|
|
||||||
Running --> Async_Suspend_Requested : request_suspend
|
Running --> Async_Suspend_Requested : request_suspend
|
||||||
|
|
||||||
Async_Suspend_Requested --> Async_Suspended : finish_async_suspend
|
Async_Suspend_Requested --> Async_Suspended : finish_async_suspend
|
||||||
|
@ -153,7 +153,7 @@ direction TB
|
||||||
[*] --> Starting
|
[*] --> Starting
|
||||||
|
|
||||||
Starting --> GC_Unsafe : attach
|
Starting --> GC_Unsafe : attach
|
||||||
|
|
||||||
state GC_Unsafe_out <<choice>>
|
state GC_Unsafe_out <<choice>>
|
||||||
|
|
||||||
state GC_Unsafe {
|
state GC_Unsafe {
|
||||||
|
@ -191,7 +191,7 @@ direction TB
|
||||||
}
|
}
|
||||||
|
|
||||||
state GC_Safe_out <<choice>>
|
state GC_Safe_out <<choice>>
|
||||||
|
|
||||||
GC_Safe --> GC_Safe_out
|
GC_Safe --> GC_Safe_out
|
||||||
GC_Safe_out --> GC_Unsafe : done_Blocking
|
GC_Safe_out --> GC_Unsafe : done_Blocking
|
||||||
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
||||||
|
@ -315,7 +315,7 @@ direction TB
|
||||||
[*] --> Starting
|
[*] --> Starting
|
||||||
|
|
||||||
Starting --> GC_Unsafe : attach
|
Starting --> GC_Unsafe : attach
|
||||||
|
|
||||||
state GC_Unsafe_out <<choice>>
|
state GC_Unsafe_out <<choice>>
|
||||||
|
|
||||||
state GC_Unsafe {
|
state GC_Unsafe {
|
||||||
|
@ -355,7 +355,7 @@ direction TB
|
||||||
}
|
}
|
||||||
|
|
||||||
state GC_Safe_out <<choice>>
|
state GC_Safe_out <<choice>>
|
||||||
|
|
||||||
GC_Safe --> GC_Safe_out
|
GC_Safe --> GC_Safe_out
|
||||||
GC_Safe_out --> GC_Unsafe : done_Blocking
|
GC_Safe_out --> GC_Unsafe : done_Blocking
|
||||||
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
GC_Safe_out --> GC_Unsafe : abort_Blocking
|
||||||
|
@ -371,7 +371,7 @@ In hybrid suspend there are several additional states, and an additional `pulse`
|
||||||
|
|
||||||
User threads in `GC_Unsafe` periodically perform the `poll` transition, as in cooperative suspend.
|
User threads in `GC_Unsafe` periodically perform the `poll` transition, as in cooperative suspend.
|
||||||
|
|
||||||
User threads in `GC_Safe` states can suspend either by reaching a transition out of `GC_Safe` (ie they attempt a `done_Blocking` or `abort_Blocking` transition), or by beeing preemptively suspended by the suspend initiator. As a result there are two possible suspended states: `Blocking_Self_Suspended` (tried to do a `done_Blocking` or `abort_Blocking` transition) or `Blocking_Async_Suspended` (suspend initiator performed an `finish_async_suspend` transition).
|
User threads in `GC_Safe` states can suspend either by reaching a transition out of `GC_Safe` (ie they attempt a `done_Blocking` or `abort_Blocking` transition), or by being preemptively suspended by the suspend initiator. As a result there are two possible suspended states: `Blocking_Self_Suspended` (tried to do a `done_Blocking` or `abort_Blocking` transition) or `Blocking_Async_Suspended` (suspend initiator performed an `finish_async_suspend` transition).
|
||||||
|
|
||||||
When resuming, if a thread was `Blocking_Self_Suspended` it finishes the `done_Blocking` or `abort_Blocking` transition and goes to a `GC_Unsafe` state. If it was in `Blocking_Async_Suspended`, then it resumes still in `GC_Safe` and goes back to the `Blocking` state.
|
When resuming, if a thread was `Blocking_Self_Suspended` it finishes the `done_Blocking` or `abort_Blocking` transition and goes to a `GC_Unsafe` state. If it was in `Blocking_Async_Suspended`, then it resumes still in `GC_Safe` and goes back to the `Blocking` state.
|
||||||
|
|
||||||
|
|
|
@ -841,7 +841,7 @@ compile calls to “methods on `base`” (i.e., the statically known parent clas
|
||||||
|
|
||||||
Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md) C# language features implemented in C# 9.0.
|
Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md) C# language features implemented in C# 9.0.
|
||||||
|
|
||||||
This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compability rules are defined in ECMA I.8.7.1.
|
This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compatibility rules are defined in ECMA I.8.7.1.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
|
@ -881,7 +881,7 @@ Edit the first paragraph "The .override directive specifies that a virtual metho
|
||||||
|
|
||||||
### II.10.3.4 Impact of overrides on derived classes
|
### II.10.3.4 Impact of overrides on derived classes
|
||||||
Add a third bullet
|
Add a third bullet
|
||||||
"- If a virtual method is overridden via an .override directive or if a derived class provides an implentation and that virtual method in parent class was overridden with an .override directive where the method body of that second .override directive is decorated with `System.Runtime.CompilerServices.PreserveBaseOverridesAttribute` then the implementation of the virtual method shall be the implementation of the method body of the second .override directive as well. If this results in the implementor of the virtual method in the parent class not having a signature which is *covariant-return-compatible-with* the virtual method in the parent class, the program is not valid.
|
"- If a virtual method is overridden via an .override directive or if a derived class provides an implementation and that virtual method in parent class was overridden with an .override directive where the method body of that second .override directive is decorated with `System.Runtime.CompilerServices.PreserveBaseOverridesAttribute` then the implementation of the virtual method shall be the implementation of the method body of the second .override directive as well. If this results in the implementor of the virtual method in the parent class not having a signature which is *covariant-return-compatible-with* the virtual method in the parent class, the program is not valid.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -891,7 +891,7 @@ Add a third bullet
|
||||||
.class B extends A {
|
.class B extends A {
|
||||||
.method virtual DerivedRetType VirtualFunction() {
|
.method virtual DerivedRetType VirtualFunction() {
|
||||||
.custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = ( 01 00 00 00 )
|
.custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = ( 01 00 00 00 )
|
||||||
.override A.VirtualFuncion
|
.override A.VirtualFunction
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,7 +906,7 @@ Add a third bullet
|
||||||
{
|
{
|
||||||
.method virtual DerivedRetTypeNotDerivedFromMoreDerivedRetType VirtualFunction() {
|
.method virtual DerivedRetTypeNotDerivedFromMoreDerivedRetType VirtualFunction() {
|
||||||
.custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = ( 01 00 00 00 )
|
.custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = ( 01 00 00 00 )
|
||||||
.override A.VirtualFuncion
|
.override A.VirtualFunction
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ https://www.ecma-international.org/publications-and-standards/standards/ecma-335
|
||||||
- Remove the rest of this section. Its contents have been moved into sections I.8.6.1.1 and I.8.6.1.2
|
- Remove the rest of this section. Its contents have been moved into sections I.8.6.1.1 and I.8.6.1.2
|
||||||
|
|
||||||
### I.8.7
|
### I.8.7
|
||||||
- In the section about type compatibility when determining a type from a signature: The byref constraint is to be referenced from section I8.6.1.2 insetad of I.8.6.1.3
|
- In the section about type compatibility when determining a type from a signature: The byref constraint is to be referenced from section I8.6.1.2 instead of I.8.6.1.3
|
||||||
|
|
||||||
### I.8.9.2
|
### I.8.9.2
|
||||||
- Insert at the end of the first paragraph “An unmanaged pointer type cannot point to a managed pointer.”
|
- Insert at the end of the first paragraph “An unmanaged pointer type cannot point to a managed pointer.”
|
||||||
|
@ -1002,7 +1002,7 @@ Changes to signatures:
|
||||||
There are apis such as `System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<T>(...)` which require that the PE file have a particular structure. In particular, that api requires that the associated RVA of a FieldDef which is used to create a span must be naturally aligned over the data type that `CreateSpan` is instantiated over. There are 2 major concerns.
|
There are apis such as `System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<T>(...)` which require that the PE file have a particular structure. In particular, that api requires that the associated RVA of a FieldDef which is used to create a span must be naturally aligned over the data type that `CreateSpan` is instantiated over. There are 2 major concerns.
|
||||||
|
|
||||||
1. That the RVA be aligned when the PE file is constructed. This may be achieved by whatever means is most convenient for the compiler.
|
1. That the RVA be aligned when the PE file is constructed. This may be achieved by whatever means is most convenient for the compiler.
|
||||||
2. That in the presence of IL rewriters that the RVA remains aligned. This section descibes metadata which will be processed by IL rewriters in order to maintain the required alignment.
|
2. That in the presence of IL rewriters that the RVA remains aligned. This section describes metadata which will be processed by IL rewriters in order to maintain the required alignment.
|
||||||
|
|
||||||
In order to maintain alignment, if the field needs alignment to be preserved, the field must be of a type locally defined within the module which has a Pack (§II.10.7) value of the desired alignment. Unlike other uses of the .pack directive, in this circumstance the .pack specifies a minimum alignment.
|
In order to maintain alignment, if the field needs alignment to be preserved, the field must be of a type locally defined within the module which has a Pack (§II.10.7) value of the desired alignment. Unlike other uses of the .pack directive, in this circumstance the .pack specifies a minimum alignment.
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ Print\ out\ the\ version\ of\ the\ CLI\ tooling
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Print\ out\ a\ short\ help\ and\ a\ list\ of\ current\ commands.\
|
Print\ out\ a\ short\ help\ and\ a\ list\ of\ current\ commands.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.SH DOTNET COMMANDS
|
.SH DOTNET COMMANDS
|
||||||
|
@ -51,7 +51,7 @@ The following commands exist for dotnet.
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Compile\ the\ application\ to\ either\ an\ intermidiate\ language\ (IL)\ or\ to\ a\ native\ binary.\
|
Compile\ the\ application\ to\ either\ an\ intermediate\ language\ (IL)\ or\ to\ a\ native\ binary.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
|
@ -59,7 +59,7 @@ Compile\ the\ application\ to\ either\ an\ intermidiate\ language\ (IL)\ or\ to\
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Restores\ the\ dependencies\ for\ a\ given\ application.\
|
Restores\ the\ dependencies\ for\ a\ given\ application.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
|
@ -75,7 +75,7 @@ Runs\ the\ application\ from\ source.
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Publishes\ a\ flat\ directory\ that\ contains\ the\ application\ and\ its\ dependencies,\ including\ the\ runtime\ binaries.\
|
Publishes\ a\ flat\ directory\ that\ contains\ the\ application\ and\ its\ dependencies,\ including\ the\ runtime\ binaries.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
|
@ -91,7 +91,7 @@ Runs\ tests\ using\ a\ test\ runner\ specified\ in\ project.json.
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Initializes\ a\ sample\ .NET\ Core\ console\ application.\
|
Initializes\ a\ sample\ .NET\ Core\ console\ application.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
|
@ -108,7 +108,7 @@ Initializes\ a\ sample\ .NET\ Core\ console\ application\ that\ can\ be\ compile
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Restores\ dependencies\ for\ a\ given\ application.\
|
Restores\ dependencies\ for\ a\ given\ application.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
|
@ -116,7 +116,7 @@ Restores\ dependencies\ for\ a\ given\ application.\
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Compiles\ the\ application\ in\ a\ given\ directory.\
|
Compiles\ the\ application\ in\ a\ given\ directory.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
|
@ -141,7 +141,7 @@ The\ secondary\ cache.\ This\ is\ used\ by\ shared\ hosters\ (such\ as\ Azure)\
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
Specifies\ the\ location\ of\ the\ servicing\ index\ to\ use\ by\ the\ shared\ host\ when\ loading\ the\ runtime.\
|
Specifies\ the\ location\ of\ the\ servicing\ index\ to\ use\ by\ the\ shared\ host\ when\ loading\ the\ runtime.\
|
||||||
\f[]
|
\f[]
|
||||||
.fi
|
.fi
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
|
|
@ -66,7 +66,7 @@ Validation may fail for several reasons:
|
||||||
* Add a comment `/azp run runtime`
|
* Add a comment `/azp run runtime`
|
||||||
* Or, click on "re-run all checks" in the GitHub Checks tab
|
* Or, click on "re-run all checks" in the GitHub Checks tab
|
||||||
* Or, simply close and reopen the PR.
|
* Or, simply close and reopen the PR.
|
||||||
* Or, ammend your commit with `--amend --no-edit` and force push to your branch.
|
* Or, amend your commit with `--amend --no-edit` and force push to your branch.
|
||||||
|
|
||||||
### Additional information:
|
### Additional information:
|
||||||
* You can list the available pipelines by adding a comment like `/azp list` or get the available commands by adding a comment like `azp help`.
|
* You can list the available pipelines by adding a comment like `/azp list` or get the available commands by adding a comment like `azp help`.
|
||||||
|
|
|
@ -65,7 +65,7 @@ Feel free to use other labels if it helps your triage efforts (e.g. **needs more
|
||||||
1. Issue has no **Assignee**, unless someone is working on the issue at the moment
|
1. Issue has no **Assignee**, unless someone is working on the issue at the moment
|
||||||
* Motivation: Observation is that contributors are less likely to grab assigned issues, no matter what the repo rules say.
|
* Motivation: Observation is that contributors are less likely to grab assigned issues, no matter what the repo rules say.
|
||||||
1. Use **up-for-grabs** as much as possible, ideally with a quick note about next steps / complexity of the issue
|
1. Use **up-for-grabs** as much as possible, ideally with a quick note about next steps / complexity of the issue
|
||||||
* Note: Per http://up-for-grabs.net, such issues should be no longer than few nights' worth of work. They should be actionable (i.e. no misterious CI failures or UWP issues that can't be tested in the open).
|
* Note: Per http://up-for-grabs.net, such issues should be no longer than few nights' worth of work. They should be actionable (i.e. no mysterious CI failures or UWP issues that can't be tested in the open).
|
||||||
1. Set milestone to **Future**, unless you can 95%-commit you can fund the issue in specific milestone
|
1. Set milestone to **Future**, unless you can 95%-commit you can fund the issue in specific milestone
|
||||||
* Motivation: Helps communicate desire/timeline to community. Can spark further priority/impact discussion.
|
* Motivation: Helps communicate desire/timeline to community. Can spark further priority/impact discussion.
|
||||||
1. Each issue has exactly one "*issue type*" label (**bug**, **enhancement**, **api-needs-work**, **test bug**, **test enhancement**, **question**, **documentation**, etc.)
|
1. Each issue has exactly one "*issue type*" label (**bug**, **enhancement**, **api-needs-work**, **test bug**, **test enhancement**, **question**, **documentation**, etc.)
|
||||||
|
|
|
@ -131,7 +131,7 @@ Suggestions for best practices or effective techniques are welcome.
|
||||||
|
|
||||||
### Bring up quantitative measurements.
|
### Bring up quantitative measurements.
|
||||||
|
|
||||||
For Jit testing we'll need various quantitatve assessments of Jit behavior:
|
For Jit testing we'll need various quantitative assessments of Jit behavior:
|
||||||
|
|
||||||
1. Time spent jitting
|
1. Time spent jitting
|
||||||
2. Speed of jitted code
|
2. Speed of jitted code
|
||||||
|
|
|
@ -145,7 +145,7 @@ issue should go away. This only has to be one once per machine (until you upda
|
||||||
|
|
||||||
### Alternative: Turn off use of precompiled code ###
|
### Alternative: Turn off use of precompiled code ###
|
||||||
|
|
||||||
If you don't have the abiltiy to update the .NET Runtime (to add crossgen), or if the above procedure did not work
|
If you don't have the ability to update the .NET Runtime (to add crossgen), or if the above procedure did not work
|
||||||
for some reason, there is another approach to getting framework symbols. You can tell the runtime to simply
|
for some reason, there is another approach to getting framework symbols. You can tell the runtime to simply
|
||||||
not use the precompiled framework code. The code will be Just in time compiled and the special crossgen tool
|
not use the precompiled framework code. The code will be Just in time compiled and the special crossgen tool
|
||||||
is not needed. This works, but will increase startup time for your code by something like a second or two. If you
|
is not needed. This works, but will increase startup time for your code by something like a second or two. If you
|
||||||
|
|
|
@ -111,7 +111,7 @@ The **Failure Trend** graph attempts to show what is failing in bar graph and gi
|
||||||
|
|
||||||
The **Failed Runs** graph is the most interesting for finding specific issues. As of writing the `Top 10 failing tasks` are:
|
The **Failed Runs** graph is the most interesting for finding specific issues. As of writing the `Top 10 failing tasks` are:
|
||||||
|
|
||||||
*Note* that any one of these buckets can include random one off infrastructure failures or systimatic Azure Dev Ops failures. For example the build bucket can include issues like:
|
*Note* that any one of these buckets can include random one off infrastructure failures or systematic Azure Dev Ops failures. For example the build bucket can include issues like:
|
||||||
|
|
||||||
> fips.c(143): OpenSSL internal error
|
> fips.c(143): OpenSSL internal error
|
||||||
|
|
||||||
|
|
|
@ -175,4 +175,4 @@ This will launch the Visual Studio debugger, with a solution setup for debugging
|
||||||
|
|
||||||
# Debugging compilation graph
|
# Debugging compilation graph
|
||||||
|
|
||||||
The AOT compilation is driven by a dependency graph. If you need to troubleshoot the dependency graph (to figure out why something was or wasn't generated) you can follow [this guide](debuging-compiler-dependency-analysis.md)
|
The AOT compilation is driven by a dependency graph. If you need to troubleshoot the dependency graph (to figure out why something was or wasn't generated) you can follow [this guide](debugging-compiler-dependency-analysis.md)
|
||||||
|
|
|
@ -34,7 +34,7 @@ Usage instructions:
|
||||||
|
|
||||||
# Single Node Exploration #
|
# Single Node Exploration #
|
||||||
Once the interesting node(s) have been identified in the dependency graph window, select one of them, and then press Explore.
|
Once the interesting node(s) have been identified in the dependency graph window, select one of them, and then press Explore.
|
||||||
- In the Node Explorer window, the Dependent nodes (the ones which dependend on the current node are the nodes displayed above, and the Dependee nodes (the nodes that this node depends on) are displayed below. Each node in the list is paired with a textual reason as to why that edge in the graph exists.
|
- In the Node Explorer window, the Dependent nodes (the ones which depend on the current node are the nodes displayed above, and the Dependee nodes (the nodes that this node depends on) are displayed below. Each node in the list is paired with a textual reason as to why that edge in the graph exists.
|
||||||
- Select a node to explore further and press the corresponding button to make it happen.
|
- Select a node to explore further and press the corresponding button to make it happen.
|
||||||
|
|
||||||
WhyDGML
|
WhyDGML
|
|
@ -60,7 +60,7 @@ Since you're debugging an optimized release build, it is likely the debugger wil
|
||||||
Build the runtime for your android architecture: `ANDROID_NDK_ROOT=<path_to_android_ndk> ./build.sh --os android --arch x86 -c Debug`. See the instructions for [Testing Android](../../testing/libraries/testing-android.md) for details.
|
Build the runtime for your android architecture: `ANDROID_NDK_ROOT=<path_to_android_ndk> ./build.sh --os android --arch x86 -c Debug`. See the instructions for [Testing Android](../../testing/libraries/testing-android.md) for details.
|
||||||
|
|
||||||
|
|
||||||
In the source code for the C# project, add the following to the .csproj (replacing `<RUNTIME_GIT_ROOT>` by the apropriate location):
|
In the source code for the C# project, add the following to the .csproj (replacing `<RUNTIME_GIT_ROOT>` by the appropriate location):
|
||||||
|
|
||||||
```
|
```
|
||||||
<Target Name="UpdateRuntimePack"
|
<Target Name="UpdateRuntimePack"
|
||||||
|
|
|
@ -61,7 +61,7 @@ disassemble wasm executables (.wasm files).
|
||||||
Wasm execution can be made deterministic by passing the -s DETERMINISTIC=1 option to emcc.
|
Wasm execution can be made deterministic by passing the -s DETERMINISTIC=1 option to emcc.
|
||||||
This will cause the app to always execute the same way, i.e. using the same memory
|
This will cause the app to always execute the same way, i.e. using the same memory
|
||||||
addresses, random numbers, etc. This can be used to make random crashes happen reliably.
|
addresses, random numbers, etc. This can be used to make random crashes happen reliably.
|
||||||
Sometimes, hovewer, turning this on will make the problem disappear. In this case, it
|
Sometimes, however, turning this on will make the problem disappear. In this case, it
|
||||||
might be useful to add some controlled indeterminism. For example, to make the
|
might be useful to add some controlled indeterminism. For example, to make the
|
||||||
random number generator mostly deterministic, change `$getRandomDevice` in
|
random number generator mostly deterministic, change `$getRandomDevice` in
|
||||||
`upstream/emscripten/src/library.js` to:
|
`upstream/emscripten/src/library.js` to:
|
||||||
|
|
|
@ -45,7 +45,7 @@ This will use `crossgen.exe` to precompile test executables before they are exec
|
||||||
src\tests\build.cmd -priority=1
|
src\tests\build.cmd -priority=1
|
||||||
```
|
```
|
||||||
|
|
||||||
The above is an example of requesting that priority '1' and below be built. The default priority value is '0'. If '1' is specified, all tests with `CLRTestPriorty` `0` **and** `1` will be built and run.
|
The above is an example of requesting that priority '1' and below be built. The default priority value is '0'. If '1' is specified, all tests with `CLRTestPriority` `0` **and** `1` will be built and run.
|
||||||
|
|
||||||
## Generating Core_Root
|
## Generating Core_Root
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ For example: `./build.sh mono release -test:JIT/opt/InstructionCombining/DivToMu
|
||||||
|
|
||||||
Run individual test:
|
Run individual test:
|
||||||
```
|
```
|
||||||
bash ./artifacts/tests/coreclr/OSX.x64.Release/JIT/opt/InstructionCombining/DivToMul/DivToMul.sh -coreroot=`pwd`/artifacts/tests/coreclr/OSX.x64.Release/Tests/Core_Root
|
bash ./artifacts/tests/coreclr/OSX.x64.Release/JIT/opt/InstructionCombining/DivToMul/DivToMul.sh -coreroot=`pwd`/artifacts/tests/coreclr/OSX.x64.Release/Tests/Core_Root
|
||||||
```
|
```
|
||||||
|
|
||||||
Run all built tests:
|
Run all built tests:
|
||||||
|
@ -118,7 +118,7 @@ make run
|
||||||
Note that the default configuration of this sample is LLVM JIT.
|
Note that the default configuration of this sample is LLVM JIT.
|
||||||
|
|
||||||
## WebAssembly
|
## WebAssembly
|
||||||
To run the WebAssembly sample, cd to `wasm`. There are two sub-folders `browser` and `console`. One is set up to run the progam in browser, the other is set up to run the program in console. Enter the desirable sub-folder and execute
|
To run the WebAssembly sample, cd to `wasm`. There are two sub-folders `browser` and `console`. One is set up to run the program in browser, the other is set up to run the program in console. Enter the desirable sub-folder and execute
|
||||||
|
|
||||||
```
|
```
|
||||||
make build && make run
|
make build && make run
|
||||||
|
|
|
@ -1139,7 +1139,7 @@ dotnet_diagnostic.SA1314.severity = none
|
||||||
# SA1316: Tuple element names should use correct casing
|
# SA1316: Tuple element names should use correct casing
|
||||||
dotnet_diagnostic.SA1316.severity = none
|
dotnet_diagnostic.SA1316.severity = none
|
||||||
|
|
||||||
# SA1400: Member should declare an access modifer
|
# SA1400: Member should declare an access modifier
|
||||||
dotnet_diagnostic.SA1400.severity = warning
|
dotnet_diagnostic.SA1400.severity = warning
|
||||||
|
|
||||||
# SA1401: Fields should be private
|
# SA1401: Fields should be private
|
||||||
|
|
|
@ -849,7 +849,7 @@ dotnet_diagnostic.CA5400.severity = none
|
||||||
# CA5401: Do not use CreateEncryptor with non-default IV
|
# CA5401: Do not use CreateEncryptor with non-default IV
|
||||||
dotnet_diagnostic.CA5401.severity = none
|
dotnet_diagnostic.CA5401.severity = none
|
||||||
|
|
||||||
# CA5402: Use CreateEncryptor with the default IV
|
# CA5402: Use CreateEncryptor with the default IV
|
||||||
dotnet_diagnostic.CA5402.severity = none
|
dotnet_diagnostic.CA5402.severity = none
|
||||||
|
|
||||||
# CA5403: Do not hard-code certificate
|
# CA5403: Do not hard-code certificate
|
||||||
|
@ -1134,7 +1134,7 @@ dotnet_diagnostic.SA1314.severity = none
|
||||||
# SA1316: Tuple element names should use correct casing
|
# SA1316: Tuple element names should use correct casing
|
||||||
dotnet_diagnostic.SA1316.severity = none
|
dotnet_diagnostic.SA1316.severity = none
|
||||||
|
|
||||||
# SA1400: Member should declare an access modifer
|
# SA1400: Member should declare an access modifier
|
||||||
dotnet_diagnostic.SA1400.severity = none
|
dotnet_diagnostic.SA1400.severity = none
|
||||||
|
|
||||||
# SA1401: Fields should be private
|
# SA1401: Fields should be private
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<IsEligibleForNgenOptimization Condition="'$(GeneratePlatformNotSupportedAssembly)' == 'true' or '$(GeneratePlatformNotSupportedAssemblyMessage)' != ''">false</IsEligibleForNgenOptimization>
|
<IsEligibleForNgenOptimization Condition="'$(GeneratePlatformNotSupportedAssembly)' == 'true' or '$(GeneratePlatformNotSupportedAssemblyMessage)' != ''">false</IsEligibleForNgenOptimization>
|
||||||
<!-- There's an issue causing IBCMerge failures because of mismatched MVIDs
|
<!-- There's an issue causing IBCMerge failures because of mismatched MVIDs
|
||||||
across many of our assemblies on Mac, so disable
|
across many of our assemblies on Mac, so disable
|
||||||
IBCMerge optimizations on Mac for now to unblock the offical build.
|
IBCMerge optimizations on Mac for now to unblock the official build.
|
||||||
See issue https://github.com/dotnet/runtime/issues/33303
|
See issue https://github.com/dotnet/runtime/issues/33303
|
||||||
-->
|
-->
|
||||||
<IsEligibleForNgenOptimization Condition="'$(TargetOS)' == 'OSX' or '$(TargetsMobile)' == 'true'">false</IsEligibleForNgenOptimization>
|
<IsEligibleForNgenOptimization Condition="'$(TargetOS)' == 'OSX' or '$(TargetsMobile)' == 'true'">false</IsEligibleForNgenOptimization>
|
||||||
|
|
|
@ -33,7 +33,7 @@ elif [[ "$1" == "MacCatalyst" || "$1" == "OSX" || "$1" == "tvOS" || "$1" == "iOS
|
||||||
if ! brew_output="$(brew uninstall openssl@1.0.2t 2>&1 >/dev/null)"; then
|
if ! brew_output="$(brew uninstall openssl@1.0.2t 2>&1 >/dev/null)"; then
|
||||||
echo "didn't uninstall openssl@1.0.2t"
|
echo "didn't uninstall openssl@1.0.2t"
|
||||||
else
|
else
|
||||||
echo "succesfully uninstalled openssl@1.0.2t"
|
echo "successfully uninstalled openssl@1.0.2t"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ if /i "%~1" == "wasm" (set __VCBuildArch=x86_amd64)
|
||||||
:: is no longer set as a global environment variable and is instead only set if the user
|
:: is no longer set as a global environment variable and is instead only set if the user
|
||||||
:: has launched the Visual Studio Developer Command Prompt.
|
:: has launched the Visual Studio Developer Command Prompt.
|
||||||
::
|
::
|
||||||
:: Following this logic, we will default to the Visual Studio toolset assocated with the active
|
:: Following this logic, we will default to the Visual Studio toolset associated with the active
|
||||||
:: Developer Command Prompt. Otherwise, we will query VSWhere to locate the later version of
|
:: Developer Command Prompt. Otherwise, we will query VSWhere to locate the later version of
|
||||||
:: Visual Studio available on the machine. Finally, we will fail the script if no supported
|
:: Visual Studio available on the machine. Finally, we will fail the script if no supported
|
||||||
:: instance can be found.
|
:: instance can be found.
|
||||||
|
|
|
@ -9,7 +9,7 @@ parameters:
|
||||||
# Will only include paths specified in the list.
|
# Will only include paths specified in the list.
|
||||||
# 3. exclude + include:
|
# 3. exclude + include:
|
||||||
# 1st we evaluate changes for all paths except ones in excluded list. If we can't find
|
# 1st we evaluate changes for all paths except ones in excluded list. If we can't find
|
||||||
# any applicable changes like that, then we evaluate changes for incldued paths
|
# any applicable changes like that, then we evaluate changes for included paths
|
||||||
# if any of these two finds changes, then a variable will be set to true.
|
# if any of these two finds changes, then a variable will be set to true.
|
||||||
# In order to consume this variable you need to reference it via: $[ dependencies.evaluate_paths.outputs['SetPathVars_<subset>.containschange'] ]
|
# In order to consume this variable you need to reference it via: $[ dependencies.evaluate_paths.outputs['SetPathVars_<subset>.containschange'] ]
|
||||||
#
|
#
|
||||||
|
@ -40,7 +40,7 @@ jobs:
|
||||||
- ${{ each path in parameters.paths }}:
|
- ${{ each path in parameters.paths }}:
|
||||||
- template: evaluate-changed-paths.yml
|
- template: evaluate-changed-paths.yml
|
||||||
parameters:
|
parameters:
|
||||||
subsetName: ${{ path.subset }}
|
subsetName: ${{ path.subset }}
|
||||||
arguments:
|
arguments:
|
||||||
# The commit that we're building is always a merge commit that is merging into the target branch.
|
# The commit that we're building is always a merge commit that is merging into the target branch.
|
||||||
# So the first parent of the commit is on the target branch and the second parent is on the source branch.
|
# So the first parent of the commit is on the target branch and the second parent is on the source branch.
|
||||||
|
|
|
@ -83,7 +83,7 @@ jobs:
|
||||||
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
# AppleClang has different version scheme, so we let complier introspection pick up the available clang from PATH
|
# AppleClang has different version scheme, so we let compiler introspection pick up the available clang from PATH
|
||||||
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
|
|
|
@ -270,7 +270,7 @@ jobs:
|
||||||
|
|
||||||
|
|
||||||
- ${{ if eq(parameters.runtimeFlavor, 'mono') }}:
|
- ${{ if eq(parameters.runtimeFlavor, 'mono') }}:
|
||||||
# We need to explictly download CoreCLR for Mono
|
# We need to explicitly download CoreCLR for Mono
|
||||||
- template: /eng/pipelines/common/download-artifact-step.yml
|
- template: /eng/pipelines/common/download-artifact-step.yml
|
||||||
parameters:
|
parameters:
|
||||||
unpackFolder: $(coreClrProductRootFolderPath)
|
unpackFolder: $(coreClrProductRootFolderPath)
|
||||||
|
|
|
@ -15,7 +15,7 @@ jobs:
|
||||||
jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml
|
jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml
|
||||||
buildConfig: release
|
buildConfig: release
|
||||||
platforms:
|
platforms:
|
||||||
# disable Linux x64 for now untill OOMs are resolved.
|
# disable Linux x64 for now until OOMs are resolved.
|
||||||
# - Linux_x64
|
# - Linux_x64
|
||||||
- Linux_arm64
|
- Linux_arm64
|
||||||
- windows_x64
|
- windows_x64
|
||||||
|
@ -39,7 +39,7 @@ jobs:
|
||||||
jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
|
jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
|
||||||
buildConfig: release
|
buildConfig: release
|
||||||
platforms:
|
platforms:
|
||||||
# disable Linux x64 for now untill OOMs are resolved.
|
# disable Linux x64 for now until OOMs are resolved.
|
||||||
# - Linux_x64
|
# - Linux_x64
|
||||||
- Linux_arm64
|
- Linux_arm64
|
||||||
- windows_x64
|
- windows_x64
|
||||||
|
|
|
@ -62,7 +62,7 @@ jobs:
|
||||||
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
# AppleClang has different version scheme, so we let complier introspection pick up the available clang from PATH
|
# AppleClang has different version scheme, so we let compiler introspection pick up the available clang from PATH
|
||||||
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
|
|
|
@ -97,7 +97,7 @@ jobs:
|
||||||
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubgroup, '_musl'), eq(parameters.archType, 'x64')) }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
# AppleClang has different version scheme, so we let complier introspection pick up the available clang from PATH
|
# AppleClang has different version scheme, so we let compiler introspection pick up the available clang from PATH
|
||||||
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
- ${{ if eq(parameters.osGroup, 'OSX') }}:
|
||||||
- name: compilerArg
|
- name: compilerArg
|
||||||
value: ''
|
value: ''
|
||||||
|
|
|
@ -7,7 +7,7 @@ Scenarios:
|
||||||
Will only include paths specified in the list.
|
Will only include paths specified in the list.
|
||||||
3. exclude + include:
|
3. exclude + include:
|
||||||
1st we evaluate changes for all paths except ones in excluded list. If we can not find
|
1st we evaluate changes for all paths except ones in excluded list. If we can not find
|
||||||
any applicable changes like that, then we evaluate changes for incldued paths
|
any applicable changes like that, then we evaluate changes for included paths
|
||||||
if any of these two finds changes, then a variable will be set to true.
|
if any of these two finds changes, then a variable will be set to true.
|
||||||
In order to consume this variable in a yaml pipeline, reference it via: $[ dependencies.<JobName>.outputs["<StepName>_<subset>.containschange"] ]
|
In order to consume this variable in a yaml pipeline, reference it via: $[ dependencies.<JobName>.outputs["<StepName>_<subset>.containschange"] ]
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ jobs:
|
||||||
timeoutInMinutes: 90
|
timeoutInMinutes: 90
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build with RuntimeFlavor only. This excercise code paths where only RuntimeFlavor is
|
# Build with RuntimeFlavor only. This exercise code paths where only RuntimeFlavor is
|
||||||
# specified. Catches cases where we depend on Configuration also being specified
|
# specified. Catches cases where we depend on Configuration also being specified
|
||||||
#
|
#
|
||||||
- template: /eng/pipelines/common/platform-matrix.yml
|
- template: /eng/pipelines/common/platform-matrix.yml
|
||||||
|
@ -90,7 +90,7 @@ jobs:
|
||||||
timeoutInMinutes: 90
|
timeoutInMinutes: 90
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build Mono + Libraries. This excercises the code path where we build libraries without
|
# Build Mono + Libraries. This exercises the code path where we build libraries without
|
||||||
# first building CoreCLR
|
# first building CoreCLR
|
||||||
#
|
#
|
||||||
- template: /eng/pipelines/common/platform-matrix.yml
|
- template: /eng/pipelines/common/platform-matrix.yml
|
||||||
|
|
|
@ -14,7 +14,7 @@ Try {
|
||||||
|
|
||||||
$ValidTo = [datetime]::Parse($Cert.GetExpirationDatestring())
|
$ValidTo = [datetime]::Parse($Cert.GetExpirationDatestring())
|
||||||
|
|
||||||
Write-Host "`nConnection Successfull" -ForegroundColor DarkGreen
|
Write-Host "`nConnection Successful" -ForegroundColor DarkGreen
|
||||||
Write-Host "Website: $WebsiteURL"
|
Write-Host "Website: $WebsiteURL"
|
||||||
}
|
}
|
||||||
Catch { Throw $_ }
|
Catch { Throw $_ }
|
||||||
|
|
|
@ -19,7 +19,7 @@ trigger:
|
||||||
- THIRD-PARTY-NOTICES.TXT
|
- THIRD-PARTY-NOTICES.TXT
|
||||||
|
|
||||||
# This is an official pipeline that should not be triggerable from a PR,
|
# This is an official pipeline that should not be triggerable from a PR,
|
||||||
# there is no public pipeline assosiated with it.
|
# there is no public pipeline associated with it.
|
||||||
pr: none
|
pr: none
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
|
@ -177,7 +177,7 @@ stages:
|
||||||
runtimeVariant: multithread
|
runtimeVariant: multithread
|
||||||
extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml
|
extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml
|
||||||
extraStepsParameters:
|
extraStepsParameters:
|
||||||
name: MonoRuntimePacks
|
name: MonoRuntimePacks
|
||||||
|
|
||||||
# Build Mono AOT offset headers once, for consumption elsewhere
|
# Build Mono AOT offset headers once, for consumption elsewhere
|
||||||
#
|
#
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<!--
|
<!--
|
||||||
Microsoft.Net.Test.Sdk has a dependency on Newtonsoft.Json v9.0.1. We upgrade the dependency version
|
Microsoft.Net.Test.Sdk has a dependency on Newtonsoft.Json v9.0.1. We upgrade the dependency version
|
||||||
with the one used in libraries to have a consistent set of dependency versions. Additionally this works
|
with the one used in libraries to have a consistent set of dependency versions. Additionally this works
|
||||||
around a dupliate type between System.Runtime.Serialization.Formatters and Newtonsoft.Json.
|
around a duplicate type between System.Runtime.Serialization.Formatters and Newtonsoft.Json.
|
||||||
-->
|
-->
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
|
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
**
|
**
|
||||||
**
|
**
|
||||||
** Purpose: This class only exists to provide support for
|
** Purpose: This class only exists to provide support for
|
||||||
** implenting IDispatch on managed objects. It is
|
** implementing IDispatch on managed objects. It is
|
||||||
** used to provide OleAut style coercion rules.
|
** used to provide OleAut style coercion rules.
|
||||||
**
|
**
|
||||||
**
|
**
|
||||||
|
|
|
@ -806,7 +806,7 @@ namespace System.Reflection.Emit
|
||||||
// Emitting a switch table
|
// Emitting a switch table
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int remaining; // number of bytes remaining for this switch instruction to be substracted
|
int remaining; // number of bytes remaining for this switch instruction to be subtracted
|
||||||
// for computing the offset
|
// for computing the offset
|
||||||
|
|
||||||
int count = labels.Length;
|
int count = labels.Length;
|
||||||
|
|
|
@ -489,7 +489,7 @@ namespace System.Reflection.Emit
|
||||||
|
|
||||||
private void AddElementType(CorElementType cvt)
|
private void AddElementType(CorElementType cvt)
|
||||||
{
|
{
|
||||||
// Adds an element to the signature. A managed represenation of CorSigCompressElement
|
// Adds an element to the signature. A managed representation of CorSigCompressElement
|
||||||
if (m_currSig + 1 > m_signature.Length)
|
if (m_currSig + 1 > m_signature.Length)
|
||||||
m_signature = ExpandArray(m_signature);
|
m_signature = ExpandArray(m_signature);
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ namespace System.Reflection.Emit
|
||||||
|
|
||||||
private void AddToken(int token)
|
private void AddToken(int token)
|
||||||
{
|
{
|
||||||
// A managed represenation of CompressToken
|
// A managed representation of CompressToken
|
||||||
// Pulls the token appart to get a rid, adds some appropriate bits
|
// Pulls the token appart to get a rid, adds some appropriate bits
|
||||||
// to the token and then adds this to the signature.
|
// to the token and then adds this to the signature.
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace System.Reflection
|
||||||
PositionImpl = accessor.Position;
|
PositionImpl = accessor.Position;
|
||||||
AttrsImpl = accessor.Attributes;
|
AttrsImpl = accessor.Attributes;
|
||||||
|
|
||||||
// Strictly speeking, property's don't contain paramter tokens
|
// Strictly speeking, property's don't contain parameter tokens
|
||||||
// However we need this to make ca's work... oh well...
|
// However we need this to make ca's work... oh well...
|
||||||
m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken;
|
m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken;
|
||||||
m_scope = accessor.m_scope;
|
m_scope = accessor.m_scope;
|
||||||
|
|
|
@ -520,7 +520,7 @@ CrashInfo::GetBaseAddressFromName(const char* moduleName)
|
||||||
{
|
{
|
||||||
std::string name = GetFileName(moduleInfo->ModuleName());
|
std::string name = GetFileName(moduleInfo->ModuleName());
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Module names are case insenstive on MacOS
|
// Module names are case insensitive on MacOS
|
||||||
if (strcasecmp(name.c_str(), moduleName) == 0)
|
if (strcasecmp(name.c_str(), moduleName) == 0)
|
||||||
#else
|
#else
|
||||||
if (name.compare(moduleName) == 0)
|
if (name.compare(moduleName) == 0)
|
||||||
|
|
|
@ -512,7 +512,7 @@ BOOL DacDbiInterfaceImpl::IsLeftSideInitialized()
|
||||||
// 4) assign the object to g_pDebugger.
|
// 4) assign the object to g_pDebugger.
|
||||||
// 5) later, LS initialization code will assign g_pDebugger->m_fLeftSideInitialized = TRUE.
|
// 5) later, LS initialization code will assign g_pDebugger->m_fLeftSideInitialized = TRUE.
|
||||||
//
|
//
|
||||||
// The memory write in #5 is atomic. There is no window where we're reading unitialized data.
|
// The memory write in #5 is atomic. There is no window where we're reading uninitialized data.
|
||||||
|
|
||||||
return (g_pDebugger->m_fLeftSideInitialized != 0);
|
return (g_pDebugger->m_fLeftSideInitialized != 0);
|
||||||
}
|
}
|
||||||
|
@ -1212,7 +1212,7 @@ mdSignature DacDbiInterfaceImpl::GetILCodeAndSigHelper(Module * pModule,
|
||||||
|
|
||||||
// Method not overridden - get the original copy of the IL by going to the PE file/RVA
|
// Method not overridden - get the original copy of the IL by going to the PE file/RVA
|
||||||
// If this is in a dynamic module then don't even attempt this since ReflectionModule::GetIL isn't
|
// If this is in a dynamic module then don't even attempt this since ReflectionModule::GetIL isn't
|
||||||
// implemend for DAC.
|
// implemented for DAC.
|
||||||
if (pTargetIL == 0 && !pModule->IsReflection())
|
if (pTargetIL == 0 && !pModule->IsReflection())
|
||||||
{
|
{
|
||||||
pTargetIL = (TADDR)pModule->GetIL(methodRVA);
|
pTargetIL = (TADDR)pModule->GetIL(methodRVA);
|
||||||
|
@ -2875,7 +2875,7 @@ void DacDbiInterfaceImpl::GetMethodDescParams(
|
||||||
thCurrent = methodInst[i - cGenericClassTypeParams];
|
thCurrent = methodInst[i - cGenericClassTypeParams];
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is the possiblity that we'll get this far with a dump and not fail, but still
|
// There is the possibility that we'll get this far with a dump and not fail, but still
|
||||||
// not be able to get full info for a particular param.
|
// not be able to get full info for a particular param.
|
||||||
EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER
|
EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER
|
||||||
{
|
{
|
||||||
|
@ -5871,7 +5871,7 @@ HRESULT DacDbiInterfaceImpl::IsWinRTModule(VMPTR_Module vmModule, BOOL& isWinRT)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines the app domain id for the object refered to by a given VMPTR_OBJECTHANDLE
|
// Determines the app domain id for the object referred to by a given VMPTR_OBJECTHANDLE
|
||||||
ULONG DacDbiInterfaceImpl::GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle)
|
ULONG DacDbiInterfaceImpl::GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle)
|
||||||
{
|
{
|
||||||
DD_ENTER_MAY_THROW;
|
DD_ENTER_MAY_THROW;
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ protected:
|
||||||
// if the specified module is a WinRT module then isWinRT will equal TRUE
|
// if the specified module is a WinRT module then isWinRT will equal TRUE
|
||||||
HRESULT IsWinRTModule(VMPTR_Module vmModule, BOOL& isWinRT);
|
HRESULT IsWinRTModule(VMPTR_Module vmModule, BOOL& isWinRT);
|
||||||
|
|
||||||
// Determines the app domain id for the object refered to by a given VMPTR_OBJECTHANDLE
|
// Determines the app domain id for the object referred to by a given VMPTR_OBJECTHANDLE
|
||||||
ULONG GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle);
|
ULONG GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -821,8 +821,8 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,
|
||||||
// Since return addres point to the next(!) instruction after [call IL_Throw] this sometimes can lead to incorrect exception stacktraces
|
// Since return addres point to the next(!) instruction after [call IL_Throw] this sometimes can lead to incorrect exception stacktraces
|
||||||
// where a next source line is spotted as an exception origin. This happens when the next instruction after [call IL_Throw] belongs to
|
// where a next source line is spotted as an exception origin. This happens when the next instruction after [call IL_Throw] belongs to
|
||||||
// a sequence point and a source line different from a sequence point and a source line of [call IL_Throw].
|
// a sequence point and a source line different from a sequence point and a source line of [call IL_Throw].
|
||||||
// Later on this flag is used in order to adjust nativeOffset and make ICorDebugILFrame::GetIP return IL offset withing
|
// Later on this flag is used in order to adjust nativeOffset and make ICorDebugILFrame::GetIP return IL offset within
|
||||||
// the same sequence point as an actuall IL throw instruction.
|
// the same sequence point as an actual IL throw instruction.
|
||||||
|
|
||||||
// Here is how we detect it:
|
// Here is how we detect it:
|
||||||
// We can assume that nativeOffset points to an the instruction after [call IL_Throw] when these conditioins are met:
|
// We can assume that nativeOffset points to an the instruction after [call IL_Throw] when these conditioins are met:
|
||||||
|
|
|
@ -1481,7 +1481,7 @@ void DacEnumCodeForStackwalk(TADDR taCallEnd)
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// * range - the address and the size of the memory range
|
// * range - the address and the size of the memory range
|
||||||
// * pBuffer - the buffer containting the memory range
|
// * pBuffer - the buffer containing the memory range
|
||||||
//
|
//
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// Return S_OK if everything succeeds.
|
// Return S_OK if everything succeeds.
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ public:
|
||||||
size_t *taggedMemorySizeInBytes);
|
size_t *taggedMemorySizeInBytes);
|
||||||
|
|
||||||
// ISOSDacInterface12
|
// ISOSDacInterface12
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetGlobalAllocationContext(
|
virtual HRESULT STDMETHODCALLTYPE GetGlobalAllocationContext(
|
||||||
CLRDATA_ADDRESS *allocPtr,
|
CLRDATA_ADDRESS *allocPtr,
|
||||||
CLRDATA_ADDRESS *allocLimit);
|
CLRDATA_ADDRESS *allocLimit);
|
||||||
|
|
||||||
|
@ -1529,7 +1529,7 @@ extern ClrDataAccess* g_dacImpl;
|
||||||
* all handles, or filled the array.
|
* all handles, or filled the array.
|
||||||
* 3. Storage variables to hold the overflow. That is, we were walking the handle
|
* 3. Storage variables to hold the overflow. That is, we were walking the handle
|
||||||
* table, filled the array that the user gave us, then needed to store the extra
|
* table, filled the array that the user gave us, then needed to store the extra
|
||||||
* handles the handle table continued to enumerate to us. This is implmeneted
|
* handles the handle table continued to enumerate to us. This is implemented
|
||||||
* as a linked list of arrays (mHead, mHead.Next, etc).
|
* as a linked list of arrays (mHead, mHead.Next, etc).
|
||||||
* 4. Variables which store the location of where we are in the overflow data.
|
* 4. Variables which store the location of where we are in the overflow data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct FakeStubUnwindInfoHeaderSuffix
|
||||||
UCHAR nUnwindInfoSize;
|
UCHAR nUnwindInfoSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variable-sized struct that preceeds a Stub when the stub requires unwind
|
// Variable-sized struct that precedes a Stub when the stub requires unwind
|
||||||
// information. Followed by a StubUnwindInfoHeaderSuffix.
|
// information. Followed by a StubUnwindInfoHeaderSuffix.
|
||||||
struct FakeStubUnwindInfoHeader
|
struct FakeStubUnwindInfoHeader
|
||||||
{
|
{
|
||||||
|
|
|
@ -5230,7 +5230,7 @@ EnumMethodInstances::Next(ClrDataAccess* dac,
|
||||||
m_methodIter.Start(m_appDomain,
|
m_methodIter.Start(m_appDomain,
|
||||||
m_methodDesc->GetModule(), // module
|
m_methodDesc->GetModule(), // module
|
||||||
m_methodDesc->GetMemberDef(), // token
|
m_methodDesc->GetMemberDef(), // token
|
||||||
m_methodDesc); // intial method desc
|
m_methodDesc); // initial method desc
|
||||||
}
|
}
|
||||||
|
|
||||||
NextMethod:
|
NextMethod:
|
||||||
|
|
|
@ -252,7 +252,7 @@ HRESULT GetResourceRvaFromResourceSectionRvaByName(ICorDebugDataTarget* pDataTar
|
||||||
// pNextLevelRVA - out - The RVA for the next level tree directory or the RVA of the resource entry
|
// pNextLevelRVA - out - The RVA for the next level tree directory or the RVA of the resource entry
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// S_OK if succesful or an appropriate failing HRESULT
|
// S_OK if successful or an appropriate failing HRESULT
|
||||||
HRESULT GetNextLevelResourceEntryRVA(ICorDebugDataTarget* pDataTarget,
|
HRESULT GetNextLevelResourceEntryRVA(ICorDebugDataTarget* pDataTarget,
|
||||||
DWORD id,
|
DWORD id,
|
||||||
ULONG64 moduleBaseAddress,
|
ULONG64 moduleBaseAddress,
|
||||||
|
@ -319,7 +319,7 @@ HRESULT GetNextLevelResourceEntryRVA(ICorDebugDataTarget* pDataTarget,
|
||||||
// pNextLevelRVA - out - The RVA for the next level tree directory or the RVA of the resource entry
|
// pNextLevelRVA - out - The RVA for the next level tree directory or the RVA of the resource entry
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// S_OK if succesful or an appropriate failing HRESULT
|
// S_OK if successful or an appropriate failing HRESULT
|
||||||
HRESULT GetNextLevelResourceEntryRVAByName(ICorDebugDataTarget* pDataTarget,
|
HRESULT GetNextLevelResourceEntryRVAByName(ICorDebugDataTarget* pDataTarget,
|
||||||
LPCWSTR pwzName,
|
LPCWSTR pwzName,
|
||||||
ULONG64 moduleBaseAddress,
|
ULONG64 moduleBaseAddress,
|
||||||
|
|
|
@ -103,7 +103,7 @@ ElfReader::~ElfReader()
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize the ELF reader from a module the base address. This function
|
// Initialize the ELF reader from a module the base address. This function
|
||||||
// caches the info neccessary in the ElfReader class look up symbols.
|
// caches the info necessary in the ElfReader class look up symbols.
|
||||||
//
|
//
|
||||||
bool
|
bool
|
||||||
ElfReader::PopulateForSymbolLookup(uint64_t baseAddress)
|
ElfReader::PopulateForSymbolLookup(uint64_t baseAddress)
|
||||||
|
|
|
@ -180,7 +180,7 @@ IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't expect this to block since this is a Unix Domain Socket. `connect` may block until the
|
// We don't expect this to block since this is a Unix Domain Socket. `connect` may block until the
|
||||||
// TCP handshake is complete for TCP/IP sockets, but UDS don't use TCP. `connect` will return even if
|
// TCP handshake is complete for TCP/IP sockets, but UDS don't use TCP. `connect` will return even if
|
||||||
// the server hasn't called `accept`.
|
// the server hasn't called `accept`.
|
||||||
if (::connect(clientSocket, (struct sockaddr *)_pServerAddress, sizeof(*_pServerAddress)) < 0)
|
if (::connect(clientSocket, (struct sockaddr *)_pServerAddress, sizeof(*_pServerAddress)) < 0)
|
||||||
|
@ -270,7 +270,7 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_
|
||||||
{
|
{
|
||||||
rgIpcPollHandles[i].revents = (uint8_t)PollEvents::UNKNOWN;
|
rgIpcPollHandles[i].revents = (uint8_t)PollEvents::UNKNOWN;
|
||||||
if (callback != nullptr)
|
if (callback != nullptr)
|
||||||
callback("unkown poll response", (uint32_t)pollfds[i].revents);
|
callback("unknown poll response", (uint32_t)pollfds[i].revents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,8 +297,8 @@ void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback callback)
|
||||||
|
|
||||||
// N.B. - it is safe to unlink the unix domain socket file while the server
|
// N.B. - it is safe to unlink the unix domain socket file while the server
|
||||||
// is still alive:
|
// is still alive:
|
||||||
// "The usual UNIX close-behind semantics apply; the socket can be unlinked
|
// "The usual UNIX close-behind semantics apply; the socket can be unlinked
|
||||||
// at any time and will be finally removed from the file system when the last
|
// at any time and will be finally removed from the file system when the last
|
||||||
// reference to it is closed." - unix(7) man page
|
// reference to it is closed." - unix(7) man page
|
||||||
Unlink(callback);
|
Unlink(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ bool TwoWayPipe::Connect(const ProcessDescriptor& pd)
|
||||||
PAL_GetTransportPipeName(m_outPipeName, pd.m_Pid, pd.m_ApplicationGroupId, "in");
|
PAL_GetTransportPipeName(m_outPipeName, pd.m_Pid, pd.m_ApplicationGroupId, "in");
|
||||||
|
|
||||||
// Pipe opening order is reversed compared to WaitForConnection()
|
// Pipe opening order is reversed compared to WaitForConnection()
|
||||||
// in order to avaid deadlock.
|
// in order to avoid deadlock.
|
||||||
m_outboundPipe = open(m_outPipeName, O_WRONLY);
|
m_outboundPipe = open(m_outPipeName, O_WRONLY);
|
||||||
if (m_outboundPipe == INVALID_PIPE)
|
if (m_outboundPipe == INVALID_PIPE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,7 +99,7 @@ STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
|
||||||
//
|
//
|
||||||
// Public API.
|
// Public API.
|
||||||
// Creation path with Mac sandbox support and explicit DAC module path for single-file apps
|
// Creation path with Mac sandbox support and explicit DAC module path for single-file apps
|
||||||
// This supercedes code:CoreCLRCreateCordbObjectEx
|
// This supersedes code:CoreCLRCreateCordbObjectEx
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
||||||
|
@ -153,7 +153,7 @@ STDAPI DLLEXPORT CoreCLRCreateCordbObject3(int iDebuggerVersion, DWORD pid, LPCW
|
||||||
//
|
//
|
||||||
// Public API.
|
// Public API.
|
||||||
// Creation path with Mac sandbox support - only way to debug a sandboxed application on Mac.
|
// Creation path with Mac sandbox support - only way to debug a sandboxed application on Mac.
|
||||||
// This supercedes code:CoreCLRCreateCordbObject
|
// This supersedes code:CoreCLRCreateCordbObject
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
||||||
|
@ -175,7 +175,7 @@ STDAPI DLLEXPORT CoreCLRCreateCordbObjectEx(int iDebuggerVersion, DWORD pid, LPC
|
||||||
//
|
//
|
||||||
// Public API.
|
// Public API.
|
||||||
// Creation path - only way to debug multi-instance.
|
// Creation path - only way to debug multi-instance.
|
||||||
// This supercedes code:CreateCordbObject
|
// This supersedes code:CreateCordbObject
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
|
||||||
|
|
|
@ -1052,7 +1052,7 @@ HRESULT CordbReferenceValue::Dereference(ICorDebugValue **ppValue)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Common helper to dereferefence.
|
// Common helper to dereferefence.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// pAppDomain, pType, pInfo - necessary paramters to create the value
|
// pAppDomain, pType, pInfo - necessary parameters to create the value
|
||||||
// pRealTypeOfTypedByref - type for a potential TypedByRef. Can be NULL if we know
|
// pRealTypeOfTypedByref - type for a potential TypedByRef. Can be NULL if we know
|
||||||
// that we're not a typed-byref (this is true if we're definitely an object handle)
|
// that we're not a typed-byref (this is true if we're definitely an object handle)
|
||||||
// ppValue - outparameter for newly created value. This will get an Ext AddRef.
|
// ppValue - outparameter for newly created value. This will get an Ext AddRef.
|
||||||
|
|
|
@ -51,7 +51,7 @@ void EventRedirectionPipeline::Delete()
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Notes:
|
// Notes:
|
||||||
// This will spin up an auxillary debugger (windbg) and attach it to the existing
|
// This will spin up an auxiliary debugger (windbg) and attach it to the existing
|
||||||
// process. If this is a create case, then we're attaching to a create-suspended process.
|
// process. If this is a create case, then we're attaching to a create-suspended process.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
|
@ -86,7 +86,7 @@ BOOL EventRedirectionPipeline::DebugSetProcessKillOnExit(bool fKillOnExit)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Notes:
|
// Notes:
|
||||||
// This will spin up an auxillary debugger (windbg) and attach it to the existing
|
// This will spin up an auxiliary debugger (windbg) and attach it to the existing
|
||||||
// process. If this is a create case, then we're attaching to a create-suspended process.
|
// process. If this is a create case, then we're attaching to a create-suspended process.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -117,7 +117,7 @@ protected:
|
||||||
|
|
||||||
// Command parameters for create case.
|
// Command parameters for create case.
|
||||||
// Note that we must always physically call CreateProcess on the debuggee so that we get the proper out-parameters
|
// Note that we must always physically call CreateProcess on the debuggee so that we get the proper out-parameters
|
||||||
// from create-process (eg, target's handle, startup info, etc). So we always attach the auxillary debugger
|
// from create-process (eg, target's handle, startup info, etc). So we always attach the auxiliary debugger
|
||||||
// even in the create case. Use "-pr -pb" in Windbg to attach to a create-suspended process.
|
// even in the create case. Use "-pr -pb" in Windbg to attach to a create-suspended process.
|
||||||
//
|
//
|
||||||
// Common Windbg options:
|
// Common Windbg options:
|
||||||
|
|
|
@ -483,7 +483,7 @@ void CordbModule::RefreshMetaData()
|
||||||
|
|
||||||
// There are several different ways we can get the metadata
|
// There are several different ways we can get the metadata
|
||||||
// 1) [Most common] Module is loaded into VM and never changed. The importer
|
// 1) [Most common] Module is loaded into VM and never changed. The importer
|
||||||
// will be constructed refering to the file on disk. This is a significant
|
// will be constructed referring to the file on disk. This is a significant
|
||||||
// working set win because the VM and debugger share the image. If there is
|
// working set win because the VM and debugger share the image. If there is
|
||||||
// an error reading by file we can fall back to case #2 for these modules
|
// an error reading by file we can fall back to case #2 for these modules
|
||||||
// 2) Most modules have a buffer in target memory that represents their
|
// 2) Most modules have a buffer in target memory that represents their
|
||||||
|
|
|
@ -1224,7 +1224,7 @@ HRESULT ShimProcess::DebugActiveProcess(
|
||||||
// bit indicating managed attach is coming.
|
// bit indicating managed attach is coming.
|
||||||
// However in interop debugging we can't do that because there are debug events which come before the
|
// However in interop debugging we can't do that because there are debug events which come before the
|
||||||
// loader breakpoint (which is how far we need to get to set the debuggee bit). If we blocked
|
// loader breakpoint (which is how far we need to get to set the debuggee bit). If we blocked
|
||||||
// DebugActiveProcess there then the debug events would be refering to an ICorDebugProcess that hasn't
|
// DebugActiveProcess there then the debug events would be referring to an ICorDebugProcess that hasn't
|
||||||
// yet been returned to the caller of DebugActiveProcess. Instead, for interop debugging we force the
|
// yet been returned to the caller of DebugActiveProcess. Instead, for interop debugging we force the
|
||||||
// native debugger to wait until it gets the loader breakpoint to set the event. Note we can't converge
|
// native debugger to wait until it gets the loader breakpoint to set the event. Note we can't converge
|
||||||
// on that solution for the pure managed case because there is no loader breakpoint event. Hence pure
|
// on that solution for the pure managed case because there is no loader breakpoint event. Hence pure
|
||||||
|
@ -1470,7 +1470,7 @@ void CordbProcess::CloseIPCHandles()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Create new OS Thread for the Win32 Event Thread (the thread used in interop-debugging to sniff
|
// Create new OS Thread for the Win32 Event Thread (the thread used in interop-debugging to sniff
|
||||||
// native debug events). This is 1:1 w/ a CordbProcess object.
|
// native debug events). This is 1:1 w/ a CordbProcess object.
|
||||||
// This will then be used to actuall create the CordbProcess object.
|
// This will then be used to actually create the CordbProcess object.
|
||||||
// The process object will then take ownership of the thread.
|
// The process object will then take ownership of the thread.
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -2005,7 +2005,7 @@ void SendAttachProcessWorkItem::Do()
|
||||||
|
|
||||||
// This just acts like an async-break, which will kick off things.
|
// This just acts like an async-break, which will kick off things.
|
||||||
// This will not induce any faked attach events from the VM (like it did in V2).
|
// This will not induce any faked attach events from the VM (like it did in V2).
|
||||||
// The Left-side will still slip foward allowing the async-break to happen, so
|
// The Left-side will still slip forward allowing the async-break to happen, so
|
||||||
// we may get normal debug events in addition to the sync-complete.
|
// we may get normal debug events in addition to the sync-complete.
|
||||||
//
|
//
|
||||||
// 1. In the common attach case, we should just get a sync-complete.
|
// 1. In the common attach case, we should just get a sync-complete.
|
||||||
|
@ -2963,7 +2963,7 @@ void CordbProcess::FlushAll()
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// S_OK on successful detach. Else errror.
|
// S_OK on successful detach. Else error.
|
||||||
//
|
//
|
||||||
// Assumptions:
|
// Assumptions:
|
||||||
// Target is stopped.
|
// Target is stopped.
|
||||||
|
@ -5499,7 +5499,7 @@ void CordbProcess::RawDispatchEvent(
|
||||||
("AppDomain changed from Func-Eval. Eval=%p, Started=%p, Now=%p\n",
|
("AppDomain changed from Func-Eval. Eval=%p, Started=%p, Now=%p\n",
|
||||||
pEval, pEval->m_DbgAppDomainStarted, (void*) pAppDomain));
|
pEval, pEval->m_DbgAppDomainStarted, (void*) pAppDomain));
|
||||||
|
|
||||||
// If we did this func eval with this thread stopped at an excpetion, then we need to pretend as if we
|
// If we did this func eval with this thread stopped at an exception, then we need to pretend as if we
|
||||||
// really didn't continue from the exception, since, of course, we really didn't on the Left Side.
|
// really didn't continue from the exception, since, of course, we really didn't on the Left Side.
|
||||||
if (pEval->IsEvalDuringException())
|
if (pEval->IsEvalDuringException())
|
||||||
{
|
{
|
||||||
|
@ -10485,7 +10485,7 @@ void CordbRCEventThread::ThreadProc()
|
||||||
// Only listen to unsynchronized processes. Processes that are synchronized will not send events without
|
// Only listen to unsynchronized processes. Processes that are synchronized will not send events without
|
||||||
// being asked by us first, so there is no need to async listen to them.
|
// being asked by us first, so there is no need to async listen to them.
|
||||||
//
|
//
|
||||||
// Note: if a process is not synchronized then there is no way for it to transition to the syncrhonized
|
// Note: if a process is not synchronized then there is no way for it to transition to the synchronized
|
||||||
// state without this thread receiving an event and taking action. So there is no need to lock the
|
// state without this thread receiving an event and taking action. So there is no need to lock the
|
||||||
// per-process mutex when checking the process's synchronized flag here.
|
// per-process mutex when checking the process's synchronized flag here.
|
||||||
if (!pProcess->GetSynchronized() && pProcess->IsSafeToSendEvents())
|
if (!pProcess->GetSynchronized() && pProcess->IsSafeToSendEvents())
|
||||||
|
@ -11277,7 +11277,7 @@ HRESULT CordbProcess::SetEnableCustomNotification(ICorDebugClass * pClass, BOOL
|
||||||
// pRawRecord - non-null raw bytes of the exception
|
// pRawRecord - non-null raw bytes of the exception
|
||||||
// countBytes - number of bytes in pRawRecord buffer.
|
// countBytes - number of bytes in pRawRecord buffer.
|
||||||
// format - format of pRawRecord
|
// format - format of pRawRecord
|
||||||
// dwFlags - flags providing auxillary info for exception record.
|
// dwFlags - flags providing auxiliary info for exception record.
|
||||||
// dwThreadId - thread that exception occurred on.
|
// dwThreadId - thread that exception occurred on.
|
||||||
// pCallback - callback to dispatch potential managed events on.
|
// pCallback - callback to dispatch potential managed events on.
|
||||||
// pContinueStatus - Continuation status for exception. This dictates what
|
// pContinueStatus - Continuation status for exception. This dictates what
|
||||||
|
@ -12350,7 +12350,7 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman
|
||||||
|
|
||||||
// These breakpoint and single step exceptions have to be dispatched to the debugger as
|
// These breakpoint and single step exceptions have to be dispatched to the debugger as
|
||||||
// out-of-band events. This tells the debugger that they must continue from these events
|
// out-of-band events. This tells the debugger that they must continue from these events
|
||||||
// immediatly, and that no interaction with the Left Side is allowed until they do so. This
|
// immediately, and that no interaction with the Left Side is allowed until they do so. This
|
||||||
// makes sense, since these events are on the helper thread.
|
// makes sense, since these events are on the helper thread.
|
||||||
return REACTION(cOOB);
|
return REACTION(cOOB);
|
||||||
}
|
}
|
||||||
|
@ -12565,7 +12565,7 @@ Reaction CordbProcess::TriageWin32DebugEvent(CordbUnmanagedThread * pUnmanagedTh
|
||||||
_ASSERTE(ThreadHoldsProcessLock());
|
_ASSERTE(ThreadHoldsProcessLock());
|
||||||
|
|
||||||
// Lots of special cases for exception events. The vast majority of hybrid debugging work that takes
|
// Lots of special cases for exception events. The vast majority of hybrid debugging work that takes
|
||||||
// place is in response to exception events. The work below will consider certian exception events
|
// place is in response to exception events. The work below will consider certain exception events
|
||||||
// special cases and rather than letting them be queued and dispatched, they will be handled right
|
// special cases and rather than letting them be queued and dispatched, they will be handled right
|
||||||
// here.
|
// here.
|
||||||
if (pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
|
if (pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
|
||||||
|
@ -12658,7 +12658,7 @@ Reaction CordbProcess::TriageWin32DebugEvent(CordbUnmanagedThread * pUnmanagedTh
|
||||||
// The process just got a native debug event via WaitForDebugEvent
|
// The process just got a native debug event via WaitForDebugEvent
|
||||||
//
|
//
|
||||||
// Notes:
|
// Notes:
|
||||||
// The function will Triage the excpetion and then handle it based on the
|
// The function will Triage the exception and then handle it based on the
|
||||||
// appropriate reaction (see: code:Reaction).
|
// appropriate reaction (see: code:Reaction).
|
||||||
//
|
//
|
||||||
// @dbgtodo interop: this should all go into the shim.
|
// @dbgtodo interop: this should all go into the shim.
|
||||||
|
@ -13754,7 +13754,7 @@ void CordbWin32EventThread::CreateProcess()
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// Process ID is filled in after process is succesfully created.
|
// Process ID is filled in after process is successfully created.
|
||||||
DWORD dwProcessId = m_actionData.createData.lpProcessInformation->dwProcessId;
|
DWORD dwProcessId = m_actionData.createData.lpProcessInformation->dwProcessId;
|
||||||
ProcessDescriptor pd = ProcessDescriptor::FromPid(dwProcessId);
|
ProcessDescriptor pd = ProcessDescriptor::FromPid(dwProcessId);
|
||||||
|
|
||||||
|
@ -14365,7 +14365,7 @@ void ExitProcessWorkItem::Do()
|
||||||
GetProcess()->IncStopCount();
|
GetProcess()->IncStopCount();
|
||||||
|
|
||||||
// By the time we release the SG + Process locks here, the process object has been
|
// By the time we release the SG + Process locks here, the process object has been
|
||||||
// marked as exiting + terminated (by the w32et which queued us). Future attemps to
|
// marked as exiting + terminated (by the w32et which queued us). Future attempts to
|
||||||
// continue should fail, and thus we should remain synchronized.
|
// continue should fail, and thus we should remain synchronized.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14788,8 +14788,8 @@ LONG CordbProcess::OutstandingHandles()
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Increment the outstanding handle count for code:CordbProces::OutstandingHandles
|
// Increment the outstanding handle count for code:CordbProcess::OutstandingHandles
|
||||||
// This is the inverse of code:CordbProces::DecrementOutstandingHandles
|
// This is the inverse of code:CordbProcess::DecrementOutstandingHandles
|
||||||
void CordbProcess::IncrementOutstandingHandles()
|
void CordbProcess::IncrementOutstandingHandles()
|
||||||
{
|
{
|
||||||
_ASSERTE(ThreadHoldsProcessLock());
|
_ASSERTE(ThreadHoldsProcessLock());
|
||||||
|
@ -14797,8 +14797,8 @@ void CordbProcess::IncrementOutstandingHandles()
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Decrement the outstanding handle count for code:CordbProces::OutstandingHandles
|
// Decrement the outstanding handle count for code:CordbProcess::OutstandingHandles
|
||||||
// This is the inverse of code:CordbProces::IncrementOutstandingHandles
|
// This is the inverse of code:CordbProcess::IncrementOutstandingHandles
|
||||||
void CordbProcess::DecrementOutstandingHandles()
|
void CordbProcess::DecrementOutstandingHandles()
|
||||||
{
|
{
|
||||||
_ASSERTE(ThreadHoldsProcessLock());
|
_ASSERTE(ThreadHoldsProcessLock());
|
||||||
|
|
|
@ -277,7 +277,7 @@ HRESULT CordbAppDomain::EnumerateThreads(ICorDebugThreadEnum **ppThreads)
|
||||||
RSInitHolder<CordbHashTableEnum> pEnum;
|
RSInitHolder<CordbHashTableEnum> pEnum;
|
||||||
GetProcess()->BuildThreadEnum(this, NULL, pEnum.GetAddr());
|
GetProcess()->BuildThreadEnum(this, NULL, pEnum.GetAddr());
|
||||||
|
|
||||||
// This builds up auxillary list. don't need pEnum after this.
|
// This builds up auxiliary list. don't need pEnum after this.
|
||||||
hr = pThreadEnum->Init(pEnum, this);
|
hr = pThreadEnum->Init(pEnum, this);
|
||||||
IfFailThrow(hr);
|
IfFailThrow(hr);
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ HRESULT CordbAssembly::EnumerateModules(ICorDebugModuleEnum **ppModules)
|
||||||
IID_ICorDebugModuleEnum,
|
IID_ICorDebugModuleEnum,
|
||||||
pEnum.GetAddr());
|
pEnum.GetAddr());
|
||||||
|
|
||||||
// this will build up an auxillary list. Don't need pEnum after this.
|
// this will build up an auxiliary list. Don't need pEnum after this.
|
||||||
hr = pModEnum->Init(pEnum, this);
|
hr = pModEnum->Init(pEnum, this);
|
||||||
IfFailThrow(hr);
|
IfFailThrow(hr);
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ HRESULT CordbClass::GetStaticFieldValue2(CordbModule * pModule,
|
||||||
|
|
||||||
// Static value classes are stored as handles so that GC can deal with them properly. Thus, we need to follow the
|
// Static value classes are stored as handles so that GC can deal with them properly. Thus, we need to follow the
|
||||||
// handle like an objectref. Do this by forcing CreateValueByType to think this is an objectref. Note: we don't do
|
// handle like an objectref. Do this by forcing CreateValueByType to think this is an objectref. Note: we don't do
|
||||||
// this for value classes that have an RVA, since they're layed out at the RVA with no handle.
|
// this for value classes that have an RVA, since they're laid out at the RVA with no handle.
|
||||||
bool fIsBoxed = (fIsValueClass &&
|
bool fIsBoxed = (fIsValueClass &&
|
||||||
!pFieldData->m_fFldIsRVA &&
|
!pFieldData->m_fFldIsRVA &&
|
||||||
!pFieldData->m_fFldIsPrimitive &&
|
!pFieldData->m_fFldIsPrimitive &&
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
// This CordbEnumerator is a templated enumerator from which COM enumerators for RS types can quickly be fashioned.
|
// This CordbEnumerator is a templated enumerator from which COM enumerators for RS types can quickly be fashioned.
|
||||||
// It uses a private array to store the items it enumerates over so by default it does not reference any
|
// It uses a private array to store the items it enumerates over so by default it does not reference any
|
||||||
// other RS type except the process it is associated with. The internal storage type does not need to match the
|
// other RS type except the process it is associated with. The internal storage type does not need to match the
|
||||||
// the item type exposed publically so that you can easily create an enumeration that holds RsSmartPtr<CordbThread>
|
// the item type exposed publicly so that you can easily create an enumeration that holds RsSmartPtr<CordbThread>
|
||||||
// but enumerates ICorDebugThread objects as an example. The enumerator has 4 templated parameters which must be
|
// but enumerates ICorDebugThread objects as an example. The enumerator has 4 templated parameters which must be
|
||||||
// defined:
|
// defined:
|
||||||
// ElemType: this is the item type used for storage internal to the enumerator. For most Rs objects you will want
|
// ElemType: this is the item type used for storage internal to the enumerator. For most Rs objects you will want
|
||||||
// to use an RsSmartPtr<T> type to ensure the enumerator holds references to the objects it is
|
// to use an RsSmartPtr<T> type to ensure the enumerator holds references to the objects it is
|
||||||
// containing. The enumerator does not do any explicit Add/Release, it just copies items.
|
// containing. The enumerator does not do any explicit Add/Release, it just copies items.
|
||||||
// ElemPublicType: this is the item type exposed publically via the Next enumeration method. Typically this is
|
// ElemPublicType: this is the item type exposed publicly via the Next enumeration method. Typically this is
|
||||||
// an ICorDebugX interface type but it can be anything.
|
// an ICorDebugX interface type but it can be anything.
|
||||||
// EnumInterfaceType: this is the COM interface that the instantiated template will implement. It is expected that
|
// EnumInterfaceType: this is the COM interface that the instantiated template will implement. It is expected that
|
||||||
// this interface type follows the standard ICorDebug COM enumerator pattern, that the interface inherits
|
// this interface type follows the standard ICorDebug COM enumerator pattern, that the interface inherits
|
||||||
|
@ -195,7 +195,7 @@ ULONG CordbEnumerator<ElemType,
|
||||||
// ppEnum - on output filled with a duplicate enumeration
|
// ppEnum - on output filled with a duplicate enumeration
|
||||||
//
|
//
|
||||||
// Return:
|
// Return:
|
||||||
// S_OK if the clone was created succesfully, otherwise some appropriate failing HRESULT
|
// S_OK if the clone was created successfully, otherwise some appropriate failing HRESULT
|
||||||
template< typename ElemType,
|
template< typename ElemType,
|
||||||
typename ElemPublicType,
|
typename ElemPublicType,
|
||||||
typename EnumInterfaceType, REFIID IID_EnumInterfaceType,
|
typename EnumInterfaceType, REFIID IID_EnumInterfaceType,
|
||||||
|
|
|
@ -295,7 +295,7 @@ HRESULT CordbFunction::GetILCode(ICorDebugCode ** ppCode)
|
||||||
// Use EnumerateNativeCode instead in that case.
|
// Use EnumerateNativeCode instead in that case.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// ppCode - out parameter yeilding the native code object.
|
// ppCode - out parameter yielding the native code object.
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// S_OK iff *ppCode is set.
|
// S_OK iff *ppCode is set.
|
||||||
|
@ -1169,10 +1169,10 @@ HRESULT CordbFunction::GetArgumentType(DWORD dwIndex,
|
||||||
// that they will return when asked for native code. The 1:1 mapping between
|
// that they will return when asked for native code. The 1:1 mapping between
|
||||||
// function and code was invalidated by generics but debuggers continue to use
|
// function and code was invalidated by generics but debuggers continue to use
|
||||||
// the old API. When they do we need to have some code to hand them back even
|
// the old API. When they do we need to have some code to hand them back even
|
||||||
// though it is an arbitrary instantiation. Note that the cannonical code
|
// though it is an arbitrary instantiation. Note that the canonical code
|
||||||
// here is merely the first one that a user inspects... it is not guaranteed to
|
// here is merely the first one that a user inspects... it is not guaranteed to
|
||||||
// be the same in each debugging session but once set it will never change. It is
|
// be the same in each debugging session but once set it will never change. It is
|
||||||
// also definately NOT guaranteed to be the instantation over the runtime type
|
// also definately NOT guaranteed to be the instantiation over the runtime type
|
||||||
// __Canon.
|
// __Canon.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
|
|
|
@ -3957,7 +3957,7 @@ public:
|
||||||
|
|
||||||
// The array of entries. (The patchtable is a hash implemented as a single-array)
|
// The array of entries. (The patchtable is a hash implemented as a single-array)
|
||||||
// This array includes empty entries.
|
// This array includes empty entries.
|
||||||
// There is an auxillary bucket structure used to map hash codes to array indices.
|
// There is an auxiliary bucket structure used to map hash codes to array indices.
|
||||||
// We traverse the array, and we recognize an empty slot
|
// We traverse the array, and we recognize an empty slot
|
||||||
// if DebuggerControllerPatch::opcode == 0.
|
// if DebuggerControllerPatch::opcode == 0.
|
||||||
// If we haven't gotten the table, then m_pPatchTable is NULL
|
// If we haven't gotten the table, then m_pPatchTable is NULL
|
||||||
|
@ -4696,7 +4696,7 @@ public:
|
||||||
// This lets us reuse the existing hash table scheme to build
|
// This lets us reuse the existing hash table scheme to build
|
||||||
// up instantiated types of arbitrary size.
|
// up instantiated types of arbitrary size.
|
||||||
//
|
//
|
||||||
// Array types are similar, excpet that they start with a head type
|
// Array types are similar, excepet that they start with a head type
|
||||||
// for the "type constructor", e.g. "_ []" is a type constructor with rank 1
|
// for the "type constructor", e.g. "_ []" is a type constructor with rank 1
|
||||||
// and m_elementType = ELEMENT_TYPE_SZARRAY. These head constructors are
|
// and m_elementType = ELEMENT_TYPE_SZARRAY. These head constructors are
|
||||||
// stored in the m_sharedtypes table in the appdomain. The actual instantiations
|
// stored in the m_sharedtypes table in the appdomain. The actual instantiations
|
||||||
|
@ -9891,7 +9891,7 @@ private:
|
||||||
// EE object handle pointer. Can be casted to OBJECTHANDLE when go to LS
|
// EE object handle pointer. Can be casted to OBJECTHANDLE when go to LS
|
||||||
// This instance owns the handle object and must call into the VM to release
|
// This instance owns the handle object and must call into the VM to release
|
||||||
// it.
|
// it.
|
||||||
// If this is non-null, then we increment code:CordbProces::IncrementOutstandingHandles.
|
// If this is non-null, then we increment code:CordbProcess::IncrementOutstandingHandles.
|
||||||
// Once it goes null, we should decrement the count.
|
// Once it goes null, we should decrement the count.
|
||||||
// Use AssignHandle, ClearHandle to keep this in sync.
|
// Use AssignHandle, ClearHandle to keep this in sync.
|
||||||
VMPTR_OBJECTHANDLE m_vmHandle;
|
VMPTR_OBJECTHANDLE m_vmHandle;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue