Skip to content

Commit

Permalink
Trying to speed up type handling
Browse files Browse the repository at this point in the history
A map of lists instead of a simple list
  • Loading branch information
oxisto committed Sep 25, 2024
1 parent 868ed5d commit d563993
Show file tree
Hide file tree
Showing 7 changed files with 17 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ private constructor(
// and individual file scopes beneath it
var newGlobalScope = globalCtx.scopeManager.globalScope
var types =
globalCtx.typeManager.firstOrderTypes.union(globalCtx.typeManager.secondOrderTypes)
globalCtx.typeManager.firstOrderTypes.values
.flatten()
.union(globalCtx.typeManager.secondOrderTypes)
types.forEach {
if (it.scope is GlobalScope) {
it.scope = newGlobalScope
Expand Down
11 changes: 6 additions & 5 deletions cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/TypeManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TypeManager {
MutableMap<TemplateDeclaration, MutableList<ParameterizedType>> =
ConcurrentHashMap()

val firstOrderTypes: MutableSet<Type> = ConcurrentHashMap.newKeySet()
val firstOrderTypes = ConcurrentHashMap<String, MutableList<Type>>()
val secondOrderTypes: MutableSet<Type> = ConcurrentHashMap.newKeySet()

/**
Expand Down Expand Up @@ -197,9 +197,10 @@ class TypeManager {
}

if (t.isFirstOrderType) {
var types = firstOrderTypes.computeIfAbsent(t.name.toString()) { mutableListOf() }
// Make sure we only ever return one unique object per type
if (!firstOrderTypes.add(t)) {
return firstOrderTypes.first { it == t && it is T } as T
if (!types.add(t)) {
return types.first { it == t && it is T } as T
} else {
log.trace(
"Registering unique first order type {}{}",
Expand All @@ -224,7 +225,7 @@ class TypeManager {

/** Checks, whether a [Type] with the given [name] exists. */
fun typeExists(name: CharSequence): Boolean {
return firstOrderTypes.any { type: Type -> type.root.name == name }
return firstOrderTypes.values.flatten().any { type: Type -> type.root.name == name }
}

fun resolvePossibleTypedef(alias: Type, scopeManager: ScopeManager): Type {
Expand All @@ -247,7 +248,7 @@ class TypeManager {
return primitiveType
}

return firstOrderTypes.firstOrNull {
return firstOrderTypes[fqn.toString()]?.firstOrNull {
(it.typeOrigin == Type.Origin.RESOLVED || it.typeOrigin == Type.Origin.GUESSED) &&
it.root.name == fqn &&
if (generics != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fun LanguageProvider.objectType(
synchronized(c.typeManager.firstOrderTypes) {
// We can try to look up the type by its name and return it, if it already exists.
var type =
c.typeManager.firstOrderTypes.firstOrNull {
c.typeManager.firstOrderTypes[name.toString()]?.firstOrNull {
it is ObjectType &&
it.name == name &&
it.scope == scope &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,8 @@ fun TranslationContext.tryRecordInference(
// update the type's record. Because types are only unique per scope, we potentially need to
// update multiple type nodes, i.e., all type nodes whose FQN match the inferred record
if (record != null) {
typeManager.firstOrderTypes
typeManager.firstOrderTypes.values
.flatten()
.filter { it.name == record.name }
.forEach { it.recordDeclaration = record }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ open class TypeResolver(ctx: TranslationContext) : ComponentPass(ctx) {

private fun handleNode(node: Node?) {
if (node is RecordDeclaration) {
for (t in typeManager.firstOrderTypes) {
for (t in typeManager.firstOrderTypes.values.flatten()) {
if (t.name == node.name && t is ObjectType) {
// The node is the class of the type t
t.recordDeclaration = node
Expand All @@ -136,7 +136,7 @@ open class TypeResolver(ctx: TranslationContext) : ComponentPass(ctx) {
}

fun resolveFirstOrderTypes() {
for (type in typeManager.firstOrderTypes.sortedBy { it.name }) {
for (type in typeManager.firstOrderTypes.values.flatten().sortedBy { it.name }) {
if (type is ObjectType && type.typeOrigin == Type.Origin.UNRESOLVED) {
resolveType(type)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class JavaExternalTypeHierarchyResolver(ctx: TranslationContext) : ComponentPass
}

// Iterate over all known types and add their (direct) supertypes.
for (t in typeManager.firstOrderTypes) {
for (t in typeManager.firstOrderTypes.values.flatten()) {
val symbol = resolver.tryToSolveType(t.typeName)
if (symbol.isSolved) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ class Application : Callable<Int> {
"Benchmark: analyzing code in " + (analyzingTime - startTime) / S_TO_MS_FACTOR + " s."
)

translationResult.benchmarkResults.print()

exportJsonFile?.let { exportToJson(translationResult, it) }
if (!noNeo4j) {
pushToNeo4j(translationResult)
Expand Down

0 comments on commit d563993

Please sign in to comment.