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

Stack trace population code can (re-)use cached Strings

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Other
    • Icon: P3 P3
    • None
    • 9
    • hotspot

      JDK-8150778 switched to StackWalker API for populating stacktrace elements in Throwable. We may optimize the VM parts even further:
       http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-March/039280.html

      Profiling shows we spent lots of time StringTable::intern-ing to convert Symbols to Strings:

                      6.600 (60%) org.openjdk.StackTraceBench.doDepth(int)
                      +- 3.920 (36%) java.lang.Throwable.getStackTrace()
                        +- 3.920 (36%) java.lang.Throwable.getStackTraceElements(java.lang.StackTraceElement[])
                          +- 3.920 (36%) JVM_GetStackTraceElements
                            +- 3.910 (36%) java_lang_Throwable::get_stack_trace_elements(Handle,objArrayHandle,Thread*)
                            | +- 3.910 (36%) java_lang_StackTraceElement::fill_in(Handle,InstanceKlass*,const methodHandle&,int,int,int,Thread*)
                            | +- 1.890 (17%) StringTable::intern(const char*,Thread*)
                            | | +- 0.480 (4%) StringTable::lookup_shared(unsigned short*,int)
                            | | +- 0.350 (3%) UTF8::unicode_length(const char*,bool&,bool&)
                            | | +- 0.320 (3%) java_lang_String::equals(oopDesc*,unsigned short*,int)
                            | | +- 0.300 (3%) StringTable::hash_string<unsigned short>(const unsigned short*,int)
                            | | +- 0.260 (2%) UTF8::convert_to_unicode<unsigned short>(const char*,unsigned short*,int)
                            | | +- 0.140 (1%) resource_allocate_bytes(unsigned long,AllocFailStrategy::AllocFailEnum)
                            | | +- 0.040 (0%) G1SATBCardTableModRefBS::enqueue(oopDesc*)
                            | +- 1.260 (12%) StringTable::intern(Symbol*,Thread*)
                            | | +- 0.490 (4%) java_lang_String::equals(oopDesc*,unsigned short*,int)
                            | | +- 0.360 (3%) StringTable::lookup_shared(unsigned short*,int)
                            | | +- 0.300 (3%) StringTable::hash_string<unsigned short>(const unsigned short*,int)
                            | | +- 0.080 (1%) Symbol::as_unicode(int&)const
                            | | +- 0.030 (0%) G1SATBCardTableModRefBS::enqueue(oopDesc*)
                            | +- 0.500 (5%) Klass::external_name()const
                            | | +- 0.380 (3%) Symbol::as_klass_external_name()const
                            | | +- 0.120 (1%) strlen
                            | +- 0.250 (2%) Backtrace::get_line_number(const methodHandle&,int)
                            | | +- 0.250 (2%) Method::line_number_from_bci(int)const
                            | +- 0.010 (0%) oopDesc::obj_field_put(int,oopDesc*)
                            +- 0.010 (0%) HandleMark::pop_and_restore()

      At least class name may be cached in Class.name field in Java, e.g.:
       http://cr.openjdk.java.net/~shade/8151751/poc-cache-Class.name.patch

      Method name and source file name might piggyback on ConstantPool constant string resolution?

      The performance improvements are very promising, up to 3-4x performance improvement across stack trace depths, see the benchmark and results here:
        http://cr.openjdk.java.net/~shade/8151751/StackTraceBench.java
        (runnable JAR: http://cr.openjdk.java.net/~shade/8151751/benchmarks.jar)

            shade Aleksey Shipilev
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: