Skip to content

Commit

Permalink
Merge pull request eclipse-openj9#354 from andrewcraik/improveStringC…
Browse files Browse the repository at this point in the history
…oding

Improve string coding
  • Loading branch information
vijaysun-omr authored Oct 23, 2017
2 parents 71a2771 + 830b52c commit 0fe08ea
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 21 deletions.
40 changes: 27 additions & 13 deletions jcl/src/java.base/share/classes/java/lang/String.java
Original file line number Diff line number Diff line change
Expand Up @@ -2423,14 +2423,19 @@ public byte[] getBytes() {
int currentLength = lengthInternal();

/*[IF Sidecar19-SE]*/
byte[] buffer = value;
// Check if the String is compressed
if (enableCompression && count >= 0) {
byte[] buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength) {
buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(String.LATIN1, buffer);
} else {
byte[] buffer = new byte[currentLength * 2];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength << 1) {
buffer = new byte[currentLength << 1];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(String.UTF16, buffer);
}
/*[ELSE]*/
Expand Down Expand Up @@ -2521,16 +2526,20 @@ public byte[] getBytes(String encoding) throws UnsupportedEncodingException {
}

int currentLength = lengthInternal();

/*[IF Sidecar19-SE]*/
byte[] buffer = value;
// Check if the String is compressed
if (enableCompression && count >= 0) {
byte[] buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength) {
buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(encoding, String.LATIN1, buffer);
} else {
byte[] buffer = new byte[currentLength * 2];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength << 1) {
buffer = new byte[currentLength << 1];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(encoding, String.UTF16, buffer);
}
/*[ELSE]*/
Expand Down Expand Up @@ -5102,14 +5111,19 @@ public byte[] getBytes(Charset charset) {
int currentLength = lengthInternal();

/*[IF Sidecar19-SE]*/
byte[] buffer = value;
// Check if the String is compressed
if (enableCompression && count >= 0) {
byte[] buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength) {
buffer = new byte[currentLength];
compressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(charset, String.LATIN1, buffer);
} else {
byte[] buffer = new byte[currentLength * 2];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
if (buffer.length != currentLength << 1) {
buffer = new byte[currentLength << 1];
decompressedArrayCopy(value, 0, buffer, 0, currentLength);
}
return StringCoding.encode(charset, String.UTF16, buffer);
}
/*[ELSE]*/
Expand Down
6 changes: 6 additions & 0 deletions runtime/tr.source/trj9/codegen/J9RecognizedMethodsEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@
java_lang_String_unsafeCharAt,
java_lang_String_split_str_int,

java_lang_StringUTF16_getChar,

java_lang_StringBuffer_append,
java_lang_StringBuffer_capacityInternal,
java_lang_StringBuffer_ensureCapacityImpl,
Expand Down Expand Up @@ -1086,6 +1088,10 @@
java_lang_StringCoding_encode,
java_lang_StringCoding_StringDecoder_decode,
java_lang_StringCoding_StringEncoder_encode,
java_lang_StringCoding_implEncodeISOArray,
java_lang_StringCoding_encode8859_1,
java_lang_StringCoding_encodeASCII,
java_lang_StringCoding_encodeUTF8,

java_util_Arrays_copyOf_byte,
java_util_Arrays_copyOf_short,
Expand Down
2 changes: 2 additions & 0 deletions runtime/tr.source/trj9/compile/J9Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ J9::Compilation::isConverterMethod(TR::RecognizedMethod rm)
switch (rm)
{
case TR::sun_nio_cs_ISO_8859_1_Encoder_encodeISOArray:
case TR::java_lang_StringCoding_implEncodeISOArray:
case TR::sun_nio_cs_ISO_8859_1_Decoder_decodeISO8859_1:
case TR::sun_nio_cs_US_ASCII_Encoder_encodeASCII:
case TR::sun_nio_cs_US_ASCII_Decoder_decodeASCII:
Expand Down Expand Up @@ -402,6 +403,7 @@ J9::Compilation::canTransformConverterMethod(TR::RecognizedMethod rm)
switch (rm)
{
case TR::sun_nio_cs_ISO_8859_1_Encoder_encodeISOArray:
case TR::java_lang_StringCoding_implEncodeISOArray:
return genTRxx || self()->cg()->getSupportsArrayTranslateTRTO255() || self()->cg()->getSupportsArrayTranslateTRTO() || genSIMD;

case TR::sun_nio_cs_ISO_8859_1_Decoder_decodeISO8859_1:
Expand Down
1 change: 1 addition & 0 deletions runtime/tr.source/trj9/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3305,6 +3305,7 @@ int TR_J9VMBase::checkInlineableTarget (TR_CallTarget* target, TR_CallSite* call
case TR::com_ibm_jit_JITHelpers_getJ9ClassFromObject32:
case TR::com_ibm_jit_JITHelpers_getJ9ClassFromObject64:
case TR::com_ibm_jit_JITHelpers_getClassInitializeStatus:
case TR::java_lang_StringUTF16_getChar:
return DontInline_Callee;
default:
break;
Expand Down
11 changes: 11 additions & 0 deletions runtime/tr.source/trj9/env/j9method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2987,6 +2987,10 @@ TR_ResolvedJ9Method::TR_ResolvedJ9Method(TR_OpaqueMethodBlock * aMethod, TR_Fron
{
{x(TR::java_lang_StringCoding_decode, "decode", "(Ljava/nio/charset/Charset;[BII)[C")},
{x(TR::java_lang_StringCoding_encode, "encode", "(Ljava/nio/charset/Charset;[CII)[B")},
{x(TR::java_lang_StringCoding_implEncodeISOArray, "implEncodeISOArray", "([BI[BII)I")},
{x(TR::java_lang_StringCoding_encode8859_1, "encode8859_1", "(B[B)[B")},
{x(TR::java_lang_StringCoding_encodeASCII, "encodeASCII", "(B[B)[B")},
{x(TR::java_lang_StringCoding_encodeUTF8, "encodeUTF8", "(B[B)[B")},
{ TR::unknownMethod}
};

Expand Down Expand Up @@ -3302,6 +3306,12 @@ TR_ResolvedJ9Method::TR_ResolvedJ9Method(TR_OpaqueMethodBlock * aMethod, TR_Fron
{ TR::unknownMethod}
};

static X StringUTF16Methods[] =
{
{ x(TR::java_lang_StringUTF16_getChar, "getChar", "([BI)C")},
{ TR::unknownMethod }
};

static X DecimalFormatHelperMethods[] =
{
{x(TR::com_ibm_jit_DecimalFormatHelper_formatAsDouble, "formatAsDouble", "(Ljava/text/DecimalFormat;Ljava/math/BigDecimal;)Ljava/lang/String;")},
Expand Down Expand Up @@ -4158,6 +4168,7 @@ TR_ResolvedJ9Method::TR_ResolvedJ9Method(TR_OpaqueMethodBlock * aMethod, TR_Fron
static Y class21[] =
{
{ "java/lang/ClassLoader", ClassLoaderMethods },
{ "java/lang/StringUTF16", StringUTF16Methods },
{ 0 }
};

Expand Down
3 changes: 3 additions & 0 deletions runtime/tr.source/trj9/il/symbol/J9MethodSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ static TR::RecognizedMethod canSkipZeroInitializationOnNewarrays[] =
//TR::java_util_Arrays_copyOf,
TR::java_io_Writer_write_lStringII,
TR::java_io_Writer_write_I,
TR::java_lang_StringCoding_encode8859_1,
TR::java_lang_StringCoding_encodeASCII,
TR::java_lang_StringCoding_encodeUTF8,
TR::unknownMethod
};

Expand Down
16 changes: 16 additions & 0 deletions runtime/tr.source/trj9/ilgen/Walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6899,6 +6899,22 @@ TR_J9ByteCodeIlGenerator::genNewArray(int32_t typeIndex)
if (_methodSymbol->skipZeroInitializationOnNewarrays())
node->setCanSkipZeroInitialization(true);

// special case for handling Arrays.copyOf in the StringEncoder fast paths for Java 9+
if (!comp()->isOutermostMethod()
&& _methodSymbol->getRecognizedMethod() == TR::java_util_Arrays_copyOf_byte)
{
int32_t callerIndex = comp()->getCurrentInlinedCallSite()->_byteCodeInfo.getCallerIndex();
TR::ResolvedMethodSymbol *caller = callerIndex > -1 ? comp()->getInlinedResolvedMethodSymbol(callerIndex) : comp()->getMethodSymbol();
switch (caller->getRecognizedMethod())
{
case TR::java_lang_StringCoding_encode8859_1:
case TR::java_lang_StringCoding_encodeASCII:
case TR::java_lang_StringCoding_encodeUTF8:
node->setCanSkipZeroInitialization(true);
break;
}
}

bool separateInitializationFromAllocation;
switch (_methodSymbol->getRecognizedMethod())
{
Expand Down
36 changes: 28 additions & 8 deletions runtime/tr.source/trj9/optimizer/UnsafeFastPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ int32_t TR_UnsafeFastPath::perform()
bool isVolatile = false;
bool isArrayOperation = false;
bool isByIndex = false;
int32_t objectChild = 1;
int32_t offsetChild = 2;

switch (symbol->getRecognizedMethod())
{
case TR::java_lang_StringUTF16_getChar:
objectChild = 0;
offsetChild = 1;
break;
}

// Check for array operation
switch (symbol->getRecognizedMethod())
Expand Down Expand Up @@ -190,6 +200,7 @@ int32_t TR_UnsafeFastPath::perform()
case TR::com_ibm_jit_JITHelpers_putLongInArray:
case TR::com_ibm_jit_JITHelpers_putObjectInArrayVolatile:
case TR::com_ibm_jit_JITHelpers_putObjectInArray:
case TR::java_lang_StringUTF16_getChar:
isArrayOperation = true;
break;
default:
Expand Down Expand Up @@ -223,6 +234,7 @@ int32_t TR_UnsafeFastPath::perform()
case TR::com_ibm_jit_JITHelpers_getByteFromArray:
type = TR::Int8;
break;
case TR::java_lang_StringUTF16_getChar:
case TR::com_ibm_jit_JITHelpers_getCharFromArrayByIndex:
isByIndex = true;
type = TR::Int16;
Expand Down Expand Up @@ -392,48 +404,56 @@ int32_t TR_UnsafeFastPath::perform()

if (type != TR::NoType && performTransformation(comp(), "%s Found unsafe/JITHelpers calls, turning node [" POINTER_PRINTF_FORMAT "] into a load/store\n", optDetailString(), node))
{

TR::SymbolReference * unsafeSymRef = comp()->getSymRefTab()->findOrCreateUnsafeSymbolRef(type, true, false, isVolatile);

// some helpers are special - we know they are accessing an array and we know the kind of that array
// so use the more helpful symref if we can
switch (calleeMethod)
{
case TR::java_lang_StringUTF16_getChar:
unsafeSymRef = comp()->getSymRefTab()->findOrCreateArrayShadowSymbolRef(TR::Int8);
break;
}

// Change the object child to the starting address of static fields in J9Class
if (isStatic)
{
TR::Node *jlClass = node->getChild(1);
TR::Node *jlClass = node->getChild(objectChild);
TR::Node *j9Class =
TR::Node::createWithSymRef(TR::aloadi, 1, 1, jlClass,
comp()->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
TR::Node *ramStatics =
TR::Node::createWithSymRef(TR::aloadi, 1, 1, j9Class,
comp()->getSymRefTab()->findOrCreateRamStaticsFromClassSymbolRef());
node->setAndIncChild(1, ramStatics);
node->setAndIncChild(objectChild, ramStatics);
jlClass->recursivelyDecReferenceCount();
offset = node->getChild(2);
offset = node->getChild(offsetChild);
// The offset for a static field is low taged, mask out the last bit to get the real offset
TR::Node *newOffset =
TR::Node::create(offset, TR::land, 2, offset,
TR::Node::lconst(offset, ~1));
node->setAndIncChild(2, newOffset);
node->setAndIncChild(offsetChild, newOffset);
offset->recursivelyDecReferenceCount();
}

// Anchor children of the call node to preserve their values
anchorAllChildren(node, tt);

// When accessing a static field, object is the starting address of static fields
object = node->getChild(1);
object = node->getChild(objectChild);
if (!isStatic)
object->setIsNonNull(true);

if (isByIndex)
{
index = node->getChild(2);
index = node->getChild(offsetChild);
index->setIsNonNegative(true);

offset = J9::TransformUtil::calculateOffsetFromIndexInContiguousArray(comp(), index, type);
}
else
{
offset = node->getChild(2);
offset = node->getChild(offsetChild);
offset->setIsNonNegative(true);

// Index is not used in the non-arraylet case so no need to compute it
Expand Down

0 comments on commit 0fe08ea

Please sign in to comment.