@@ -19,16 +19,10 @@ internal actual fun <E : Throwable> recoverStackTrace(exception: E): E {
19
19
}
20
20
21
21
private fun <E : Throwable > E.sanitizeStackTrace (): E {
22
+ val stackTrace = stackTrace
22
23
val size = stackTrace.size
23
24
24
- var lastIntrinsic = - 1
25
- for (i in 0 until size) {
26
- val name = stackTrace[i].className
27
- if (" kotlinx.coroutines.internal.ExceptionsKt" == name) {
28
- lastIntrinsic = i
29
- }
30
- }
31
-
25
+ val lastIntrinsic = stackTrace.indexOfFirst { " kotlinx.coroutines.internal.ExceptionsKt" == it.className }
32
26
val startIndex = lastIntrinsic + 1
33
27
val trace = Array (size - lastIntrinsic) {
34
28
if (it == 0 ) {
@@ -38,7 +32,7 @@ private fun <E : Throwable> E.sanitizeStackTrace(): E {
38
32
}
39
33
}
40
34
41
- stackTrace = trace
35
+ setStackTrace( trace)
42
36
return this
43
37
}
44
38
@@ -74,6 +68,12 @@ internal actual fun <E : Throwable> unwrap(exception: E): E {
74
68
return exception
75
69
}
76
70
71
+ val cause = exception.cause
72
+ // Fast-path to avoid array cloning
73
+ if (cause == null || cause.javaClass != exception.javaClass) {
74
+ return exception
75
+ }
76
+
77
77
val element = exception.stackTrace.firstOrNull() ? : return exception
78
78
if (element.isArtificial()) {
79
79
@Suppress(" UNCHECKED_CAST" )
@@ -102,7 +102,7 @@ internal fun sanitize(element: StackTraceElement): StackTraceElement {
102
102
if (! element.className.contains(' /' )) {
103
103
return element
104
104
}
105
- // STE generated with debug metadata contains '/' as separators in FQN, while Java contains dots
105
+ // KT-28237: STE generated with debug metadata contains '/' as separators in FQN, while Java contains dots
106
106
return StackTraceElement (element.className.replace(' /' , ' .' ), element.methodName, element.fileName, element.lineNumber)
107
107
}
108
108
internal fun artificialFrame (message : String ) = java.lang.StackTraceElement (" \b\b\b ($message " , " \b " , " \b " , - 1 )
0 commit comments