IR: synchronize on SymbolTable operations

This commit is contained in:
Georgy Bronnikov
2021-01-15 14:17:41 +03:00
parent c9d0448fd1
commit ec2dc9c0fa
@@ -76,101 +76,113 @@ class SymbolTable(
abstract fun get(sig: IdSignature): S? abstract fun get(sig: IdSignature): S?
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B { inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
@Suppress("UNCHECKED_CAST") synchronized(this) {
val d0 = d.original as D @Suppress("UNCHECKED_CAST")
assert(d0 === d) { val d0 = d.original as D
"Non-original descriptor in declaration: $d\n\tExpected: $d0" assert(d0 === d) {
"Non-original descriptor in declaration: $d\n\tExpected: $d0"
}
val existing = get(d0)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
unboundSymbols.remove(existing)
existing
}
return createOwner(symbol)
} }
val existing = get(d0)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
unboundSymbols.remove(existing)
existing
}
return createOwner(symbol)
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
inline fun declare(sig: IdSignature, createSymbol: () -> S, createOwner: (S) -> B): B { inline fun declare(sig: IdSignature, createSymbol: () -> S, createOwner: (S) -> B): B {
val existing = get(sig) synchronized(this) {
val symbol = if (existing == null) { val existing = get(sig)
createSymbol() val symbol = if (existing == null) {
} else { createSymbol()
unboundSymbols.remove(existing) } else {
existing unboundSymbols.remove(existing)
existing
}
val result = createOwner(symbol)
// TODO: try to get rid of this
set(symbol)
return result
} }
val result = createOwner(symbol)
// TODO: try to get rid of this
set(symbol)
return result
} }
inline fun declareIfNotExists(d: D, createSymbol: () -> S, createOwner: (S) -> B): B { inline fun declareIfNotExists(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
@Suppress("UNCHECKED_CAST") synchronized(this) {
val d0 = d.original as D @Suppress("UNCHECKED_CAST")
assert(d0 === d) { val d0 = d.original as D
"Non-original descriptor in declaration: $d\n\tExpected: $d0" assert(d0 === d) {
"Non-original descriptor in declaration: $d\n\tExpected: $d0"
}
val existing = get(d0)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
if (!existing.isBound) unboundSymbols.remove(existing)
existing
}
return if (symbol.isBound) symbol.owner else createOwner(symbol)
} }
val existing = get(d0)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
if (!existing.isBound) unboundSymbols.remove(existing)
existing
}
return if (symbol.isBound) symbol.owner else createOwner(symbol)
} }
inline fun declare(sig: IdSignature, d: D?, createSymbol: () -> S, createOwner: (S) -> B): B { inline fun declare(sig: IdSignature, d: D?, createSymbol: () -> S, createOwner: (S) -> B): B {
@Suppress("UNCHECKED_CAST") synchronized(this) {
val d0 = d?.original as D @Suppress("UNCHECKED_CAST")
assert(d0 === d) { val d0 = d?.original as D
"Non-original descriptor in declaration: $d\n\tExpected: $d0" assert(d0 === d) {
"Non-original descriptor in declaration: $d\n\tExpected: $d0"
}
val existing = get(sig)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
unboundSymbols.remove(existing)
existing
}
return createOwner(symbol)
} }
val existing = get(sig)
val symbol = if (existing == null) {
val new = createSymbol()
set(new)
new
} else {
unboundSymbols.remove(existing)
existing
}
return createOwner(symbol)
} }
inline fun referenced(d: D, orElse: () -> S): S { inline fun referenced(d: D, orElse: () -> S): S {
@Suppress("UNCHECKED_CAST") synchronized(this) {
val d0 = d.original as D @Suppress("UNCHECKED_CAST")
assert(d0 === d) { val d0 = d.original as D
"Non-original descriptor in declaration: $d\n\tExpected: $d0" assert(d0 === d) {
} "Non-original descriptor in declaration: $d\n\tExpected: $d0"
val s = get(d0)
if (s == null) {
val new = orElse()
assert(unboundSymbols.add(new)) {
"Symbol for $new was already referenced"
} }
set(new) val s = get(d0)
return new if (s == null) {
val new = orElse()
assert(unboundSymbols.add(new)) {
"Symbol for $new was already referenced"
}
set(new)
return new
}
return s
} }
return s
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
inline fun referenced(sig: IdSignature, orElse: () -> S): S { inline fun referenced(sig: IdSignature, orElse: () -> S): S {
return get(sig) ?: run { synchronized(this) {
val new = orElse() return get(sig) ?: run {
assert(unboundSymbols.add(new)) { val new = orElse()
"Symbol for ${new.signature} was already referenced" assert(unboundSymbols.add(new)) {
"Symbol for ${new.signature} was already referenced"
}
set(new)
new
} }
set(new)
new
} }
} }
} }