Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8224193

stringStream should not use Resource Area



    • Subcomponent:
    • Resolved In Build:



        stringStream is often used as a temp buffer to assemble messages before posting them somewhere else. For example (compilerBroker.cpp):

          void log_compile(JavaThread* thread, CompileTask* task) {
            StringLogMessage lm;
            stringStream sstr = lm.stream();
            // msg.time_stamp().update_to(tty->time_stamp().ticks());
            task->print(&sstr, NULL, true, false);
            log(thread, "%s", (const char*)lm);

        This is a valid scenario; the problem however is that stringStream uses ResourceArea as backing memory for its temporary buffer which is a very poor choice for two reasons:

        1) When implementing sub functions which print to the stream and also need Resource Area, the polite thing to do is to span open a ResourceMark in the sub function (e.g. inside CompileTask::print() in above example).

        However, if the printing the sub function does happens to trigger a reallocation of the stream-internal backing memory, it will do so under the then current ResourceMark in the child frame. That will either crash in release builds or assert in debug builds (see [1] for an example). The bad thing is that this is difficult to test since it is dependent on how much logging happens.

        2) Even if we did not have the problem of ResourceMarks, this is very inefficient way to use resource area, since resource area resizing is often not a resizing but just a reallocation of the buffer while the old buffer is not released (if the character array is not at the top of the resource area anymore). That is by design and cannot be changed.

        Because of both reasons, the reasonable thing to do would be to not use resource area for any kind of buffer which gets handed up and down the stack and potentially resized inside every frame. Like it is typical for stream objects.

        Note that we did a similar cleanup already in UL, with the same reasoning: JDK-8181917


        [1] Example assert stack:

        Stack: [0x00003fff511b0000,0x00003fff515b0000], sp=0x00003fff515ad380, free space=4084k
        Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
        V [libjvm.so+0x1824afc] stringStream::write(char const*, unsigned long)+0x22c
        V [libjvm.so+0x182528c] outputStream::do_vsnprintf_and_write_with_automatic_buffer(char const*, char*, bool)+0x10c
        V [libjvm.so+0x1825b2c] outputStream::print(char const*, ...)+0x13c
        V [libjvm.so+0x16d5514] Method::print_short_name(outputStream*)+0xe4
        V [libjvm.so+0xcee158] CompileTask::print(outputStream*, char const*, bool, bool)+0x188
        V [libjvm.so+0xce6ca0] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xf30
        V [libjvm.so+0xce7f48] CompileBroker::compiler_thread_loop()+0xb58
        V [libjvm.so+0x1b56b7c] compiler_thread_entry(JavaThread*, Thread*)+0x7c
        V [libjvm.so+0x1b62304] JavaThread::thread_main_inner()+0x234
        V [libjvm.so+0x1b6a138] Thread::call_run()+0x158
        V [libjvm.so+0x180e08c] thread_native_entry(Thread*)+0x18c
        C [libpthread.so.0+0xc460] start_thread+0x100


            Issue Links



                stuefe Thomas Stuefe
                stuefe Thomas Stuefe
                0 Vote for this issue
                1 Start watching this issue