From badb414bfbd3cbc649f5aebe9304df741421c0c0 Mon Sep 17 00:00:00 2001
From: Marko Lahma <marko.lahma@gmail.com>
Date: Sat, 13 Nov 2021 10:54:34 +0200
Subject: [PATCH] Change Mark to be readonly struct

* Add ThrowHelper
---
 YamlDotNet/Core/AnchorNotFoundException.cs    |  2 +-
 YamlDotNet/Core/Events/DocumentStart.cs       |  2 +-
 YamlDotNet/Core/Events/MappingEnd.cs          |  2 +-
 YamlDotNet/Core/Events/ParsingEvent.cs        |  6 +--
 YamlDotNet/Core/Events/SequenceEnd.cs         |  2 +-
 YamlDotNet/Core/Events/StreamEnd.cs           |  2 +-
 YamlDotNet/Core/Events/StreamStart.cs         |  2 +-
 .../ForwardAnchorNotSupportedException.cs     |  2 +-
 YamlDotNet/Core/Mark.cs                       | 37 ++++++-------------
 .../MaximumRecursionLevelReachedException.cs  |  2 +-
 YamlDotNet/Core/Parser.cs                     |  2 +-
 YamlDotNet/Core/Scanner.cs                    | 10 ++---
 YamlDotNet/Core/SemanticErrorException.cs     |  2 +-
 YamlDotNet/Core/SyntaxErrorException.cs       |  2 +-
 YamlDotNet/Core/Tokens/BlockEnd.cs            |  2 +-
 YamlDotNet/Core/Tokens/BlockEntry.cs          |  2 +-
 YamlDotNet/Core/Tokens/BlockMappingStart.cs   |  2 +-
 YamlDotNet/Core/Tokens/BlockSequenceStart.cs  |  2 +-
 YamlDotNet/Core/Tokens/DocumentEnd.cs         |  2 +-
 YamlDotNet/Core/Tokens/DocumentStart.cs       |  2 +-
 YamlDotNet/Core/Tokens/FlowEntry.cs           |  2 +-
 YamlDotNet/Core/Tokens/FlowMappingEnd.cs      |  2 +-
 YamlDotNet/Core/Tokens/FlowMappingStart.cs    |  2 +-
 YamlDotNet/Core/Tokens/FlowSequenceEnd.cs     |  2 +-
 YamlDotNet/Core/Tokens/FlowSequenceStart.cs   |  2 +-
 YamlDotNet/Core/Tokens/Key.cs                 |  2 +-
 YamlDotNet/Core/Tokens/StreamEnd.cs           |  2 +-
 YamlDotNet/Core/Tokens/StreamStart.cs         |  2 +-
 YamlDotNet/Core/Tokens/Token.cs               |  8 ++--
 YamlDotNet/Core/Tokens/Value.cs               |  2 +-
 YamlDotNet/Core/YamlException.cs              |  4 +-
 YamlDotNet/Helpers/ThrowHelper.cs             | 35 ++++++++++++++++++
 32 files changed, 85 insertions(+), 67 deletions(-)
 create mode 100644 YamlDotNet/Helpers/ThrowHelper.cs

diff --git a/YamlDotNet/Core/AnchorNotFoundException.cs b/YamlDotNet/Core/AnchorNotFoundException.cs
index 187b603a1..d9218f7ef 100644
--- a/YamlDotNet/Core/AnchorNotFoundException.cs
+++ b/YamlDotNet/Core/AnchorNotFoundException.cs
@@ -40,7 +40,7 @@ public AnchorNotFoundException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="AnchorNotFoundException"/> class.
         /// </summary>
-        public AnchorNotFoundException(Mark start, Mark end, string message)
+        public AnchorNotFoundException(in Mark start, in Mark end, string message)
             : base(start, end, message)
         {
         }
diff --git a/YamlDotNet/Core/Events/DocumentStart.cs b/YamlDotNet/Core/Events/DocumentStart.cs
index 82cd21d1a..8725eeb06 100644
--- a/YamlDotNet/Core/Events/DocumentStart.cs
+++ b/YamlDotNet/Core/Events/DocumentStart.cs
@@ -92,7 +92,7 @@ public DocumentStart(VersionDirective? version, TagDirectiveCollection? tags, bo
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        public DocumentStart(Mark start, Mark end)
+        public DocumentStart(in Mark start, in Mark end)
             : this(null, null, true, start, end)
         {
         }
diff --git a/YamlDotNet/Core/Events/MappingEnd.cs b/YamlDotNet/Core/Events/MappingEnd.cs
index 8194ad114..8f083437a 100644
--- a/YamlDotNet/Core/Events/MappingEnd.cs
+++ b/YamlDotNet/Core/Events/MappingEnd.cs
@@ -43,7 +43,7 @@ public class MappingEnd : ParsingEvent
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        public MappingEnd(Mark start, Mark end)
+        public MappingEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Events/ParsingEvent.cs b/YamlDotNet/Core/Events/ParsingEvent.cs
index 6ec573076..ba6a3172e 100644
--- a/YamlDotNet/Core/Events/ParsingEvent.cs
+++ b/YamlDotNet/Core/Events/ParsingEvent.cs
@@ -59,10 +59,10 @@ public abstract class ParsingEvent
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        internal ParsingEvent(Mark start, Mark end)
+        internal ParsingEvent(in Mark start, in Mark end)
         {
-            this.Start = start ?? throw new System.ArgumentNullException(nameof(start));
-            this.End = end ?? throw new System.ArgumentNullException(nameof(end));
+            this.Start = start;
+            this.End = end;
         }
     }
 }
diff --git a/YamlDotNet/Core/Events/SequenceEnd.cs b/YamlDotNet/Core/Events/SequenceEnd.cs
index 63a0ef41c..217d21170 100644
--- a/YamlDotNet/Core/Events/SequenceEnd.cs
+++ b/YamlDotNet/Core/Events/SequenceEnd.cs
@@ -43,7 +43,7 @@ public sealed class SequenceEnd : ParsingEvent
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        public SequenceEnd(Mark start, Mark end)
+        public SequenceEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Events/StreamEnd.cs b/YamlDotNet/Core/Events/StreamEnd.cs
index 66b79281d..296da6fef 100644
--- a/YamlDotNet/Core/Events/StreamEnd.cs
+++ b/YamlDotNet/Core/Events/StreamEnd.cs
@@ -55,7 +55,7 @@ internal override EventType Type
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        public StreamEnd(Mark start, Mark end)
+        public StreamEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Events/StreamStart.cs b/YamlDotNet/Core/Events/StreamStart.cs
index 552020050..e2f7c7b76 100644
--- a/YamlDotNet/Core/Events/StreamStart.cs
+++ b/YamlDotNet/Core/Events/StreamStart.cs
@@ -63,7 +63,7 @@ public StreamStart()
         /// </summary>
         /// <param name="start">The start position of the event.</param>
         /// <param name="end">The end position of the event.</param>
-        public StreamStart(Mark start, Mark end)
+        public StreamStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs b/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs
index 0ddcbc4f5..ed1078317 100644
--- a/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs
+++ b/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs
@@ -41,7 +41,7 @@ public ForwardAnchorNotSupportedException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="AnchorNotFoundException"/> class.
         /// </summary>
-        public ForwardAnchorNotSupportedException(Mark start, Mark end, string message)
+        public ForwardAnchorNotSupportedException(in Mark start, in Mark end, string message)
             : base(start, end, message)
         {
         }
diff --git a/YamlDotNet/Core/Mark.cs b/YamlDotNet/Core/Mark.cs
index ac038adfa..e9b6a61fd 100644
--- a/YamlDotNet/Core/Mark.cs
+++ b/YamlDotNet/Core/Mark.cs
@@ -20,18 +20,19 @@
 // SOFTWARE.
 
 using System;
+using YamlDotNet.Helpers;
 
 namespace YamlDotNet.Core
 {
     /// <summary>
     /// Represents a location inside a file
     /// </summary>
-    public sealed class Mark : IEquatable<Mark>, IComparable<Mark>, IComparable
+    public readonly struct Mark : IEquatable<Mark>, IComparable<Mark>, IComparable
     {
         /// <summary>
         /// Gets a <see cref="Mark"/> with empty values.
         /// </summary>
-        public static readonly Mark Empty = new Mark();
+        public static readonly Mark Empty = new Mark(0, 1, 1);
 
         /// <summary>
         /// Gets / sets the absolute offset in the file
@@ -48,25 +49,19 @@ public sealed class Mark : IEquatable<Mark>, IComparable<Mark>, IComparable
         /// </summary>
         public int Column { get; }
 
-        public Mark()
-        {
-            Line = 1;
-            Column = 1;
-        }
-
         public Mark(int index, int line, int column)
         {
             if (index < 0)
             {
-                throw new ArgumentOutOfRangeException(nameof(index), "Index must be greater than or equal to zero.");
+                ThrowHelper.ThrowArgumentOutOfRangeException(nameof(index), "Index must be greater than or equal to zero.");
             }
             if (line < 1)
             {
-                throw new ArgumentOutOfRangeException(nameof(line), "Line must be greater than or equal to 1.");
+                ThrowHelper.ThrowArgumentOutOfRangeException(nameof(line), "Line must be greater than or equal to 1.");
             }
             if (column < 1)
             {
-                throw new ArgumentOutOfRangeException(nameof(column), "Column must be greater than or equal to 1.");
+                ThrowHelper.ThrowArgumentOutOfRangeException(nameof(column), "Column must be greater than or equal to 1.");
             }
 
             Index = index;
@@ -88,14 +83,13 @@ public override string ToString()
         /// <summary />
         public override bool Equals(object? obj)
         {
-            return Equals(obj as Mark);
+            return Equals((Mark)(obj ?? Empty));
         }
 
         /// <summary />
-        public bool Equals(Mark? other)
+        public bool Equals(Mark other)
         {
-            return other != null
-                && Index == other.Index
+            return Index == other.Index
                 && Line == other.Line
                 && Column == other.Column;
         }
@@ -115,21 +109,12 @@ public override int GetHashCode()
         /// <summary />
         public int CompareTo(object? obj)
         {
-            if (obj == null)
-            {
-                throw new ArgumentNullException(nameof(obj));
-            }
-            return CompareTo(obj as Mark);
+            return CompareTo((Mark)(obj ?? Empty));
         }
 
         /// <summary />
-        public int CompareTo(Mark? other)
+        public int CompareTo(Mark other)
         {
-            if (other == null)
-            {
-                throw new ArgumentNullException(nameof(other));
-            }
-
             var cmp = Line.CompareTo(other.Line);
             if (cmp == 0)
             {
diff --git a/YamlDotNet/Core/MaximumRecursionLevelReachedException.cs b/YamlDotNet/Core/MaximumRecursionLevelReachedException.cs
index 1a28acf01..7287b8dfa 100644
--- a/YamlDotNet/Core/MaximumRecursionLevelReachedException.cs
+++ b/YamlDotNet/Core/MaximumRecursionLevelReachedException.cs
@@ -40,7 +40,7 @@ public MaximumRecursionLevelReachedException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="MaximumRecursionLevelReachedException"/> class.
         /// </summary>
-        public MaximumRecursionLevelReachedException(Mark start, Mark end, string message)
+        public MaximumRecursionLevelReachedException(in Mark start, in Mark end, string message)
             : base(start, end, message)
         {
         }
diff --git a/YamlDotNet/Core/Parser.cs b/YamlDotNet/Core/Parser.cs
index 59742ad6c..d3b812f0f 100644
--- a/YamlDotNet/Core/Parser.cs
+++ b/YamlDotNet/Core/Parser.cs
@@ -419,7 +419,7 @@ private ParsingEvent ParseDocumentContent()
         /// <summary>
         /// Generate an empty scalar event.
         /// </summary>
-        private static ParsingEvent ProcessEmptyScalar(Mark position)
+        private static ParsingEvent ProcessEmptyScalar(in Mark position)
         {
             return new Events.Scalar(AnchorName.Empty, TagName.Empty, string.Empty, ScalarStyle.Plain, true, false, position, position);
         }
diff --git a/YamlDotNet/Core/Scanner.cs b/YamlDotNet/Core/Scanner.cs
index 55304be5b..754948ad3 100644
--- a/YamlDotNet/Core/Scanner.cs
+++ b/YamlDotNet/Core/Scanner.cs
@@ -2207,7 +2207,7 @@ private void RemoveSimpleKey()
         ///      %TAG    !yaml!  tag:yaml.org,2002:  \n
         ///       ^^^
         /// </summary>
-        private string ScanDirectiveName(Mark start)
+        private string ScanDirectiveName(in Mark start)
         {
             var name = new StringBuilder();
 
@@ -2252,7 +2252,7 @@ private void SkipWhitespaces()
         ///      %YAML   1.1     # a comment \n
         ///           ^^^^^^
         /// </summary>
-        private Token ScanVersionDirectiveValue(Mark start)
+        private Token ScanVersionDirectiveValue(in Mark start)
         {
             SkipWhitespaces();
 
@@ -2283,7 +2283,7 @@ private Token ScanVersionDirectiveValue(Mark start)
         ///      %TAG    !yaml!  tag:yaml.org,2002:  \n
         ///          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         /// </summary>
-        private Token ScanTagDirectiveValue(Mark start)
+        private Token ScanTagDirectiveValue(in Mark start)
         {
             SkipWhitespaces();
 
@@ -2371,7 +2371,7 @@ private string ScanTagUri(string? head, Mark start)
         /// Decode an URI-escape sequence corresponding to a single UTF-8 character.
         /// </summary>
 
-        private string ScanUriEscapes(Mark start)
+        private string ScanUriEscapes(in Mark start)
         {
             // Decode the required number of characters.
 
@@ -2495,7 +2495,7 @@ private string ScanTagHandle(bool isDirective, Mark start)
         ///      %YAML   1.1     # a comment \n
         ///                ^
         /// </summary>
-        private int ScanVersionDirectiveNumber(Mark start)
+        private int ScanVersionDirectiveNumber(in Mark start)
         {
             var value = 0;
             var length = 0;
diff --git a/YamlDotNet/Core/SemanticErrorException.cs b/YamlDotNet/Core/SemanticErrorException.cs
index 39e868332..5209cc867 100644
--- a/YamlDotNet/Core/SemanticErrorException.cs
+++ b/YamlDotNet/Core/SemanticErrorException.cs
@@ -40,7 +40,7 @@ public SemanticErrorException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="SemanticErrorException"/> class.
         /// </summary>
-        public SemanticErrorException(Mark start, Mark end, string message)
+        public SemanticErrorException(in Mark start, in Mark end, string message)
             : base(start, end, message)
         {
         }
diff --git a/YamlDotNet/Core/SyntaxErrorException.cs b/YamlDotNet/Core/SyntaxErrorException.cs
index d2c5fbba7..21744d15d 100644
--- a/YamlDotNet/Core/SyntaxErrorException.cs
+++ b/YamlDotNet/Core/SyntaxErrorException.cs
@@ -40,7 +40,7 @@ public SyntaxErrorException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="SyntaxErrorException"/> class.
         /// </summary>
-        public SyntaxErrorException(Mark start, Mark end, string message)
+        public SyntaxErrorException(in Mark start, in Mark end, string message)
             : base(start, end, message)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/BlockEnd.cs b/YamlDotNet/Core/Tokens/BlockEnd.cs
index f04136763..b0252180c 100644
--- a/YamlDotNet/Core/Tokens/BlockEnd.cs
+++ b/YamlDotNet/Core/Tokens/BlockEnd.cs
@@ -39,7 +39,7 @@ public BlockEnd()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public BlockEnd(Mark start, Mark end)
+        public BlockEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/BlockEntry.cs b/YamlDotNet/Core/Tokens/BlockEntry.cs
index 872519ab7..6f36b4e44 100644
--- a/YamlDotNet/Core/Tokens/BlockEntry.cs
+++ b/YamlDotNet/Core/Tokens/BlockEntry.cs
@@ -39,7 +39,7 @@ public BlockEntry()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public BlockEntry(Mark start, Mark end)
+        public BlockEntry(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/BlockMappingStart.cs b/YamlDotNet/Core/Tokens/BlockMappingStart.cs
index 4cf95a98c..edec2e962 100644
--- a/YamlDotNet/Core/Tokens/BlockMappingStart.cs
+++ b/YamlDotNet/Core/Tokens/BlockMappingStart.cs
@@ -39,7 +39,7 @@ public BlockMappingStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public BlockMappingStart(Mark start, Mark end)
+        public BlockMappingStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/BlockSequenceStart.cs b/YamlDotNet/Core/Tokens/BlockSequenceStart.cs
index c07c3c5fc..a4157cddb 100644
--- a/YamlDotNet/Core/Tokens/BlockSequenceStart.cs
+++ b/YamlDotNet/Core/Tokens/BlockSequenceStart.cs
@@ -39,7 +39,7 @@ public BlockSequenceStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public BlockSequenceStart(Mark start, Mark end)
+        public BlockSequenceStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/DocumentEnd.cs b/YamlDotNet/Core/Tokens/DocumentEnd.cs
index 583a53172..d1892522b 100644
--- a/YamlDotNet/Core/Tokens/DocumentEnd.cs
+++ b/YamlDotNet/Core/Tokens/DocumentEnd.cs
@@ -39,7 +39,7 @@ public DocumentEnd()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public DocumentEnd(Mark start, Mark end)
+        public DocumentEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/DocumentStart.cs b/YamlDotNet/Core/Tokens/DocumentStart.cs
index 209939e3d..0fe3ad83f 100644
--- a/YamlDotNet/Core/Tokens/DocumentStart.cs
+++ b/YamlDotNet/Core/Tokens/DocumentStart.cs
@@ -39,7 +39,7 @@ public DocumentStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public DocumentStart(Mark start, Mark end)
+        public DocumentStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/FlowEntry.cs b/YamlDotNet/Core/Tokens/FlowEntry.cs
index b82399eda..103334e95 100644
--- a/YamlDotNet/Core/Tokens/FlowEntry.cs
+++ b/YamlDotNet/Core/Tokens/FlowEntry.cs
@@ -39,7 +39,7 @@ public FlowEntry()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public FlowEntry(Mark start, Mark end)
+        public FlowEntry(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/FlowMappingEnd.cs b/YamlDotNet/Core/Tokens/FlowMappingEnd.cs
index a21f5ffda..23770b3f0 100644
--- a/YamlDotNet/Core/Tokens/FlowMappingEnd.cs
+++ b/YamlDotNet/Core/Tokens/FlowMappingEnd.cs
@@ -39,7 +39,7 @@ public FlowMappingEnd()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public FlowMappingEnd(Mark start, Mark end)
+        public FlowMappingEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/FlowMappingStart.cs b/YamlDotNet/Core/Tokens/FlowMappingStart.cs
index 941efa5a3..c75d070ef 100644
--- a/YamlDotNet/Core/Tokens/FlowMappingStart.cs
+++ b/YamlDotNet/Core/Tokens/FlowMappingStart.cs
@@ -39,7 +39,7 @@ public FlowMappingStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public FlowMappingStart(Mark start, Mark end)
+        public FlowMappingStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs b/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs
index 93a7e7de4..f7deaf658 100644
--- a/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs
+++ b/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs
@@ -39,7 +39,7 @@ public FlowSequenceEnd()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public FlowSequenceEnd(Mark start, Mark end)
+        public FlowSequenceEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/FlowSequenceStart.cs b/YamlDotNet/Core/Tokens/FlowSequenceStart.cs
index 8d96ff081..35080ace7 100644
--- a/YamlDotNet/Core/Tokens/FlowSequenceStart.cs
+++ b/YamlDotNet/Core/Tokens/FlowSequenceStart.cs
@@ -39,7 +39,7 @@ public FlowSequenceStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public FlowSequenceStart(Mark start, Mark end)
+        public FlowSequenceStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/Key.cs b/YamlDotNet/Core/Tokens/Key.cs
index 42d5f85ff..fba6896f6 100644
--- a/YamlDotNet/Core/Tokens/Key.cs
+++ b/YamlDotNet/Core/Tokens/Key.cs
@@ -39,7 +39,7 @@ public Key()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public Key(Mark start, Mark end)
+        public Key(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/StreamEnd.cs b/YamlDotNet/Core/Tokens/StreamEnd.cs
index 5886bba29..3169056d4 100644
--- a/YamlDotNet/Core/Tokens/StreamEnd.cs
+++ b/YamlDotNet/Core/Tokens/StreamEnd.cs
@@ -39,7 +39,7 @@ public StreamEnd()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public StreamEnd(Mark start, Mark end)
+        public StreamEnd(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/StreamStart.cs b/YamlDotNet/Core/Tokens/StreamStart.cs
index 4579d385a..6a8194cde 100644
--- a/YamlDotNet/Core/Tokens/StreamStart.cs
+++ b/YamlDotNet/Core/Tokens/StreamStart.cs
@@ -39,7 +39,7 @@ public StreamStart()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public StreamStart(Mark start, Mark end)
+        public StreamStart(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/Tokens/Token.cs b/YamlDotNet/Core/Tokens/Token.cs
index 715442d41..d4cb81feb 100644
--- a/YamlDotNet/Core/Tokens/Token.cs
+++ b/YamlDotNet/Core/Tokens/Token.cs
@@ -19,8 +19,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 // SOFTWARE.
 
-using System;
-
 namespace YamlDotNet.Core.Tokens
 {
     /// <summary>
@@ -43,10 +41,10 @@ public abstract class Token
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        protected Token(Mark start, Mark end)
+        protected Token(in Mark start, in Mark end)
         {
-            this.Start = start ?? throw new ArgumentNullException(nameof(start));
-            this.End = end ?? throw new ArgumentNullException(nameof(end));
+            this.Start = start;
+            this.End = end;
         }
     }
 }
diff --git a/YamlDotNet/Core/Tokens/Value.cs b/YamlDotNet/Core/Tokens/Value.cs
index 6aa917ad4..ab8dfd8e9 100644
--- a/YamlDotNet/Core/Tokens/Value.cs
+++ b/YamlDotNet/Core/Tokens/Value.cs
@@ -39,7 +39,7 @@ public Value()
         /// </summary>
         /// <param name="start">The start position of the token.</param>
         /// <param name="end">The end position of the token.</param>
-        public Value(Mark start, Mark end)
+        public Value(in Mark start, in Mark end)
             : base(start, end)
         {
         }
diff --git a/YamlDotNet/Core/YamlException.cs b/YamlDotNet/Core/YamlException.cs
index 3a207d09d..7f24feb1b 100644
--- a/YamlDotNet/Core/YamlException.cs
+++ b/YamlDotNet/Core/YamlException.cs
@@ -50,7 +50,7 @@ public YamlException(string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="YamlException"/> class.
         /// </summary>
-        public YamlException(Mark start, Mark end, string message)
+        public YamlException(in Mark start, in Mark end, string message)
             : this(start, end, message, null)
         {
         }
@@ -58,7 +58,7 @@ public YamlException(Mark start, Mark end, string message)
         /// <summary>
         /// Initializes a new instance of the <see cref="YamlException"/> class.
         /// </summary>
-        public YamlException(Mark start, Mark end, string message, Exception? innerException)
+        public YamlException(in Mark start, in Mark end, string message, Exception? innerException)
             : base(message, innerException)
         {
             Start = start;
diff --git a/YamlDotNet/Helpers/ThrowHelper.cs b/YamlDotNet/Helpers/ThrowHelper.cs
new file mode 100644
index 000000000..babccb725
--- /dev/null
+++ b/YamlDotNet/Helpers/ThrowHelper.cs
@@ -0,0 +1,35 @@
+// This file is part of YamlDotNet - A .NET library for YAML.
+// Copyright (c) Antoine Aubry and contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace YamlDotNet.Helpers
+{
+    internal static class ThrowHelper
+    {
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static void ThrowArgumentOutOfRangeException(string paramName, string message)
+        {
+            throw new ArgumentOutOfRangeException(paramName, message);
+        }
+    }
+}