From f8bbd5eff01a85e509ad549dd22b6d1d0db3168a Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Wed, 21 Nov 2018 19:39:17 +0700 Subject: [PATCH] [regex] Fix memory leak in debug mode --- .../kotlin/text/regex/AbstractCharClass.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt b/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt index 08f19d41450..bc8e56e6ba7 100644 --- a/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt +++ b/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt @@ -93,14 +93,16 @@ internal abstract class AbstractCharClass : SpecialToken() { surrogates_.value?.let { return it } + val surrogates = lowHighSurrogates val result = object : AbstractCharClass() { override fun contains(ch: Int): Boolean { val index = ch - Char.MIN_SURROGATE.toInt() - return if (index >= 0 && index < AbstractCharClass.SURROGATE_CARDINALITY) - this.altSurrogates xor this@AbstractCharClass.lowHighSurrogates.get(index) - else + return if (index >= 0 && index < AbstractCharClass.SURROGATE_CARDINALITY) { + this.altSurrogates xor surrogates[index] + } else { false + } } } result.setNegative(this.altSurrogates) @@ -109,12 +111,10 @@ internal abstract class AbstractCharClass : SpecialToken() { } - private val withoutSurrogates_ = AtomicReference(null) + // We cannot cache this class as we've done with surrogates above because + // here is a circular reference between it and AbstractCharClass. val withoutSurrogates: AbstractCharClass get() { - withoutSurrogates_.value?.let { - return it - } val result = object : AbstractCharClass() { override fun contains(ch: Int): Boolean { val index = ch - Char.MIN_SURROGATE.toInt() @@ -129,11 +129,9 @@ internal abstract class AbstractCharClass : SpecialToken() { } result.setNegative(isNegative()) result.mayContainSupplCodepoints = mayContainSupplCodepoints - withoutSurrogates_ .compareAndSet(null, result.freeze()) - return withoutSurrogates_.value!! + return result } - /** * Sets this CharClass to negative form, i.e. if they will add some characters and after that set this * class to negative it will accept all the characters except previously set ones.