<lambda>null1 package shark.internal
2
3 import shark.HeapObject.HeapObjectArray
4 import shark.internal.Reference.LazyDetails
5 import shark.internal.ReferenceLocationType.ARRAY_ENTRY
6 import shark.ValueHolder
7
8 internal class ObjectArrayReferenceReader : ReferenceReader<HeapObjectArray> {
9 override fun read(source: HeapObjectArray): Sequence<Reference> {
10 if (source.isSkippablePrimitiveWrapperArray) {
11 // primitive wrapper arrays aren't interesting.
12 // That also means the wrapped size isn't added to the dominator tree, so we need to
13 // add that back when computing shallow size in ShallowSizeCalculator.
14 // Another side effect is that if the wrapped primitive is referenced elsewhere, we might
15 // double count its size.
16 return emptySequence()
17 }
18
19 val graph = source.graph
20 val record = source.readRecord()
21 val arrayClassId = source.arrayClassId
22 return record.elementIds.asSequence().filter { objectId ->
23 objectId != ValueHolder.NULL_REFERENCE && graph.objectExists(objectId)
24 }.mapIndexed { index, elementObjectId ->
25 Reference(
26 valueObjectId = elementObjectId,
27 isLowPriority = false,
28 lazyDetailsResolver = {
29 LazyDetails(
30 name = index.toString(),
31 locationClassObjectId = arrayClassId,
32 locationType = ARRAY_ENTRY,
33 isVirtual = false,
34 matchedLibraryLeak = null
35 )
36 }
37 )
38 }
39 }
40 internal companion object {
41 private val skippablePrimitiveWrapperArrayTypes = setOf(
42 Boolean::class,
43 Char::class,
44 Float::class,
45 Double::class,
46 Byte::class,
47 Short::class,
48 Int::class,
49 Long::class
50 ).map { it.javaObjectType.name + "[]" }
51
52 internal val HeapObjectArray.isSkippablePrimitiveWrapperArray: Boolean
53 get() = arrayClassName in skippablePrimitiveWrapperArrayTypes
54 }
55 }
56