Uploaded image for project: 'Harmony'
  1. Harmony
  2. HARMONY-6051

[jit][opt]A special case not considered when doing sink_constant optimization

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • DRLVM
    • None
    • Every one
    • Novice

    Description

      Sink_constant optimization pass will try to delay ldref HIR as late as possible. This optimization default to be enabled on this line:

      working_vm\vm\jitrino\src\optimizer\optimizer.cpp : void OptInitAction::readFlags() :
      optimizerFlags.sink_constants = getBoolArg("sink_constants", true);

      With this optimization being enabled, in function:

      working_vm\vm\jitrino\src\optimizer\codeselectors.cpp : void _BlockCodeSelector::genInstCode :

      when translating Op_LdRef instruction, it will just skip it. And as a result, for example, when translating Op_DirectCall instruction which will use the results of a previous Op_LdRef, it just insert a new Op_LdRef instruction just before Op_DirectCall.

      Op_LdRef is translated into LIR actually in function:

      working_vm\vm\jitrino\src\codegenerator\ia32\ia32instcodeselector.cpp : CG_OpndHandle* InstCodeSelector::ldRef :

      This function try to emit some simple sequence of instruction for LdRef, but when target of LdRef is SystemClass or SystemString and till here we have not created an object for this String, it will translate this LdRef into a VM Helper Call of VM_RT_LDC_STRING. This is too costly.

      Generally this is not a big issue because we hope such LdRef will not be executed too often. But if, for example, the Op_DirectCall locate in a hot loop and LdRef is translated into a VM Helper Call, there will be a great performance dropping till a 2nd complication for this method.

      To reproduce this problem, use the following java program:

      import java.util.*;

      class x
      {
      public static void main(String[] args)
      {
      long start = System.currentTimeMillis();

      String f = "";
      for(int i = 0;i < 100000000;i++)

      { if(i % 2 == 0) f = "abc"; else f = "xyz"; }

      System.out.println(f);

      System.out.println("Used " + (System.currentTimeMillis() - start) / 1000.0);
      }
      }

      Now run it like this:

      set JAVA_HOME=working_vm\build\windows_x86_msvc_debug\deploy\jdk\jre
      working_vm\build\windows_x86_msvc_debug\deploy\jdk\jre\bin\java -Xem:server_static x

      Output is:

      xyz
      Used 7.953

      And if we disable sink_constants option by changing the line above to
      optimizerFlags.sink_constants = getBoolArg("sink_constants", false);

      We will get output like this:

      xyz
      Used 0.359

      Besides server_static model, same problem exists for OPT mode, but does not exist for SERVER mode and CLIENT mode.

      A quick fix for this problem is like this:
      When doing sink_constant optimization, check if we really know the value of the target when compiling the current method.

      Attachments

        Activity

          People

            Unassigned Unassigned
            daizisheng li, shisheng
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Time Tracking

                Estimated:
                Original Estimate - 2h
                2h
                Remaining:
                Remaining Estimate - 2h
                2h
                Logged:
                Time Spent - Not Specified
                Not Specified