From 0f08672340821165bdfa014fd3d8a1cb438e5f4e Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 2 Aug 2023 13:13:23 -0700 Subject: [PATCH 01/16] Added 78891 test --- .../JitBlue/Runtime_78891/Runtime_78891.cs | 73 +++++++++++++++++++ .../Runtime_78891/Runtime_78891.csproj | 8 ++ 2 files changed, 81 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs new file mode 100644 index 00000000000000..195b6c6417187c --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Xunit; + +// This test is to ensure that an assertion does not occur in the JIT. +public class Runtime_78554 +{ + public class C0 + { + public long F1; + } + + public struct S5 + { + public bool F1; + public int F2; + public C0 F4; + public short F5; + public ulong F6; + public uint F7; + } + + public class Program + { + public static S5 s_48; + public static int Start() + { + var vr2 = new S5(); + var vr3 = new S5(); + try + { + M59(vr2, vr3); + return 100; + } + catch + { + return 0; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Consume(short x) + { + + } + + public static void M59(S5 arg0, S5 arg1) + { + try + { + arg0 = arg1; + arg0 = arg1; + short var3 = arg1.F5; + Consume(var3); + } + finally + { + if (s_48.F4.F1 > arg0.F7) + { + arg0.F1 |= false; + } + } + } + } + + [Fact] + public static int TestEntryPoint() + { + return Program.Start(); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 35f0ba94eb3cc1d286aaa6dc5ae6d8261716cb3e Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 2 Aug 2023 13:14:16 -0700 Subject: [PATCH 02/16] Fix name --- src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index 195b6c6417187c..99f51c14d36288 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -5,7 +5,7 @@ using Xunit; // This test is to ensure that an assertion does not occur in the JIT. -public class Runtime_78554 +public class Runtime_78891 { public class C0 { From 432e66acb87caa974102d73ce0e7b7228d93e860 Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 2 Aug 2023 13:17:38 -0700 Subject: [PATCH 03/16] Fix test --- .../JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index 99f51c14d36288..9441e536ac1a64 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Runtime.CompilerServices; using Xunit; @@ -32,11 +33,12 @@ public static int Start() try { M59(vr2, vr3); - return 100; + return 0; } - catch + catch (NullReferenceException) { - return 0; + // We expect a null reference exception to occur, return 100. + return 100; } } From 9d1217f81da066090b6bf3e804793505c20ba455 Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 2 Aug 2023 19:04:49 -0700 Subject: [PATCH 04/16] Feedback --- .../JitBlue/Runtime_78891/Runtime_78891.cs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index 9441e536ac1a64..bf19c13a3e7e1f 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -26,20 +26,13 @@ public struct S5 public class Program { public static S5 s_48; - public static int Start() + + [Fact] + public static void Start() { var vr2 = new S5(); var vr3 = new S5(); - try - { - M59(vr2, vr3); - return 0; - } - catch (NullReferenceException) - { - // We expect a null reference exception to occur, return 100. - return 100; - } + Assert.Throws(() => M59(vr2, vr3)); } [MethodImpl(MethodImplOptions.NoInlining)] @@ -66,10 +59,4 @@ public static void M59(S5 arg0, S5 arg1) } } } - - [Fact] - public static int TestEntryPoint() - { - return Program.Start(); - } } From 54544c40a97249de35b0c35df3e9044e8b873098 Mon Sep 17 00:00:00 2001 From: TIHan Date: Sun, 6 Aug 2023 18:19:34 -0700 Subject: [PATCH 05/16] 78891 test is process isolated to use the environment variables. When enabling GC in the emitter, if the current IG has no instructions, do not force a new IG. --- src/coreclr/jit/emit.cpp | 25 +++++++++++++------ .../Runtime_78891/Runtime_78891.csproj | 10 ++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 2d55d71a70a78a..db27df2dae0b37 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -10448,14 +10448,23 @@ void emitter::emitEnableGC() emitNoGCIG = false; - // The next time an instruction needs to be generated, force a new instruction group. - // It will be an emitAdd group in that case. Note that the next thing we see might be - // a label, which will force a non-emitAdd group. - // - // Note that we can't just create a new instruction group here, because we don't know - // if there are going to be any instructions added to it, and we don't support empty - // instruction groups. - emitForceNewIG = true; + // If the current IG does not have instructions, do not force a new IG. + // Instead, just use the current one without NOGCINTERRUPT. + if (emitCurIGnonEmpty()) + { + // The next time an instruction needs to be generated, force a new instruction group. + // It will be an emitAdd group in that case. Note that the next thing we see might be + // a label, which will force a non-emitAdd group. + // + // Note that we can't just create a new instruction group here, because we don't know + // if there are going to be any instructions added to it, and we don't support empty + // instruction groups. + emitForceNewIG = true; + } + else + { + emitCurIG->igFlags &= ~IGF_NOGCINTERRUPT; + } } else { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj index de6d5e08882e86..b102493d45de79 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj @@ -1,8 +1,18 @@ + + true True + + + + + + + + From c035f0fb0a914c2f389fd02c2fb6f8dfd4118b4b Mon Sep 17 00:00:00 2001 From: TIHan Date: Sun, 6 Aug 2023 18:27:45 -0700 Subject: [PATCH 06/16] Remove extend flag --- src/coreclr/jit/emit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index db27df2dae0b37..bc77e6b21d8dcc 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -10449,7 +10449,7 @@ void emitter::emitEnableGC() emitNoGCIG = false; // If the current IG does not have instructions, do not force a new IG. - // Instead, just use the current one without NOGCINTERRUPT. + // Instead, just use the current one without NOGCINTERRUPT and EXTEND. if (emitCurIGnonEmpty()) { // The next time an instruction needs to be generated, force a new instruction group. @@ -10464,6 +10464,7 @@ void emitter::emitEnableGC() else { emitCurIG->igFlags &= ~IGF_NOGCINTERRUPT; + emitCurIG->igFlags &= ~IGF_EXTEND; } } else From 0ecc3f9c35532605d7e1ea963413dc54964f39a5 Mon Sep 17 00:00:00 2001 From: TIHan Date: Sun, 6 Aug 2023 18:29:13 -0700 Subject: [PATCH 07/16] Quick cleanup --- src/coreclr/jit/emit.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index bc77e6b21d8dcc..e41264de96618f 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -10463,8 +10463,7 @@ void emitter::emitEnableGC() } else { - emitCurIG->igFlags &= ~IGF_NOGCINTERRUPT; - emitCurIG->igFlags &= ~IGF_EXTEND; + emitCurIG->igFlags &= ~(IGF_NOGCINTERRUPT | IGF_EXTEND); } } else From 296c2bbf178132669bf73cf9cc2842e157686f5d Mon Sep 17 00:00:00 2001 From: TIHan Date: Sun, 6 Aug 2023 18:37:07 -0700 Subject: [PATCH 08/16] Quick cleanup --- src/coreclr/jit/emit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index e41264de96618f..f2d9f155fb684c 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -10449,7 +10449,7 @@ void emitter::emitEnableGC() emitNoGCIG = false; // If the current IG does not have instructions, do not force a new IG. - // Instead, just use the current one without NOGCINTERRUPT and EXTEND. + // Instead, just use the current one with the flags reset. if (emitCurIGnonEmpty()) { // The next time an instruction needs to be generated, force a new instruction group. @@ -10463,7 +10463,7 @@ void emitter::emitEnableGC() } else { - emitCurIG->igFlags &= ~(IGF_NOGCINTERRUPT | IGF_EXTEND); + emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK); } } else From 2cdd5d995928e44b822908b5a5d9ac8ac9c2dc6a Mon Sep 17 00:00:00 2001 From: Will Smith Date: Sun, 6 Aug 2023 19:00:41 -0700 Subject: [PATCH 09/16] Update Runtime_78891.csproj --- .../JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj index b102493d45de79..5997f6cfc55265 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.csproj @@ -8,7 +8,6 @@ - From 587ba9a91e4e3584dd9d1038c47dcc0af6a800ba Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 09:20:07 -0700 Subject: [PATCH 10/16] Feedback --- src/coreclr/jit/emit.cpp | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index f2d9f155fb684c..676a1898215e2b 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1654,7 +1654,10 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) if ((emitCurIGfreeNext + fullSize >= emitCurIGfreeEndp) || emitForceNewIG || (emitCurIGinsCnt >= (EMIT_MAX_IG_INS_COUNT - 1))) { - emitNxtIG(true); + if (emitCurIGnonEmpty()) + { + emitNxtIG(true); + } } /* Grab the space for the instruction */ @@ -10448,23 +10451,14 @@ void emitter::emitEnableGC() emitNoGCIG = false; - // If the current IG does not have instructions, do not force a new IG. - // Instead, just use the current one with the flags reset. - if (emitCurIGnonEmpty()) - { - // The next time an instruction needs to be generated, force a new instruction group. - // It will be an emitAdd group in that case. Note that the next thing we see might be - // a label, which will force a non-emitAdd group. - // - // Note that we can't just create a new instruction group here, because we don't know - // if there are going to be any instructions added to it, and we don't support empty - // instruction groups. - emitForceNewIG = true; - } - else - { - emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK); - } + // The next time an instruction needs to be generated, force a new instruction group. + // It will be an emitAdd group in that case. Note that the next thing we see might be + // a label, which will force a non-emitAdd group. + // + // Note that we can't just create a new instruction group here, because we don't know + // if there are going to be any instructions added to it, and we don't support empty + // instruction groups. + emitForceNewIG = true; } else { From 96a6f8923b40fa60284b098e3e48a319e9fda8fb Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 09:48:09 -0700 Subject: [PATCH 11/16] Fix test --- .../JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index bf19c13a3e7e1f..9195d92a5aef55 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -28,11 +28,12 @@ public class Program public static S5 s_48; [Fact] - public static void Start() + public static int TestEntryPoint() { var vr2 = new S5(); var vr3 = new S5(); Assert.Throws(() => M59(vr2, vr3)); + return 100; } [MethodImpl(MethodImplOptions.NoInlining)] From dd950d900f6e24b8b5a51da1060c8f253f70af3f Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 12:38:11 -0700 Subject: [PATCH 12/16] Fix test --- .../JitBlue/Runtime_78891/Runtime_78891.cs | 73 +++++++++---------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index 9195d92a5aef55..90fcf714ff13d1 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -5,58 +5,55 @@ using System.Runtime.CompilerServices; using Xunit; +public class C0 +{ + public long F1; +} + +public struct S5 +{ + public bool F1; + public int F2; + public C0 F4; + public short F5; + public ulong F6; + public uint F7; +} + // This test is to ensure that an assertion does not occur in the JIT. public class Runtime_78891 { - public class C0 - { - public long F1; - } + public static S5 s_48; - public struct S5 + [Fact] + public static int TestEntryPoint() { - public bool F1; - public int F2; - public C0 F4; - public short F5; - public ulong F6; - public uint F7; + var vr2 = new S5(); + var vr3 = new S5(); + Assert.Throws(() => M59(vr2, vr3)); + return 100; } - public class Program + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Consume(short x) { - public static S5 s_48; - [Fact] - public static int TestEntryPoint() - { - var vr2 = new S5(); - var vr3 = new S5(); - Assert.Throws(() => M59(vr2, vr3)); - return 100; - } + } - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Consume(short x) + public static void M59(S5 arg0, S5 arg1) + { + try { - + arg0 = arg1; + arg0 = arg1; + short var3 = arg1.F5; + Consume(var3); } - - public static void M59(S5 arg0, S5 arg1) + finally { - try - { - arg0 = arg1; - arg0 = arg1; - short var3 = arg1.F5; - Consume(var3); - } - finally + if (s_48.F4.F1 > arg0.F7) { - if (s_48.F4.F1 > arg0.F7) - { - arg0.F1 |= false; - } + arg0.F1 |= false; } } } From 5e2257a03465e4d8ec44bfd9f7089fdd1cdf3a8e Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 12:40:04 -0700 Subject: [PATCH 13/16] Reset flags --- src/coreclr/jit/emit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 676a1898215e2b..ec221728e70f94 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1654,10 +1654,17 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) if ((emitCurIGfreeNext + fullSize >= emitCurIGfreeEndp) || emitForceNewIG || (emitCurIGinsCnt >= (EMIT_MAX_IG_INS_COUNT - 1))) { + // If the current IG has instructions, then we need to create a new one. + // If it does not, then re-use the current one with its flags reset. if (emitCurIGnonEmpty()) { emitNxtIG(true); } + else + { + // Reset flags. + emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK); + } } /* Grab the space for the instruction */ From c14814f2817ce5e14be123086bcd3d985dc2ca6d Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 12:41:57 -0700 Subject: [PATCH 14/16] Fix test --- src/coreclr/jit/emit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index ec221728e70f94..e27b2ed970979d 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1663,7 +1663,7 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) else { // Reset flags. - emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK); + emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK) | IGF_EXTEND; } } From 662779b6ae6015c7a0f5082f50dbb5a08ee2c98e Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 13:58:26 -0700 Subject: [PATCH 15/16] Fixing test again... --- .../JitBlue/Runtime_78891/Runtime_78891.cs | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs index 90fcf714ff13d1..9b376b4b40fd21 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_78891/Runtime_78891.cs @@ -5,42 +5,33 @@ using System.Runtime.CompilerServices; using Xunit; -public class C0 -{ - public long F1; -} - -public struct S5 -{ - public bool F1; - public int F2; - public C0 F4; - public short F5; - public ulong F6; - public uint F7; -} - // This test is to ensure that an assertion does not occur in the JIT. public class Runtime_78891 { - public static S5 s_48; + class C0 + { + public long F1; + } - [Fact] - public static int TestEntryPoint() + struct S5 { - var vr2 = new S5(); - var vr3 = new S5(); - Assert.Throws(() => M59(vr2, vr3)); - return 100; + public bool F1; + public int F2; + public C0 F4; + public short F5; + public ulong F6; + public uint F7; } + static S5 s_48; + [MethodImpl(MethodImplOptions.NoInlining)] - public static void Consume(short x) + static void Consume(short x) { } - public static void M59(S5 arg0, S5 arg1) + static void M59(S5 arg0, S5 arg1) { try { @@ -57,4 +48,12 @@ public static void M59(S5 arg0, S5 arg1) } } } + + [Fact] + public static void TestEntryPoint() + { + var vr2 = new S5(); + var vr3 = new S5(); + Assert.Throws(() => M59(vr2, vr3)); + } } From e9d26999aad22963f0d9b6d30350effa1c7b0606 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 7 Aug 2023 17:26:49 -0700 Subject: [PATCH 16/16] Only set the NOGCINTERRUPT flag accordingly --- src/coreclr/jit/emit.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index e27b2ed970979d..59d82cc741bac1 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1655,15 +1655,20 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) (emitCurIGinsCnt >= (EMIT_MAX_IG_INS_COUNT - 1))) { // If the current IG has instructions, then we need to create a new one. - // If it does not, then re-use the current one with its flags reset. if (emitCurIGnonEmpty()) { emitNxtIG(true); } else { - // Reset flags. - emitCurIG->igFlags = (emitCurIG->igFlags & IGF_PROPAGATE_MASK) | IGF_EXTEND; + if (emitNoGCIG) + { + emitCurIG->igFlags |= IGF_NOGCINTERRUPT; + } + else + { + emitCurIG->igFlags &= ~IGF_NOGCINTERRUPT; + } } }