Skip to content

Instantly share code, notes, and snippets.

View GrabYourPitchforks's full-sized avatar
😵
On other projects, not checking GitHub notifications - ping via Teams if urgent.

Levi Broderick GrabYourPitchforks

😵
On other projects, not checking GitHub notifications - ping via Teams if urgent.
View GitHub Profile
@GrabYourPitchforks
GrabYourPitchforks / ReflectionServices.cs
Last active October 1, 2017 00:59
ReflectionServices proposal
using System;
using System.Security;
namespace System.Reflection
{
public delegate ref TField FieldAccessor<TField>(object target);
public delegate ref TField FieldAccessor<TTarget, TField>(ref TTarget target);
/// <summary>
// Input: a 32-bit integer of the form [ 00wwwwww 00xxxxxx 00yyyyyy 00zzzzzz ]
// Output: a 32-bit integer where each input byte is mapped to its corresponding BASE64 ASCII byte
private static uint ByteToBase64(uint b)
{
b += 0x41414141U; // 'A'
return b
+ (0x06U * (((b + 0x25252525U) & 0x80808080U) >> 7))
- (0x4BU * (((b + 0x0B0B0B0BU) & 0x80808080U) >> 7))
- (0x0FU * (((b + 0x01010101U) & 0x80808080U) >> 7))
+ (0x03U * ((b & 0x80808080U) >> 7));
; System_Private_CoreLib!System.Buffer.Memmove(Byte*, Byte*, UInt64):
00007ff8`1f759440 0f1f440000 nop dword ptr [rax+rax]
00007ff8`1f759445 488bc1 mov rax,rcx
00007ff8`1f759448 482bc2 sub rax,rdx
00007ff8`1f75944b 493bc0 cmp rax,r8
00007ff8`1f75944e 0f822f010000 jb System_Private_CoreLib!System.Buffer.Memmove(Byte*, Byte*, UInt64)+0x143 (00007ff8`1f759583)
00007ff8`1f759454 488bc2 mov rax,rdx
00007ff8`1f759457 482bc1 sub rax,rcx
00007ff8`1f75945a 493bc0 cmp rax,r8
00007ff8`1f75945d 0f8220010000 jb System_Private_CoreLib!System.Buffer.Memmove(Byte*, Byte*, UInt64)+0x143 (00007ff8`1f759583)
; System_Private_CoreLib!System.Buffer.Memmove(System.ByReference`1<Byte>, System.ByReference`1<Byte>, UInt64):
00007ff8`2c697e30 4883ec28 sub rsp,28h
00007ff8`2c697e34 90 nop
00007ff8`2c697e35 488bc1 mov rax,rcx
00007ff8`2c697e38 482bc2 sub rax,rdx
00007ff8`2c697e3b 493bc0 cmp rax,r8
00007ff8`2c697e3e 0f8233010000 jb System_Private_CoreLib!System.Buffer.Memmove(System.ByReference`1<Byte>, System.ByReference`1<Byte>, UInt64)+0x147 (00007ff8`2c697f77)
00007ff8`2c697e44 488bc2 mov rax,rdx
00007ff8`2c697e47 482bc1 sub rax,rcx
00007ff8`2c697e4a 493bc0 cmp rax,r8
; System_Private_CoreLib!System.Buffer.Memmove(Byte*, Byte*, UInt32):
53c15f10 55 push ebp
53c15f11 8bec mov ebp,esp
53c15f13 57 push edi
53c15f14 56 push esi
53c15f15 53 push ebx
53c15f16 83ec08 sub esp,8
53c15f19 8b4508 mov eax,dword ptr [ebp+8]
53c15f1c 8bf1 mov esi,ecx
53c15f1e 2bf2 sub esi,edx
; System_Private_CoreLib!System.Buffer.Memmove(System.ByReference`1<Byte>, System.ByReference`1<Byte>, UInt32):
53b9caec 55 push ebp
53b9caed 8bec mov ebp,esp
53b9caef 57 push edi
53b9caf0 56 push esi
53b9caf1 53 push ebx
53b9caf2 8b550c mov edx,dword ptr [ebp+0Ch]
53b9caf5 2b5508 sub edx,dword ptr [ebp+8]
53b9caf8 8b4508 mov eax,dword ptr [ebp+8]
53b9cafb 2b450c sub eax,dword ptr [ebp+0Ch]
// 'valueIfTrue' and 'valueIfFalse' really should be compile-time constants for maximum throughput.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int ConditionalSelect(bool condition, int valueIfTrue, int valueIfFalse)
{
// From https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf
// Example 3.2. We're taking advantage of the fact that bools are passed by value as 32-bit integers,
// so we'll blit it directly into a 1 or a 0 without a jump.
// Codegen will emit a movzx, but on Ivy Bridge (and later) the CPU itself elides the instruction.
return ((-Unsafe.As<bool, int>(ref condition)) & (valueIfTrue - valueIfFalse)) + valueIfFalse;
}
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
@GrabYourPitchforks
GrabYourPitchforks / utf8string.md
Created March 23, 2018 20:55
Utf8String design philosophy

Usage, usability, and behaviors

The goal of this project is to make a type that mirrors System.String as much as practical. It should be a heapable, immutable, indexable, and pinnable type. The data may contain embedded null characters. When pinned, the pointer should represent a null-terminated UTF-8 string.

We should provide conversions between String and Utf8String, though due to the expense of conversion we should avoid these operations when possible. There are a few ways to avoid these, including:

  • Adding Utf8String-based overloads to existing APIs like Console.WriteLine, File.WriteAllText, etc.
  • Adding ToUtf8String methods on existing types like Int32.
  • Implement utility classes like Utf8StringBuilder.
  • Not having implicit or explicit conversion operators that could perform expensive transcodings, but instead having constructor overloads or some other obvious "this may be expensive" mechanism.
@GrabYourPitchforks
GrabYourPitchforks / memory_guidelines.md
Last active April 21, 2024 07:45
Memory usage guidelines

Memory<T> usage guidelines

This document describes the relationship between Memory<T> and its related classes (MemoryPool<T>, IMemoryOwner<T>, etc.). It also describes best practices when accepting Memory<T> instances in public API surface. Following these guidelines will help developers write clear, bug-free code.

First, a tour of the basic exchange types

  • Span<T> is the basic exchange type that represents contiguous buffers. These buffers may be backed by managed memory (such as T[] or System.String). They may also be backed by unmanaged memory (such as via stackalloc or a raw void*). The Span<T> type is not heapable, meaning that it cannot appear as a field in classes, and it cannot be used across yield or await boundaries.

  • Memory is a wrapper around an object that can generate a Span. For instance, Memory instances can be backed by T[], System.String (readonly), and even SafeHandle instances. Memory cannot be backed by "transient" unmanaged me