`StackObj` is used as a base class by some classes. Operationally, it provides allocation and deallocation functions that are all deleted, so that an attempt to apply a `new` or `delete` expression involving a derived class will fail at compile-time.
We've long had a different mechanism for rejecting `new` or `delete` expressions for any class not explicitly defined for such. We detect and complain about calls to the global allocation and deallocation functions at JVM link time. That mechanism has various limitations, making it not as good as `StackObj` though. It's limited to gcc and clang based builds, it's much later (link-time rather than compile-time), and decoding the failure and locating the failure is significantly harder. (It also used to not cover some of the new-ish overloads, but that was recently fixed:JDK-8369188. Those overloads are covered by `StackObj` via argument mismatch failures, due to how C++ name lookup works.)
(Before the link-time check we had asserting replacements for the allocation and deallocation functions in debug builds. There is a lot of discussion in this area inJDK-8173070 and other linked issues.)
However, withJDK-8369187 we now have compile-time warnings for a use of any of the global allocation and deallocation functions, including the various new-ish overloads. So the operational advantages of `StackObj` are now available without needing to derive from that class.
It has been suggested that `StackObj` has a documentation benefit in addition to its operational behavior, acting much like a comment that a derived class should only be allocated on the stack. However, it turns out there is widespread violation of that restriction. There are even classes derived from `StackObj` that are *never* allocated on the stack, instead only being members of other classes that are *exclusively* heap allocated.
So it's much worse than an unenforceable comment. Being in code suggests that there is some actual operational meaning. But there isn't. And when it's used several inheritance layers up, so that it might not be obvious that restriction is supposed to apply, and there's no enforcement, then it's really easy for improper uses to arise. And then what do you do? After a while, it ceases to have any real meaning, and is just noise. Which is where we are now.
It has been suggested that it should only be used for leaf or near leaf classes, and that being used at the root of a significantly nested hierarchy (i.e. so having "several inheritance layers") just seems wrong. And yet, look at `Closure` as an example of exactly that, and the problems that arise. There are other classes like that. So again, we have wide-spread violation of "proper" usage.
We've long had a different mechanism for rejecting `new` or `delete` expressions for any class not explicitly defined for such. We detect and complain about calls to the global allocation and deallocation functions at JVM link time. That mechanism has various limitations, making it not as good as `StackObj` though. It's limited to gcc and clang based builds, it's much later (link-time rather than compile-time), and decoding the failure and locating the failure is significantly harder. (It also used to not cover some of the new-ish overloads, but that was recently fixed:
(Before the link-time check we had asserting replacements for the allocation and deallocation functions in debug builds. There is a lot of discussion in this area in
However, with
It has been suggested that `StackObj` has a documentation benefit in addition to its operational behavior, acting much like a comment that a derived class should only be allocated on the stack. However, it turns out there is widespread violation of that restriction. There are even classes derived from `StackObj` that are *never* allocated on the stack, instead only being members of other classes that are *exclusively* heap allocated.
So it's much worse than an unenforceable comment. Being in code suggests that there is some actual operational meaning. But there isn't. And when it's used several inheritance layers up, so that it might not be obvious that restriction is supposed to apply, and there's no enforcement, then it's really easy for improper uses to arise. And then what do you do? After a while, it ceases to have any real meaning, and is just noise. Which is where we are now.
It has been suggested that it should only be used for leaf or near leaf classes, and that being used at the root of a significantly nested hierarchy (i.e. so having "several inheritance layers") just seems wrong. And yet, look at `Closure` as an example of exactly that, and the problems that arise. There are other classes like that. So again, we have wide-spread violation of "proper" usage.