diff options
author | Lukas Rytz <lukas.rytz@typesafe.com> | 2016-05-25 06:30:12 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@typesafe.com> | 2016-05-25 06:30:12 +0200 |
commit | c17ef7758bee4be23dcd91701d54f09220bdc343 (patch) | |
tree | 710fe9bc16d203f3ef162b4fa0da50b614527650 /test | |
parent | 808f3d071e97aa23b797f2c0616c207ff1f20229 (diff) | |
parent | 60f28f9e6a330e91a0f1204917301d401a6fce72 (diff) | |
download | scala-c17ef7758bee4be23dcd91701d54f09220bdc343.tar.gz scala-c17ef7758bee4be23dcd91701d54f09220bdc343.tar.bz2 scala-c17ef7758bee4be23dcd91701d54f09220bdc343.zip |
Merge pull request #5124 from performantdata/bug/SI-9522
SI-9522 release key reference when deleting from OpenHashMap
Diffstat (limited to 'test')
-rw-r--r-- | test/junit/scala/collection/mutable/OpenHashMapTest.scala | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/test/junit/scala/collection/mutable/OpenHashMapTest.scala b/test/junit/scala/collection/mutable/OpenHashMapTest.scala index 9b5c20e01a..b6cddf2101 100644 --- a/test/junit/scala/collection/mutable/OpenHashMapTest.scala +++ b/test/junit/scala/collection/mutable/OpenHashMapTest.scala @@ -4,6 +4,10 @@ import org.junit.Test import org.junit.Assert._ import org.junit.runner.RunWith import org.junit.runners.JUnit4 +import org.openjdk.jol.info.GraphLayout +import org.openjdk.jol.info.GraphWalker +import org.openjdk.jol.info.GraphVisitor +import org.openjdk.jol.info.GraphPathRecord /** Tests for [[OpenHashMap]]. */ @RunWith(classOf[JUnit4]) @@ -28,7 +32,13 @@ class OpenHashMapTest { val fieldMirror = mirror.reflect(m).reflectField(termSym) */ // Use Java reflection instead for now. - val field = m.getClass.getDeclaredField("deleted") + val field = + try { // Name may or not be mangled, depending on what the compiler authors are doing. + m.getClass.getDeclaredField("scala$collection$mutable$OpenHashMap$$deleted") + } catch { + case _: NoSuchFieldException => + m.getClass.getDeclaredField("deleted") + } field.setAccessible(true) m.put(0, 0) @@ -39,4 +49,50 @@ class OpenHashMapTest { // TODO assertEquals(0, fieldMirror.get.asInstanceOf[Int]) assertEquals(0, field.getInt(m)) } + + /** Test that an [[OpenHashMap]] frees references to a deleted key (SI-9522). */ + @Test + def freesDeletedKey { + import scala.language.reflectiveCalls + + class MyClass { + override def hashCode() = 42 + } + + val counter = new GraphVisitor() { + private[this] var instanceCount: Int = _ + + def countInstances(obj: AnyRef) = { + instanceCount = 0 + val walker = new GraphWalker(obj) + walker.addVisitor(this) + walker.walk + instanceCount + } + + override def visit(record: GraphPathRecord) { + if (record.klass() == classOf[MyClass]) instanceCount += 1 + } + } + + val m = OpenHashMap.empty[MyClass, Int] + val obj = new MyClass + assertEquals("Found a key instance in the map before adding one!?", 0, counter.countInstances(m)) + m.put(obj, 0) + assertEquals("There should be only one key instance in the map.", 1, counter.countInstances(m)) + m.put(obj, 1) + assertEquals("There should still be only one key instance in the map.", 1, counter.countInstances(m)) + m.remove(obj) + assertEquals("There should be no key instance in the map.", 0, counter.countInstances(m)) + + val obj2 = new MyClass + assertEquals("The hash codes of the test objects need to match.", obj.##, obj2.##) + m.put(obj, 0) + m.put(obj2, 0) + assertEquals("There should be two key instances in the map.", 2, counter.countInstances(m)) + m.remove(obj) + assertEquals("There should be one key instance in the map.", 1, counter.countInstances(m)) + m.remove(obj2) + assertEquals("There should be no key instance in the map.", 0, counter.countInstances(m)) + } } |