From e05f79b11cb9dbe5a75723109fe13fd9043a2afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 17 Jan 2022 14:51:57 +0900 Subject: [PATCH 1/2] Split CheckNotDisposed to allow inlining `CheckNotDisposed` is not getting inlined because RyuJIT thinks it's not profitable (ldstr/newobj/throw is expensive). If we extract the rare path into a separate method, it changes the profitability math and allows inlining to happen. --- .../src/System/Text/Json/Writer/Utf8JsonWriter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 084b7c65c6350c..1c3a105a8c0d58 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -238,11 +238,13 @@ private void CheckNotDisposed() // The conditions are ordered with stream first as that would be the most common mode if (_output == null) { - throw new ObjectDisposedException(nameof(Utf8JsonWriter)); + ThrowObjectDisposedException(); } } } + private void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(Utf8JsonWriter)); + /// /// Commits the JSON text written so far which makes it visible to the output destination. /// From e700e3a5300087848ec5944e1867f3187101f2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 18 Jan 2022 08:02:01 +0900 Subject: [PATCH 2/2] Review feedback --- .../System.Text.Json/src/System/Text/Json/ThrowHelper.cs | 6 ++++++ .../src/System/Text/Json/Writer/Utf8JsonWriter.cs | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index e5cd6d024ee1aa..a164e71c13993d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -646,6 +646,12 @@ public static void ThrowInvalidOperationException_ExpectedChar(JsonTokenType tok { throw GetInvalidOperationException("char", tokenType); } + + [DoesNotReturn] + public static void ThrowObjectDisposedException_Utf8JsonWriter() + { + throw new ObjectDisposedException(nameof(Utf8JsonWriter)); + } } internal enum ExceptionResource diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 1c3a105a8c0d58..9b22c33ac7d8f7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -238,13 +238,11 @@ private void CheckNotDisposed() // The conditions are ordered with stream first as that would be the most common mode if (_output == null) { - ThrowObjectDisposedException(); + ThrowHelper.ThrowObjectDisposedException_Utf8JsonWriter(); } } } - private void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(Utf8JsonWriter)); - /// /// Commits the JSON text written so far which makes it visible to the output destination. ///