JDK-8244999 : Clean up usage of ResourceMark in print functions with an outputStream argument
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 15
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2020-05-14
  • Updated: 2022-01-03
  • Resolved: 2020-08-06
Related Reports
Relates :  
Relates :  
Description
JDK-8222893 fixed a bug due to the usage of a ResourceMark in a print function. The RFR [1] states that:

"print functions with outputStream should not have a ResourceMark because you could call it with a LogStream or stream that was allocated outside the resource mark. The caller needs the ResourceMark."

As a follow-up, we should take a closer look at other print functions with an outputStream argument which also define a ResourceMark like Klass::print_on(outputStream*) and clean these up.


[1] https://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2019-May/034095.html
Comments
What [~dholmes] writes above makes sense. Finding and testing that the callers of these print(outputStream*) functions have a ResourceMark rather than having the ResourceMark in the code that knows it needs one is hard to do. Also, the printing functions aren't well tested. They are mostly used for logging, Print* options and debugging and error conditions. From my reading stringStream now has a CHeap backing store for the string since JDK-8224193, and LogStream uses malloc, so this isn't really an issue anymore. Closing as WNF.
06-08-2020

I'm really not clear what this bug is about - even after following the various links. Given: void Foo::print_on(Outputstream st) { ResourceMark rm; st->print_cr("Foo: %s", somethingUsing ResourceArea()); } what exactly are we concerned about? I'm assuming it is something like this ... if st is itself a ResourceArea-based object then the call to print_cr might reallocate an internal data structure in the ResourceArea, but that will be wiped out when we call the ResourceMark destructor, thus resulting in a broken stream object. But if that is the case then simply moving the ResourceMark to the caller is not in itself enough: if (someCondition) { ResourceMark rm; Foo::print_on(st); } This has the exact same problem in regard to st allocating under the ResourceMark. The only safe usage is where st is actually allocated initially under the ResourceMark: ResourceMark rm; MyStream st = new MyStream() if (someCondition) { Foo::print_on(st); } Given ResourceMarks are intended to manage temporary use of the ResourceArea and help avoid excessive allocation through prompt deallocation, this seems a generally impractical pattern to use. To me it argues that streams should never be ResourceArea based and so are always safe in relation to ResourceMarks. In which case we do not have worry about this and can always put the ResourceMark in the method that actually uses the object allocated in the ResourceArea.
02-06-2020