Index: vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp =================================================================== --- vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (revision 612856) +++ vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (working copy) @@ -1645,8 +1645,8 @@ // // Try some optimizations for System::arraycopy(...), Min, Max, Abs... // - if (!compilationInterface.needWriteBarriers() //genArrayCopyRepMove is not ready to work in WB mode - && translationFlags.genArrayCopyRepMove == true + + if (translationFlags.genArrayCopyRepMove == true && genArrayCopyRepMove(methodDesc,numArgs,srcOpnds)) { return; } else if (translationFlags.genArrayCopy == true && @@ -2385,32 +2385,56 @@ srcOpnds[3]->getType()->isInt4() && // 3 - dstPos srcOpnds[4]->getType()->isInt4()); // 4 - length - bool throwsASE = false; bool srcIsArray = srcType->isArray() && !srcType->isUnresolvedType(); bool dstIsArray = dstType->isArray() && !dstType->isUnresolvedType(); - ArrayType* srcAsArrayType = srcType->asArrayType(); - ArrayType* dstAsArrayType = dstType->asArrayType(); - bool srcIsArrOfPrimitive = srcIsArray && VMInterface::isArrayOfPrimitiveElements(srcAsArrayType->getVMTypeHandle()); - bool dstIsArrOfPrimitive = dstIsArray && VMInterface::isArrayOfPrimitiveElements(dstAsArrayType->getVMTypeHandle()); - if ( !(srcIsArray && dstIsArray) ) { - throwsASE = true; - } else if ( srcIsArrOfPrimitive ) { - if( !dstIsArrOfPrimitive || srcType != dstType ) - throwsASE = true; - } else if( dstIsArrOfPrimitive ) { - throwsASE = true; - } else { // the both are of objects - // Here is some inaccuracy. If src is a subclass of dst there is no ASE for sure. - // If it is not, we should check the assignability of each element being copied. - // To avoid this we just reject the inlining of System::arraycopy call in this case. - NamedType* srcElemType = srcAsArrayType->getElementType(); - NamedType* dstElemType = dstAsArrayType->getElementType(); - throwsASE = srcElemType->getVMTypeHandle() != dstElemType->getVMTypeHandle(); + + bool isOptimizable = true; + + if ( srcIsArray && dstIsArray ) { + // these are arrays + + ArrayType* srcAsArrayType = srcType->asArrayType(); + ArrayType* dstAsArrayType = dstType->asArrayType(); + bool srcIsArrOfPrimitive = srcIsArray && VMInterface::isArrayOfPrimitiveElements(srcAsArrayType->getVMTypeHandle()); + bool dstIsArrOfPrimitive = dstIsArray && VMInterface::isArrayOfPrimitiveElements(dstAsArrayType->getVMTypeHandle()); + + // are these primitive or reference arrays? + if ( srcIsArrOfPrimitive && dstIsArrOfPrimitive ) { + // both arrays are primitive + + // if we are dealing with different primitive type arrays, reject optimization + // TODO: is that really necessary? + isOptimizable = (srcType == dstType); + + } else if ( srcIsArrOfPrimitive ^ dstIsArrOfPrimitive ) { + // arrays are mixed primitive and reference types + // reject optimization + isOptimizable = false; + + } else { + // both arrays are reference + + // if write barriers are enabled, reject optimization + // if not, check the types + if ( compilationInterface.needWriteBarriers() ) { + isOptimizable = false; + } else { + // Here is some inaccuracy. If src is a subclass of dst there is no ASE for sure. + // If it is not, we should check the assignability of each element being copied. + // To avoid this we just reject the inlining of System::arraycopy call in this case. + NamedType* srcElemType = srcAsArrayType->getElementType(); + NamedType* dstElemType = dstAsArrayType->getElementType(); + isOptimizable = (srcElemType->getVMTypeHandle() == dstElemType->getVMTypeHandle()); + } + + } + + } else { + // source or destination are not arrays + isOptimizable = false; } - if ( throwsASE ) - return false; - else - return true; + + return isOptimizable; } bool