JastAdd dynamically grows the child vector to fit all children when calling
setChild(). This works well for
List nodes that need to expand their child vector to fit all children. Since the AST should be fully parsed before evaluating any attribute, we can assume that all lists have their final size. However, this is not necessarily true of nodes with grammar-declared NTAs.
Grammar-declared NTAs are stored in the child vector, but only inserted when first evaluated. This creates a possible race for threads needing to expand the child vector to fit new NTA children.
- Reserve space for NTAs in the child vector when constructing a node.
- Generate a variant of
setChild(), maybe called
setChildConcurrent(), which uses mutual exclusion or other synchronization if the child vector needs to grow. Use
setChildConcurrent()inside NTA evaluator. Child vector growing can be safely serialized and will not lead to deadlock (only one lock needed per node).
- Don't store NTAs in the child vector.