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

Severe inefficiency in CDRInputStream_1_0

XMLWordPrintable

      FULL PRODUCT VERSION :
      Custom build; issue is with source code tied to openjre 72b05; library issue is in latest code (112). Within this custom build can only use hotspot zero without shark.

      A DESCRIPTION OF THE PROBLEM :
      Noticed a severe performance hit converting a char array within an IDL message; traced it down to com.sun.corba.se.impl.encoding.CDRInputStream_1_0 implementation.

      In particular, read_char() here calls into char[] getConvertedChar(int,CodeSetConversion.BTCConverter) to convert a single character to the current character set. getConvertedChar returns an array of a single character, which read_char indexes and returns.

      Within getConvertedChar(), however, the bbwi isn't backed by a byte buffer. So it falls down a path that generates a new byte[] tmpBuf. Though read_char only needs a single char, this tmpBuf array is the size of the entire CORBA message, including headers. After this array is created, the converter is called to convert a single character at the desired position to the desired code set, creating an array of a single character. Note that tmpBuf is discarded; additional calls to read_char within the message result in brand new byte arrays being created, which again are the size of the entire CORBA message, for read_char's benefit... which only needs the single char.

      This is compounded when attempting to decode IDL char arrays or string arrays. In such cases, idlj creates a helper which allocates the entire char array, then calls read_char to read each element from the CORBA buffer. Each such read results in a new discarded tmpBuf array that is the size of the entire CORBA message. (String arrays are better, since the entire CORBA message is only copied to discarded tmpBuf arrays once per string; char arrays are most impacted).

      E.g. to make this clear: an interface Foo is created with a method void sendBar(Baz x);. Baz is just a structure, containing a member char data[128]. Baz has other members which, when aligned and sent through CORBA, causes a payload of 1024 bytes to be transmitted. This is used in Java with GIOP 1.0 protocols, which have a 100 byte header.

      In java, the idlj compiled mirror of char data[128] is of course char[] data. The helper reads data by creating a new char[128]; for each such char in this array, it calls read_char(). While assigning data[0], this calls getConvertedChars(1, getCharConverter()). getConvertedChar's creates a local tmpBuf of size 1124, copies the 100 byte CORBA header and the entire payload into it, then calls the converter to extract the byte at data[0] into a new char[1], which it returns. Now data[0] is set, and data[1] needs to be assigned. Another call to getConvertedChars occurs, creating another local tmpBuf of size 1124.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See description.


      REPRODUCIBILITY :
      This bug can be reproduced always.

            coffeys Sean Coffey
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: