[cfe-dev] Reference-counted statements

Chris Lattner clattner at apple.com
Fri Aug 7 18:39:48 PDT 2009


On Aug 7, 2009, at 9:26 AM, Douglas Gregor wrote:

> Daniel, Ted, John and I had a design discussion yesterday about the  
> ownership model for expressions and statements in Clang. The  
> catalyst for this discussion is the generic tree transformation that  
> went into Clang earlier this week, and on the problem of  
> transforming expression trees. In particular, given the expression
>
> 	x + y
>
> let's say that the tree transformer transforms x into x' but leaves  
> y alone. It will then attempt to construct a new addition operation
>
> 	x' +' y
>

It is unfortunate, but I agree that this is probably the best way to  
handle this.  Go for it!  Now we *really* don't want parent pointers  
in the AST :)

-Chris

> With today's strict ownership model for expressions, we have a  
> problem: both the + and the transformed +' believe that they own the  
> subexpression y, which will lead to double-frees, use-after-free  
> errors, etc.
>
> One immediate possibility would be to clone the subexpression y  
> (into a y' that is exactly similar to y); then the +' expression  
> will own x' and y' and the strict ownership model is retained. This  
> solution is relatively easy to implement, and is being used already  
> (in a limited way) during template instantiation. However, it has  
> performance costs in both time and memory. Moreover, it might not be  
> the right answer for other clients of Clang's ASTs, which may need  
> to refer to an expression within the the AST that might be  
> prematurely destroyed.
>
> We think that the addition of reference-counting to statements and  
> expressions is the right answer for Clang, and I've attached a patch  
> that adds such reference counting. Essentially, each statement (and,  
> therefore, expression) gets a an embedded reference count; the  
> Destroy method of a statement decrements the reference count, then  
> deallocates the expression and destroys its children if the  
> reference count hits zero.
>
> Most AST clients will still use simple Stmt or Expr pointers and  
> will not need to increase or decrease the reference counts. In those  
> few places where we are explicitly sharing statements or expressions  
> (e.g., as part of a tree transform), we will call the statement's  
> Retain operation to increase the reference count. In the attached  
> patch, I've introduced Retain calls in a few places to illustrate  
> the idea:
>
> 	1) When performing template instantiation for non-dependent leaf  
> nodes (e.g., literals), we retain the literal as written in the  
> source code bump its reference count by one. Previously, we were  
> cloning.
>
> 	2) When adding a SwitchCase (for a "case" or a "default" statement)  
> to a switch, we retain that SwitchCase. The switch statement itself  
> then Destroys its SwitchCases as part of its own destruction. This  
> fixes a bunch of crash-on-invalid problems we've had with switch  
> statements (see PR3444).
>
> Two performance-related notes: first, the size of statements and  
> expressions did not get any bigger. We reduced the size of the  
> statement class field in Stmt from 32 bits to 8 bits [*] and used  
> the remaining 24 bits for the reference count. Second, the reference  
> counts are modified very, very rarely, and only in response to  
> explicit sharing (as in the two cases I've shown), so we are not  
> concerned about additional overhead introduced by the counting.
>
> Comments, questions, etc. all welcome!
>
> 	- Doug
>
> [*] 256 statement/expression types should be enough for anyone! ;)
>
> <ref-counted- 
> stmts.patch>_______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list